about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <github35764891676564198441@oli-obk.de>2025-05-10 07:02:30 +0000
committerGitHub <noreply@github.com>2025-05-10 07:02:30 +0000
commitcbd4db0b7c680258e17517e31efc04b6afe22464 (patch)
treeb815913f2d6c42de19b550fd5f5941555789ab08
parentc4cffcebbe36867241741143f1bfb5052d4d3271 (diff)
parenta4f765dcada7c37abfc3beda66b7823736b58ea6 (diff)
downloadrust-cbd4db0b7c680258e17517e31efc04b6afe22464.tar.gz
rust-cbd4db0b7c680258e17517e31efc04b6afe22464.zip
Merge pull request #4318 from rust-lang/rustup-2025-05-10
Automatic Rustup
-rw-r--r--.github/workflows/post-merge.yml7
-rw-r--r--Cargo.lock343
-rw-r--r--RELEASES.md166
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs3
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs4
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs13
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs3
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs17
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs1
-rw-r--r--compiler/rustc_ast_pretty/src/pp.rs6
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/mod.rs4
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs35
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs15
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/item.rs11
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs2
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/deprecation.rs26
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/repr.rs69
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/stability.rs25
-rw-r--r--compiler/rustc_attr_parsing/src/parser.rs15
-rw-r--r--compiler/rustc_attr_parsing/src/session_diagnostics.rs36
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs7
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs8
-rw-r--r--compiler/rustc_borrowck/src/lib.rs34
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs4
-rw-r--r--compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs45
-rw-r--r--compiler/rustc_borrowck/src/root_cx.rs5
-rw-r--r--compiler/rustc_borrowck/src/type_check/free_region_relations.rs8
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs16
-rw-r--r--compiler/rustc_borrowck/src/type_check/opaque_types.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs11
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/back/lto.rs6
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/mod.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs7
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs52
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs14
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs124
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs66
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs21
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs57
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/naked_asm.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/intern.rs35
-rw-r--r--compiler/rustc_data_structures/src/graph/linked_graph/mod.rs (renamed from compiler/rustc_data_structures/src/graph/implementation/mod.rs)36
-rw-r--r--compiler/rustc_data_structures/src/graph/linked_graph/tests.rs (renamed from compiler/rustc_data_structures/src/graph/implementation/tests.rs)8
-rw-r--r--compiler/rustc_data_structures/src/graph/mod.rs2
-rw-r--r--compiler/rustc_data_structures/src/sync.rs2
-rw-r--r--compiler/rustc_data_structures/src/sync/parallel.rs10
-rw-r--r--compiler/rustc_driver_impl/Cargo.toml2
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs8
-rw-r--r--compiler/rustc_driver_impl/src/pretty.rs2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0253.md6
-rw-r--r--compiler/rustc_expand/src/config.rs7
-rw-r--r--compiler/rustc_expand/src/expand.rs6
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs6
-rw-r--r--compiler/rustc_feature/src/unstable.rs7
-rw-r--r--compiler/rustc_hir/src/def.rs14
-rw-r--r--compiler/rustc_hir/src/definitions.rs94
-rw-r--r--compiler/rustc_hir/src/hir/tests.rs23
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs344
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs47
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs34
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs30
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs34
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs2
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs37
-rw-r--r--compiler/rustc_hir_typeck/src/_match.rs7
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs15
-rw-r--r--compiler/rustc_hir_typeck/src/check.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/expr_use_visitor.rs49
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/gather_locals.rs51
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs9
-rw-r--r--compiler/rustc_hir_typeck/src/opaque_types.rs26
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs158
-rw-r--r--compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs15
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs18
-rw-r--r--compiler/rustc_incremental/src/assert_dep_graph.rs2
-rw-r--r--compiler/rustc_incremental/src/persist/save.rs13
-rw-r--r--compiler/rustc_infer/src/infer/canonical/query_response.rs26
-rw-r--r--compiler/rustc_infer/src/infer/context.rs85
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs8
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs27
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/mod.rs4
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/table.rs104
-rw-r--r--compiler/rustc_infer/src/infer/outlives/for_liveness.rs4
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs2
-rw-r--r--compiler/rustc_infer/src/infer/outlives/verify.rs2
-rw-r--r--compiler/rustc_infer/src/infer/projection.rs25
-rw-r--r--compiler/rustc_infer/src/infer/relate/mod.rs5
-rw-r--r--compiler/rustc_infer/src/infer/relate/type_relating.rs3
-rw-r--r--compiler/rustc_infer/src/infer/resolve.rs3
-rw-r--r--compiler/rustc_infer/src/infer/snapshot/fudge.rs3
-rw-r--r--compiler/rustc_infer/src/infer/snapshot/undo_log.rs2
-rw-r--r--compiler/rustc_infer/src/traits/util.rs2
-rw-r--r--compiler/rustc_interface/src/passes.rs28
-rw-r--r--compiler/rustc_lexer/src/cursor.rs14
-rw-r--r--compiler/rustc_lexer/src/lib.rs155
-rw-r--r--compiler/rustc_lexer/src/tests.rs2
-rw-r--r--compiler/rustc_lint/src/autorefs.rs14
-rw-r--r--compiler/rustc_lint/src/for_loops_over_fallibles.rs12
-rw-r--r--compiler/rustc_lint/src/foreign_modules.rs2
-rw-r--r--compiler/rustc_lint/src/impl_trait_overcaptures.rs5
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs32
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp5
-rw-r--r--compiler/rustc_log/src/lib.rs13
-rw-r--r--compiler/rustc_metadata/Cargo.toml1
-rw-r--r--compiler/rustc_metadata/src/creader.rs5
-rw-r--r--compiler/rustc_metadata/src/dependency_format.rs71
-rw-r--r--compiler/rustc_metadata/src/locator.rs147
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs11
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs23
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs2
-rw-r--r--compiler/rustc_middle/src/arena.rs2
-rw-r--r--compiler/rustc_middle/src/lib.rs1
-rw-r--r--compiler/rustc_middle/src/middle/exported_symbols.rs4
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs6
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs2
-rw-r--r--compiler/rustc_middle/src/mir/terminator.rs103
-rw-r--r--compiler/rustc_middle/src/query/mod.rs16
-rw-r--r--compiler/rustc_middle/src/query/on_disk_cache.rs4
-rw-r--r--compiler/rustc_middle/src/ty/context.rs61
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs4
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs18
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs30
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs37
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs5
-rw-r--r--compiler/rustc_middle/src/ty/util.rs2
-rw-r--r--compiler/rustc_middle/src/ty/visit.rs4
-rw-r--r--compiler/rustc_mir_build/src/builder/mod.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs5
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/cursor.rs78
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/direction.rs48
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/graphviz.rs48
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/mod.rs30
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/results.rs57
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/tests.rs6
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/visitor.rs31
-rw-r--r--compiler/rustc_mir_dataflow/src/lib.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/points.rs10
-rw-r--r--compiler/rustc_mir_dataflow/src/rustc_peek.rs20
-rw-r--r--compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs27
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs57
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/by_move_body.rs12
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mappings.rs2
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs32
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans.rs118
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs43
-rw-r--r--compiler/rustc_mir_transform/src/dest_prop.rs2
-rw-r--r--compiler/rustc_mir_transform/src/jump_threading.rs4
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs3
-rw-r--r--compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs5
-rw-r--r--compiler/rustc_mir_transform/src/match_branches.rs37
-rw-r--r--compiler/rustc_mir_transform/src/prettify.rs4
-rw-r--r--compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs4
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs7
-rw-r--r--compiler/rustc_mir_transform/src/simplify.rs9
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/delegate.rs13
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs176
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/effect_goals.rs45
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs45
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs79
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs39
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/mod.rs22
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs16
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs13
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs74
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs81
-rw-r--r--compiler/rustc_parse/messages.ftl23
-rw-r--r--compiler/rustc_parse/src/errors.rs79
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs106
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs2
-rw-r--r--compiler/rustc_parse/src/parser/item.rs15
-rw-r--r--compiler/rustc_parse/src/parser/path.rs29
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs73
-rw-r--r--compiler/rustc_parse_format/src/lib.rs841
-rw-r--r--compiler/rustc_parse_format/src/tests.rs159
-rw-r--r--compiler/rustc_passes/messages.ftl19
-rw-r--r--compiler/rustc_passes/src/check_attr.rs5
-rw-r--r--compiler/rustc_passes/src/check_export.rs398
-rw-r--r--compiler/rustc_passes/src/errors.rs54
-rw-r--r--compiler/rustc_passes/src/lang_items.rs7
-rw-r--r--compiler/rustc_passes/src/lib.rs2
-rw-r--r--compiler/rustc_passes/src/reachable.rs10
-rw-r--r--compiler/rustc_passes/src/weak_lang_items.rs3
-rw-r--r--compiler/rustc_pattern_analysis/messages.ftl4
-rw-r--r--compiler/rustc_pattern_analysis/src/constructor.rs22
-rw-r--r--compiler/rustc_pattern_analysis/src/errors.rs14
-rw-r--r--compiler/rustc_pattern_analysis/src/rustc.rs71
-rw-r--r--compiler/rustc_pattern_analysis/src/usefulness.rs4
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs77
-rw-r--r--compiler/rustc_query_system/src/dep_graph/mod.rs3
-rw-r--r--compiler/rustc_query_system/src/dep_graph/query.rs6
-rw-r--r--compiler/rustc_query_system/src/dep_graph/serialized.rs378
-rw-r--r--compiler/rustc_resolve/messages.ftl7
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs4
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs8
-rw-r--r--compiler/rustc_resolve/src/errors.rs16
-rw-r--r--compiler/rustc_resolve/src/imports.rs43
-rw-r--r--compiler/rustc_resolve/src/lib.rs44
-rw-r--r--compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs4
-rw-r--r--compiler/rustc_session/src/config.rs20
-rw-r--r--compiler/rustc_session/src/cstore.rs1
-rw-r--r--compiler/rustc_session/src/options.rs4
-rw-r--r--compiler/rustc_session/src/output.rs8
-rw-r--r--compiler/rustc_smir/src/rustc_smir/builder.rs2
-rw-r--r--compiler/rustc_span/src/hygiene.rs25
-rw-r--r--compiler/rustc_span/src/lib.rs55
-rw-r--r--compiler/rustc_span/src/source_map.rs80
-rw-r--r--compiler/rustc_span/src/source_map/tests.rs73
-rw-r--r--compiler/rustc_span/src/symbol.rs28
-rw-r--r--compiler/rustc_symbol_mangling/src/export.rs181
-rw-r--r--compiler/rustc_symbol_mangling/src/lib.rs23
-rw-r--r--compiler/rustc_symbol_mangling/src/test.rs2
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs24
-rw-r--r--compiler/rustc_target/src/spec/base/msvc.rs14
-rw-r--r--compiler/rustc_target/src/spec/mod.rs14
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs13
-rw-r--r--compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs8
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs7
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs1
-rw-r--r--compiler/rustc_target/src/target_features.rs21
-rw-r--r--compiler/rustc_trait_selection/Cargo.toml1
-rw-r--r--compiler/rustc_trait_selection/messages.ftl28
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs46
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs52
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_condition.rs319
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs17
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs6
-rw-r--r--compiler/rustc_trait_selection/src/errors.rs58
-rw-r--r--compiler/rustc_trait_selection/src/opaque_types.rs83
-rw-r--r--compiler/rustc_trait_selection/src/solve/delegate.rs20
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs8
-rw-r--r--compiler/rustc_trait_selection/src/solve/inspect/analyse.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/normalize.rs386
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs170
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs20
-rw-r--r--compiler/rustc_traits/src/normalize_projection_ty.rs14
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs70
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs10
-rw-r--r--compiler/rustc_ty_utils/src/lib.rs4
-rw-r--r--compiler/rustc_ty_utils/src/nested_bodies.rs34
-rw-r--r--compiler/rustc_ty_utils/src/stalled_generators.rs54
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs5
-rw-r--r--compiler/rustc_type_ir/src/binder.rs6
-rw-r--r--compiler/rustc_type_ir/src/infer_ctxt.rs32
-rw-r--r--compiler/rustc_type_ir/src/interner.rs2
-rw-r--r--compiler/rustc_type_ir/src/predicate.rs70
-rw-r--r--compiler/rustc_type_ir/src/relate.rs2
-rw-r--r--compiler/rustc_type_ir/src/solve/mod.rs70
-rw-r--r--compiler/rustc_type_ir/src/ty_kind.rs22
-rw-r--r--compiler/rustc_type_ir/src/ty_kind/closure.rs2
-rw-r--r--compiler/rustc_type_ir/src/visit.rs8
-rw-r--r--compiler/stable_mir/Cargo.toml6
-rw-r--r--compiler/stable_mir/src/lib.rs4
-rw-r--r--library/Cargo.lock75
-rw-r--r--library/alloc/Cargo.toml2
-rw-r--r--library/alloc/src/collections/btree/map.rs11
-rw-r--r--library/alloc/src/collections/btree/set.rs13
-rw-r--r--library/alloc/src/collections/linked_list.rs9
-rw-r--r--library/alloc/src/collections/vec_deque/mod.rs67
-rw-r--r--library/alloc/src/rc.rs10
-rw-r--r--library/alloc/src/vec/extract_if.rs15
-rw-r--r--library/alloc/src/vec/into_iter.rs5
-rw-r--r--library/alloc/src/vec/mod.rs22
-rw-r--r--library/alloctests/tests/lib.rs1
-rw-r--r--library/alloctests/tests/vec_deque.rs69
m---------library/backtrace0
-rw-r--r--library/core/src/hint.rs4
-rw-r--r--library/core/src/intrinsics/mod.rs1
-rw-r--r--library/core/src/iter/adapters/cloned.rs88
-rw-r--r--library/core/src/iter/adapters/copied.rs95
-rw-r--r--library/core/src/iter/traits/iterator.rs456
-rw-r--r--library/core/src/macros/mod.rs1
-rw-r--r--library/core/src/ptr/mod.rs37
-rw-r--r--library/core/src/str/lossy.rs2
-rw-r--r--library/coretests/tests/lib.rs1
-rw-r--r--library/coretests/tests/ptr.rs4
-rw-r--r--library/proc_macro/src/lib.rs8
-rw-r--r--library/std/Cargo.toml4
-rw-r--r--library/std/src/collections/hash/map.rs20
-rw-r--r--library/std/src/collections/hash/set.rs19
-rw-r--r--library/std/src/fs.rs73
-rw-r--r--library/std/src/fs/tests.rs52
-rw-r--r--library/std/src/io/pipe.rs6
-rw-r--r--library/std/src/process.rs48
-rw-r--r--library/std/src/sys/args/common.rs4
-rw-r--r--library/std/src/sys/fs/hermit.rs11
-rw-r--r--library/std/src/sys/fs/solid.rs11
-rw-r--r--library/std/src/sys/fs/uefi.rs5
-rw-r--r--library/std/src/sys/fs/unix.rs39
-rw-r--r--library/std/src/sys/fs/unsupported.rs5
-rw-r--r--library/std/src/sys/fs/wasi.rs11
-rw-r--r--library/std/src/sys/fs/windows.rs17
-rw-r--r--library/std/src/sys/pal/unix/fuchsia.rs321
-rw-r--r--library/std/src/sys/pal/unix/futex.rs54
-rw-r--r--library/std/src/sys/pal/unix/thread.rs19
-rw-r--r--library/std/src/sys/process/env.rs (renamed from library/std/src/sys_common/process.rs)48
-rw-r--r--library/std/src/sys/process/mod.rs59
-rw-r--r--library/std/src/sys/process/uefi.rs116
-rw-r--r--library/std/src/sys/process/unix/common.rs2
-rw-r--r--library/std/src/sys/process/unix/fuchsia.rs9
-rw-r--r--library/std/src/sys/process/unix/mod.rs1
-rw-r--r--library/std/src/sys/process/unix/unix.rs5
-rw-r--r--library/std/src/sys/process/unix/unsupported.rs8
-rw-r--r--library/std/src/sys/process/unix/vxworks.rs5
-rw-r--r--library/std/src/sys/process/unsupported.rs8
-rw-r--r--library/std/src/sys/process/windows.rs7
-rw-r--r--library/std/src/sys/sync/mutex/fuchsia.rs6
-rw-r--r--library/std/src/sys_common/mod.rs1
-rw-r--r--library/test/src/lib.rs10
-rw-r--r--library/windows_targets/src/lib.rs1
-rw-r--r--rustfmt.toml1
-rw-r--r--src/bootstrap/Cargo.lock145
-rw-r--r--src/bootstrap/Cargo.toml2
-rw-r--r--src/bootstrap/src/bin/main.rs4
-rw-r--r--src/bootstrap/src/core/build_steps/check.rs67
-rw-r--r--src/bootstrap/src/core/build_steps/format.rs8
-rw-r--r--src/bootstrap/src/core/build_steps/run.rs81
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs1
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs7
-rw-r--r--src/bootstrap/src/core/builder/mod.rs5
-rw-r--r--src/bootstrap/src/lib.rs1
-rw-r--r--src/bootstrap/src/utils/cc_detect.rs1
-rw-r--r--src/bootstrap/src/utils/cc_detect/tests.rs12
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/bootstrap/src/utils/helpers.rs30
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version2
m---------src/doc/reference0
m---------src/doc/rust-by-example0
-rw-r--r--src/doc/rustc-dev-guide/src/mir/dataflow.md3
-rw-r--r--src/doc/rustc-dev-guide/src/tests/ci.md16
-rw-r--r--src/doc/rustc-dev-guide/src/tests/ui.md6
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/platform-support.md2
-rw-r--r--src/doc/rustc/src/platform-support/armv5te-unknown-linux-gnueabi.md29
-rw-r--r--src/doc/rustc/src/platform-support/riscv32im-risc0-zkvm-elf.md1
-rw-r--r--src/doc/style-guide/src/editions.md4
-rw-r--r--src/doc/style-guide/src/expressions.md9
-rw-r--r--src/doc/style-guide/src/nightly.md12
-rw-r--r--src/doc/style-guide/src/types.md12
-rw-r--r--src/doc/unstable-book/src/language-features/arbitrary-self-types.md2
-rw-r--r--src/doc/unstable-book/src/language-features/deref-patterns.md34
-rw-r--r--src/doc/unstable-book/src/language-features/f128.md2
-rw-r--r--src/doc/unstable-book/src/language-features/f16.md2
-rw-r--r--src/doc/unstable-book/src/language-features/frontmatter.md25
-rw-r--r--src/librustdoc/Cargo.toml1
-rw-r--r--src/librustdoc/clean/render_macro_matchers.rs2
-rw-r--r--src/librustdoc/clean/types.rs6
-rw-r--r--src/librustdoc/doctest.rs23
-rw-r--r--src/librustdoc/doctest/markdown.rs1
-rw-r--r--src/librustdoc/html/highlight.rs6
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css43
-rw-r--r--src/librustdoc/lib.rs26
-rw-r--r--src/librustdoc/lint.rs10
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs21
-rw-r--r--src/librustdoc/passes/lint.rs4
-rw-r--r--src/librustdoc/passes/lint/unportable_markdown.rs145
m---------src/llvm-project0
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/wildcard_imports.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/ty/mod.rs6
-rw-r--r--src/tools/clippy/tests/ui/double_ended_iterator_last.fixed15
-rw-r--r--src/tools/clippy/tests/ui/double_ended_iterator_last.rs15
-rw-r--r--src/tools/clippy/tests/ui/double_ended_iterator_last.stderr4
-rw-r--r--src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.rs15
-rw-r--r--src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.stderr4
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports.fixed10
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports.stderr10
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed10
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr10
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed10
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr10
-rw-r--r--src/tools/compiletest/src/directive-list.rs1
-rw-r--r--src/tools/compiletest/src/errors.rs3
-rw-r--r--src/tools/compiletest/src/json.rs55
-rw-r--r--src/tools/compiletest/src/runtest.rs43
-rw-r--r--src/tools/compiletest/src/runtest/incremental.rs14
-rw-r--r--src/tools/compiletest/src/runtest/ui.rs47
-rw-r--r--src/tools/coverage-dump/Cargo.toml1
-rw-r--r--src/tools/coverage-dump/src/covfun.rs86
-rw-r--r--src/tools/coverage-dump/src/covfun/tests.rs53
-rw-r--r--src/tools/coverage-dump/src/covmap.rs75
-rw-r--r--src/tools/coverage-dump/src/llvm_utils.rs85
-rw-r--r--src/tools/coverage-dump/src/llvm_utils/tests.rs (renamed from src/tools/coverage-dump/src/parser/tests.rs)4
-rw-r--r--src/tools/coverage-dump/src/main.rs5
-rw-r--r--src/tools/coverage-dump/src/parser.rs34
-rw-r--r--src/tools/coverage-dump/src/prf_names.rs40
-rw-r--r--src/tools/features-status-dump/Cargo.toml2
-rw-r--r--src/tools/lint-docs/src/lib.rs1
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs1
-rw-r--r--src/tools/opt-dist/Cargo.toml5
-rw-r--r--src/tools/opt-dist/src/environment.rs5
-rw-r--r--src/tools/opt-dist/src/exec.rs11
-rw-r--r--src/tools/opt-dist/src/main.rs26
-rw-r--r--src/tools/run-make-support/src/external_deps/cargo.rs5
-rw-r--r--src/tools/rust-analyzer/Cargo.lock18
-rw-r--r--src/tools/rust-analyzer/Cargo.toml4
-rw-r--r--src/tools/rust-analyzer/crates/base-db/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/base-db/src/input.rs2
-rw-r--r--src/tools/rust-analyzer/crates/base-db/src/lib.rs94
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/attr.rs55
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/db.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs49
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs93
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs19
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs187
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lib.rs113
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs10
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs85
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs18
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs42
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs5
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/resolver.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/test_db.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs158
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/change.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/db.rs10
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs60
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/lib.rs7
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/name.rs23
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs29
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs7
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/db.rs5
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs5
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/display.rs83
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/drop.rs7
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs9
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lower.rs19
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs72
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir.rs23
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs22
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs43
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs21
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs75
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs47
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs18
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs31
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs27
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs10
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs78
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/traits.rs11
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/utils.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/variance.rs19
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/display.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs81
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics.rs21
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs10
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/symbols.rs22
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs27
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs299
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs7
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs28
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs33
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs68
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs15
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_imports.rs (renamed from src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_use.rs)111
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/lib.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/tests.rs5
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs30
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/utils.rs16
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs96
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs12
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/item.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs18
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs18
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/assists.rs12
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/lib.rs16
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs61
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/expected_function.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs26
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs19
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs9
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs42
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs13
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs55
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/doc_links.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/tests.rs42
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs20
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/lib.rs9
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/moniker.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/status.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs2
-rw-r--r--src/tools/rust-analyzer/crates/intern/src/symbol.rs34
-rw-r--r--src/tools/rust-analyzer/crates/load-cargo/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs2
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs4
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/items.rs3
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs2
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs15
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/types.rs5
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/lexed_str.rs9
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs4
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs4
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/err/0022_bad_exprs.rast7
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_default_values_syntax.rast9
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rast30
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rs1
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_in_array_recover.rast15
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_in_array_recover.rs1
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/build.rs2
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/env.rs2
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/workspace.rs2
-rw-r--r--src/tools/rust-analyzer/crates/query-group-macro/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs10
-rw-r--r--src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs2
-rw-r--r--src/tools/rust-analyzer/crates/query-group-macro/tests/interned.rs2
-rw-r--r--src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs6
-rw-r--r--src/tools/rust-analyzer/crates/query-group-macro/tests/old_and_new.rs8
-rw-r--r--src/tools/rust-analyzer/crates/query-group-macro/tests/supertrait.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs6
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs13
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs12
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs3
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs6
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs14
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs8
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs18
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs4
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs6
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs8
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs18
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs4
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/ratoml.rs7
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs5
-rw-r--r--src/tools/rust-analyzer/crates/span/src/hygiene.rs65
-rw-r--r--src/tools/rust-analyzer/crates/stdx/src/thread.rs15
-rw-r--r--src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs5
-rw-r--r--src/tools/rust-analyzer/crates/syntax/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/syntax/rust.ungram1
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs4
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/make.rs35
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs124
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs1
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs2
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs50
-rw-r--r--src/tools/rust-analyzer/crates/test-fixture/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/tt/src/lib.rs6
-rw-r--r--src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs3
-rw-r--r--src/tools/rust-analyzer/rust-version2
-rw-r--r--src/tools/rust-analyzer/xtask/src/codegen/grammar.rs3
-rw-r--r--src/tools/rust-analyzer/xtask/src/codegen/parser_inline_tests.rs4
-rw-r--r--src/tools/rust-analyzer/xtask/src/dist.rs109
-rw-r--r--src/tools/rust-analyzer/xtask/src/flags.rs52
-rw-r--r--src/tools/rust-analyzer/xtask/src/install.rs28
-rw-r--r--src/tools/rust-analyzer/xtask/src/main.rs1
-rw-r--r--src/tools/rust-analyzer/xtask/src/pgo.rs105
-rw-r--r--src/tools/rust-analyzer/xtask/src/util.rs12
-rw-r--r--src/tools/rustbook/Cargo.lock191
-rw-r--r--src/tools/rustbook/Cargo.toml2
-rw-r--r--src/tools/tidy/src/deps.rs10
-rw-r--r--src/tools/tidy/src/issues.txt10
-rw-r--r--src/version2
-rw-r--r--tests/assembly/asm/aarch64-types.rs6
-rw-r--r--tests/codegen/const-vector.rs6
-rw-r--r--tests/codegen/simd/extract-insert-dyn.rs16
-rw-r--r--tests/coverage/abort.cov-map32
-rw-r--r--tests/coverage/assert-ne.cov-map21
-rw-r--r--tests/coverage/assert.cov-map28
-rw-r--r--tests/coverage/assert_not.cov-map19
-rw-r--r--tests/coverage/async.cov-map231
-rw-r--r--tests/coverage/async.coverage14
-rw-r--r--tests/coverage/async2.cov-map69
-rw-r--r--tests/coverage/async2.coverage4
-rw-r--r--tests/coverage/async_block.cov-map23
-rw-r--r--tests/coverage/async_closure.cov-map46
-rw-r--r--tests/coverage/async_closure.coverage3
-rw-r--r--tests/coverage/attr/impl.cov-map27
-rw-r--r--tests/coverage/attr/module.cov-map27
-rw-r--r--tests/coverage/attr/nested.cov-map24
-rw-r--r--tests/coverage/attr/off-on-sandwich.cov-map36
-rw-r--r--tests/coverage/attr/trait-impl-inherit.cov-map11
-rw-r--r--tests/coverage/await_ready.cov-map17
-rw-r--r--tests/coverage/await_ready.coverage2
-rw-r--r--tests/coverage/bad_counter_ids.cov-map104
-rw-r--r--tests/coverage/bench.cov-map9
-rw-r--r--tests/coverage/branch/generics.cov-map33
-rw-r--r--tests/coverage/branch/guard.cov-map17
-rw-r--r--tests/coverage/branch/guard.coverage2
-rw-r--r--tests/coverage/branch/if-let.cov-map53
-rw-r--r--tests/coverage/branch/if.cov-map47
-rw-r--r--tests/coverage/branch/lazy-boolean.cov-map66
-rw-r--r--tests/coverage/branch/let-else.cov-map19
-rw-r--r--tests/coverage/branch/match-arms.cov-map91
-rw-r--r--tests/coverage/branch/match-trivial.cov-map23
-rw-r--r--tests/coverage/branch/match-trivial.coverage4
-rw-r--r--tests/coverage/branch/no-mir-spans.cov-map24
-rw-r--r--tests/coverage/branch/while.cov-map56
-rw-r--r--tests/coverage/closure.cov-map295
-rw-r--r--tests/coverage/closure.coverage74
-rw-r--r--tests/coverage/closure_bug.cov-map55
-rw-r--r--tests/coverage/closure_bug.coverage2
-rw-r--r--tests/coverage/closure_macro.cov-map52
-rw-r--r--tests/coverage/closure_macro.coverage2
-rw-r--r--tests/coverage/closure_macro_async.cov-map58
-rw-r--r--tests/coverage/closure_macro_async.coverage2
-rw-r--r--tests/coverage/closure_unit_return.cov-map47
-rw-r--r--tests/coverage/closure_unit_return.coverage4
-rw-r--r--tests/coverage/condition/conditions.cov-map78
-rw-r--r--tests/coverage/conditions.cov-map201
-rw-r--r--tests/coverage/continue.cov-map97
-rw-r--r--tests/coverage/continue.coverage4
-rw-r--r--tests/coverage/coroutine.cov-map43
-rw-r--r--tests/coverage/coverage_attr_closure.cov-map44
-rw-r--r--tests/coverage/dead_code.cov-map45
-rw-r--r--tests/coverage/dead_code.coverage24
-rw-r--r--tests/coverage/drop_trait.cov-map34
-rw-r--r--tests/coverage/drop_trait.coverage8
-rw-r--r--tests/coverage/fn_sig_into_try.cov-map46
-rw-r--r--tests/coverage/fn_sig_into_try.coverage16
-rw-r--r--tests/coverage/generic-unused-impl.cov-map21
-rw-r--r--tests/coverage/generics.cov-map71
-rw-r--r--tests/coverage/generics.coverage8
-rw-r--r--tests/coverage/holes.cov-map86
-rw-r--r--tests/coverage/holes.coverage18
-rw-r--r--tests/coverage/if.cov-map15
-rw-r--r--tests/coverage/if.coverage20
-rw-r--r--tests/coverage/if_else.cov-map15
-rw-r--r--tests/coverage/if_else.coverage10
-rw-r--r--tests/coverage/if_not.cov-map11
-rw-r--r--tests/coverage/if_not.coverage2
-rw-r--r--tests/coverage/ignore_run.cov-map9
-rw-r--r--tests/coverage/inline-dead.cov-map47
-rw-r--r--tests/coverage/inline-dead.coverage2
-rw-r--r--tests/coverage/inline.cov-map125
-rw-r--r--tests/coverage/inline.coverage2
-rw-r--r--tests/coverage/inner_items.cov-map60
-rw-r--r--tests/coverage/inner_items.coverage10
-rw-r--r--tests/coverage/issue-83601.cov-map29
-rw-r--r--tests/coverage/issue-84561.cov-map132
-rw-r--r--tests/coverage/issue-84561.coverage14
-rw-r--r--tests/coverage/issue-85461.cov-map11
-rw-r--r--tests/coverage/issue-93054.cov-map25
-rw-r--r--tests/coverage/lazy_boolean.cov-map20
-rw-r--r--tests/coverage/lazy_boolean.coverage8
-rw-r--r--tests/coverage/let_else_loop.cov-map33
-rw-r--r--tests/coverage/long_and_wide.cov-map40
-rw-r--r--tests/coverage/long_and_wide.coverage262
-rw-r--r--tests/coverage/loop-break.cov-map6
-rw-r--r--tests/coverage/loop_break_value.cov-map11
-rw-r--r--tests/coverage/loop_break_value.coverage4
-rw-r--r--tests/coverage/loops_branches.cov-map55
-rw-r--r--tests/coverage/macro_in_closure.cov-map17
-rw-r--r--tests/coverage/macro_name_span.cov-map19
-rw-r--r--tests/coverage/match_or_pattern.cov-map19
-rw-r--r--tests/coverage/match_or_pattern.coverage8
-rw-r--r--tests/coverage/mcdc/condition-limit.cov-map19
-rw-r--r--tests/coverage/mcdc/if.cov-map109
-rw-r--r--tests/coverage/mcdc/if.coverage8
-rw-r--r--tests/coverage/mcdc/inlined_expressions.cov-map11
-rw-r--r--tests/coverage/mcdc/nested_if.cov-map44
-rw-r--r--tests/coverage/mcdc/nested_if.coverage6
-rw-r--r--tests/coverage/mcdc/non_control_flow.cov-map77
-rw-r--r--tests/coverage/nested_loops.cov-map70
-rw-r--r--tests/coverage/no-core.cov-map9
-rw-r--r--tests/coverage/no_cov_crate.cov-map93
-rw-r--r--tests/coverage/no_cov_crate.coverage4
-rw-r--r--tests/coverage/no_spans.cov-map18
-rw-r--r--tests/coverage/no_spans.coverage21
-rw-r--r--tests/coverage/no_spans.rs13
-rw-r--r--tests/coverage/no_spans_if_not.cov-map21
-rw-r--r--tests/coverage/overflow.cov-map45
-rw-r--r--tests/coverage/panic_unwind.cov-map32
-rw-r--r--tests/coverage/partial_eq.cov-map27
-rw-r--r--tests/coverage/partial_eq.coverage8
-rw-r--r--tests/coverage/simple_loop.cov-map24
-rw-r--r--tests/coverage/simple_loop.coverage12
-rw-r--r--tests/coverage/simple_match.cov-map19
-rw-r--r--tests/coverage/simple_match.coverage8
-rw-r--r--tests/coverage/sort_groups.cov-map87
-rw-r--r--tests/coverage/test_harness.cov-map18
-rw-r--r--tests/coverage/tight_inf_loop.cov-map14
-rw-r--r--tests/coverage/trivial.cov-map9
-rw-r--r--tests/coverage/try_error_result.cov-map266
-rw-r--r--tests/coverage/try_error_result.coverage12
-rw-r--r--tests/coverage/unicode.cov-map30
-rw-r--r--tests/coverage/unicode.coverage2
-rw-r--r--tests/coverage/unreachable.cov-map24
-rw-r--r--tests/coverage/unused.cov-map81
-rw-r--r--tests/coverage/unused_mod.cov-map22
-rw-r--r--tests/coverage/uses_crate.cov-map62
-rw-r--r--tests/coverage/uses_crate.coverage10
-rw-r--r--tests/coverage/uses_inline_crate.cov-map81
-rw-r--r--tests/coverage/uses_inline_crate.coverage20
-rw-r--r--tests/coverage/while.cov-map12
-rw-r--r--tests/coverage/while_early_ret.cov-map23
-rw-r--r--tests/coverage/yield.cov-map51
-rw-r--r--tests/crashes/127643.rs22
-rw-r--r--tests/crashes/131758.rs11
-rw-r--r--tests/crashes/133066.rs12
-rw-r--r--tests/debuginfo/step-into-match.rs4
-rw-r--r--tests/debuginfo/type-names.rs2
-rw-r--r--tests/incremental/circular-dependencies.rs1
-rw-r--r--tests/incremental/ich_nested_items.rs1
-rw-r--r--tests/incremental/incremental_proc_macro.rs2
-rw-r--r--tests/incremental/issue-49595/issue-49595.rs2
-rw-r--r--tests/incremental/issue-84252-global-alloc.rs1
-rw-r--r--tests/incremental/issue-85360-eval-obligation-ice.rs2
-rw-r--r--tests/incremental/no_mangle.rs1
-rw-r--r--tests/incremental/thinlto/cgu_keeps_identical_fn.rs4
-rw-r--r--tests/incremental/unrecoverable_query.rs2
-rw-r--r--tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff19
-rw-r--r--tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff4
-rw-r--r--tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff2
-rw-r--r--tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff3
-rw-r--r--tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff3
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff14
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff14
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff14
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff14
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff16
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff16
-rw-r--r--tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify-after-simplifycfg.diff18
-rw-r--r--tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff24
-rw-r--r--tests/mir-opt/pre-codegen/matchbr.match1.PreCodegen.after.mir13
-rw-r--r--tests/mir-opt/pre-codegen/matchbr.rs10
-rw-r--r--tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff5
-rw-r--r--tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff5
-rw-r--r--tests/pretty/hir-delegation.pp3
-rw-r--r--tests/run-make/arm64ec-import-export-static/export.rs23
-rw-r--r--tests/run-make/arm64ec-import-export-static/import.rs12
-rw-r--r--tests/run-make/arm64ec-import-export-static/rmake.rs15
-rw-r--r--tests/run-make/export/compile-interface-error/app.rs3
-rw-r--r--tests/run-make/export/compile-interface-error/liblibr.rs5
-rw-r--r--tests/run-make/export/compile-interface-error/rmake.rs9
-rw-r--r--tests/run-make/export/disambiguator/app.rs7
-rw-r--r--tests/run-make/export/disambiguator/libr.rs27
-rw-r--r--tests/run-make/export/disambiguator/rmake.rs12
-rw-r--r--tests/run-make/export/extern-opt/app.rs6
-rw-r--r--tests/run-make/export/extern-opt/libinterface.rs4
-rw-r--r--tests/run-make/export/extern-opt/libr.rs5
-rw-r--r--tests/run-make/export/extern-opt/rmake.rs23
-rw-r--r--tests/run-make/export/simple/app.rs8
-rw-r--r--tests/run-make/export/simple/libr.rs22
-rw-r--r--tests/run-make/export/simple/rmake.rs12
-rw-r--r--tests/run-make/pointer-auth-link-with-c/test.rs2
-rw-r--r--tests/run-make/remap-path-prefix-dwarf/rmake.rs53
-rw-r--r--tests/run-make/remap-path-prefix-dwarf/src/print_value.rs7
-rw-r--r--tests/run-make/remap-path-prefix-dwarf/src/some_value.rs6
-rw-r--r--tests/run-make/remap-path-prefix/rmake.rs6
-rw-r--r--tests/run-make/rustdoc-tempdir-removal/compile-error.rs5
-rw-r--r--tests/run-make/rustdoc-tempdir-removal/rmake.rs42
-rw-r--r--tests/run-make/rustdoc-tempdir-removal/run-error.rs3
-rw-r--r--tests/run-make/sanitizer-dylib-link/program.rs2
-rw-r--r--tests/rustdoc-gui/sidebar.goml36
-rw-r--r--tests/rustdoc-js-std/path-maxeditdistance.js2
-rw-r--r--tests/rustdoc-ui/ice-bug-report-url.rs5
-rw-r--r--tests/rustdoc-ui/ice-bug-report-url.stderr2
-rw-r--r--tests/rustdoc-ui/issues/issue-81662-shortness.rs3
-rw-r--r--tests/rustdoc-ui/issues/issue-81662-shortness.stdout8
-rw-r--r--tests/rustdoc-ui/issues/issue-83883-describe-lints.rs5
-rw-r--r--tests/rustdoc-ui/unportable-markdown.rs62
-rw-r--r--tests/rustdoc-ui/unportable-markdown.stderr23
-rw-r--r--tests/rustdoc/anchors/anchor-id-duplicate-method-name-25001.rs (renamed from tests/rustdoc/anchor-id-duplicate-method-name-25001.rs)0
-rw-r--r--tests/rustdoc/anchors/anchor-id-trait-method-15169.rs (renamed from tests/rustdoc/anchor-id-trait-method-15169.rs)0
-rw-r--r--tests/rustdoc/anchors/anchor-id-trait-tymethod-28478.rs (renamed from tests/rustdoc/anchor-id-trait-tymethod-28478.rs)0
-rw-r--r--tests/rustdoc/anchors/anchors.no_const_anchor.html (renamed from tests/rustdoc/anchors.no_const_anchor.html)0
-rw-r--r--tests/rustdoc/anchors/anchors.no_const_anchor2.html (renamed from tests/rustdoc/anchors.no_const_anchor2.html)0
-rw-r--r--tests/rustdoc/anchors/anchors.no_method_anchor.html (renamed from tests/rustdoc/anchors.no_method_anchor.html)0
-rw-r--r--tests/rustdoc/anchors/anchors.no_trait_method_anchor.html (renamed from tests/rustdoc/anchors.no_trait_method_anchor.html)0
-rw-r--r--tests/rustdoc/anchors/anchors.no_tymethod_anchor.html (renamed from tests/rustdoc/anchors.no_tymethod_anchor.html)0
-rw-r--r--tests/rustdoc/anchors/anchors.no_type_anchor.html (renamed from tests/rustdoc/anchors.no_type_anchor.html)0
-rw-r--r--tests/rustdoc/anchors/anchors.no_type_anchor2.html (renamed from tests/rustdoc/anchors.no_type_anchor2.html)0
-rw-r--r--tests/rustdoc/anchors/anchors.rs (renamed from tests/rustdoc/anchors.rs)0
-rw-r--r--tests/rustdoc/anchors/auxiliary/issue-86620-1.rs (renamed from tests/rustdoc/auxiliary/issue-86620-1.rs)0
-rw-r--r--tests/rustdoc/anchors/disambiguate-anchors-32890.rs (renamed from tests/rustdoc/disambiguate-anchors-32890.rs)0
-rw-r--r--tests/rustdoc/anchors/disambiguate-anchors-header-29449.rs (renamed from tests/rustdoc/disambiguate-anchors-header-29449.rs)0
-rw-r--r--tests/rustdoc/anchors/method-anchor-in-blanket-impl-86620.rs (renamed from tests/rustdoc/method-anchor-in-blanket-impl-86620.rs)0
-rw-r--r--tests/rustdoc/anchors/trait-impl-items-links-and-anchors.rs (renamed from tests/rustdoc/trait-impl-items-links-and-anchors.rs)0
-rw-r--r--tests/rustdoc/assoc/assoc-fns.rs (renamed from tests/rustdoc/assoc-fns.rs)0
-rw-r--r--tests/rustdoc/assoc/assoc-item-cast.rs (renamed from tests/rustdoc/assoc-item-cast.rs)0
-rw-r--r--tests/rustdoc/assoc/assoc-type-bindings-20646.rs (renamed from tests/rustdoc/assoc-type-bindings-20646.rs)0
-rw-r--r--tests/rustdoc/assoc/assoc-types.rs (renamed from tests/rustdoc/assoc-types.rs)0
-rw-r--r--tests/rustdoc/assoc/auxiliary/cross-crate-hidden-assoc-trait-items.rs (renamed from tests/rustdoc/auxiliary/cross-crate-hidden-assoc-trait-items.rs)0
-rw-r--r--tests/rustdoc/assoc/auxiliary/issue-20646.rs (renamed from tests/rustdoc/auxiliary/issue-20646.rs)0
-rw-r--r--tests/rustdoc/assoc/auxiliary/issue-20727.rs (renamed from tests/rustdoc/auxiliary/issue-20727.rs)0
-rw-r--r--tests/rustdoc/assoc/auxiliary/normalize-assoc-item.rs (renamed from tests/rustdoc/auxiliary/normalize-assoc-item.rs)0
-rw-r--r--tests/rustdoc/assoc/cross-crate-hidden-assoc-trait-items.rs (renamed from tests/rustdoc/cross-crate-hidden-assoc-trait-items.rs)0
-rw-r--r--tests/rustdoc/assoc/doc-assoc-item.rs (renamed from tests/rustdoc/doc-assoc-item.rs)0
-rw-r--r--tests/rustdoc/assoc/inline-assoc-type-20727-bindings.rs (renamed from tests/rustdoc/inline-assoc-type-20727-bindings.rs)0
-rw-r--r--tests/rustdoc/assoc/inline-assoc-type-20727-bounds-deref.rs (renamed from tests/rustdoc/inline-assoc-type-20727-bounds-deref.rs)0
-rw-r--r--tests/rustdoc/assoc/inline-assoc-type-20727-bounds-index.rs (renamed from tests/rustdoc/inline-assoc-type-20727-bounds-index.rs)0
-rw-r--r--tests/rustdoc/assoc/inline-assoc-type-20727-bounds.rs (renamed from tests/rustdoc/inline-assoc-type-20727-bounds.rs)0
-rw-r--r--tests/rustdoc/assoc/normalize-assoc-item.rs (renamed from tests/rustdoc/normalize-assoc-item.rs)0
-rw-r--r--tests/rustdoc/async/async-fn-opaque-item.rs (renamed from tests/rustdoc/async-fn-opaque-item.rs)0
-rw-r--r--tests/rustdoc/async/async-fn.rs (renamed from tests/rustdoc/async-fn.rs)0
-rw-r--r--tests/rustdoc/async/async-move-doctest.rs (renamed from tests/rustdoc/async-move-doctest.rs)0
-rw-r--r--tests/rustdoc/async/async-trait-sig.rs (renamed from tests/rustdoc/async-trait-sig.rs)0
-rw-r--r--tests/rustdoc/async/async-trait.rs (renamed from tests/rustdoc/async-trait.rs)0
-rw-r--r--tests/rustdoc/async/auxiliary/async-trait-dep.rs (renamed from tests/rustdoc/auxiliary/async-trait-dep.rs)0
-rw-r--r--tests/rustdoc/auto/auto-impl-for-trait.rs (renamed from tests/rustdoc/auto-impl-for-trait.rs)0
-rw-r--r--tests/rustdoc/auto/auto-impl-primitive.rs (renamed from tests/rustdoc/auto-impl-primitive.rs)0
-rw-r--r--tests/rustdoc/auto/auto-trait-bounds-by-associated-type-50159.rs (renamed from tests/rustdoc/auto-trait-bounds-by-associated-type-50159.rs)0
-rw-r--r--tests/rustdoc/auto/auto-trait-bounds-inference-variables-54705.rs (renamed from tests/rustdoc/auto-trait-bounds-inference-variables-54705.rs)0
-rw-r--r--tests/rustdoc/auto/auto-trait-bounds-where-51236.rs (renamed from tests/rustdoc/auto-trait-bounds-where-51236.rs)0
-rw-r--r--tests/rustdoc/auto/auto-trait-negative-impl-55321.rs (renamed from tests/rustdoc/auto-trait-negative-impl-55321.rs)0
-rw-r--r--tests/rustdoc/auto/auto-trait-not-send.rs (renamed from tests/rustdoc/auto-trait-not-send.rs)0
-rw-r--r--tests/rustdoc/auto/auto-traits.rs (renamed from tests/rustdoc/auto-traits.rs)0
-rw-r--r--tests/rustdoc/auto/auto_aliases.rs (renamed from tests/rustdoc/auto_aliases.rs)0
-rw-r--r--tests/rustdoc/auto/auxiliary/auto-traits.rs (renamed from tests/rustdoc/auxiliary/auto-traits.rs)0
-rw-r--r--tests/rustdoc/constant/assoc-consts-underscore.rs (renamed from tests/rustdoc/assoc-consts-underscore.rs)0
-rw-r--r--tests/rustdoc/constant/assoc-consts-version.rs (renamed from tests/rustdoc/assoc-consts-version.rs)0
-rw-r--r--tests/rustdoc/constant/assoc-consts.rs (renamed from tests/rustdoc/assoc-consts.rs)0
-rw-r--r--tests/rustdoc/constant/associated-consts.rs (renamed from tests/rustdoc/associated-consts.rs)0
-rw-r--r--tests/rustdoc/constant/const-display.rs (renamed from tests/rustdoc/const-display.rs)0
-rw-r--r--tests/rustdoc/constant/const-doc.rs (renamed from tests/rustdoc/const-doc.rs)0
-rw-r--r--tests/rustdoc/constant/const-effect-param.rs (renamed from tests/rustdoc/const-effect-param.rs)0
-rw-r--r--tests/rustdoc/constant/const-underscore.rs (renamed from tests/rustdoc/const-underscore.rs)0
-rw-r--r--tests/rustdoc/constant/const-value-display.rs (renamed from tests/rustdoc/const-value-display.rs)0
-rw-r--r--tests/rustdoc/constant/const.rs (renamed from tests/rustdoc/const.rs)0
-rw-r--r--tests/rustdoc/constant/document-item-with-associated-const-in-where-clause.rs (renamed from tests/rustdoc/document-item-with-associated-const-in-where-clause.rs)0
-rw-r--r--tests/rustdoc/constant/generic-const-items.rs (renamed from tests/rustdoc/generic-const-items.rs)0
-rw-r--r--tests/rustdoc/constant/generic_const_exprs.rs (renamed from tests/rustdoc/generic_const_exprs.rs)0
-rw-r--r--tests/rustdoc/constant/glob-shadowing-const.rs (renamed from tests/rustdoc/glob-shadowing-const.rs)0
-rw-r--r--tests/rustdoc/constant/hide-complex-unevaluated-const-arguments.rs (renamed from tests/rustdoc/hide-complex-unevaluated-const-arguments.rs)0
-rw-r--r--tests/rustdoc/constant/hide-complex-unevaluated-consts.rs (renamed from tests/rustdoc/hide-complex-unevaluated-consts.rs)0
-rw-r--r--tests/rustdoc/constant/ice-associated-const-equality-105952.rs (renamed from tests/rustdoc/ice-associated-const-equality-105952.rs)0
-rw-r--r--tests/rustdoc/constant/legacy-const-generic.rs (renamed from tests/rustdoc/legacy-const-generic.rs)0
-rw-r--r--tests/rustdoc/constant/link-assoc-const.rs (renamed from tests/rustdoc/link-assoc-const.rs)0
-rw-r--r--tests/rustdoc/constant/redirect-const.rs (renamed from tests/rustdoc/redirect-const.rs)0
-rw-r--r--tests/rustdoc/constant/rfc-2632-const-trait-impl.rs (renamed from tests/rustdoc/rfc-2632-const-trait-impl.rs)0
-rw-r--r--tests/rustdoc/constant/show-const-contents.rs (renamed from tests/rustdoc/show-const-contents.rs)0
-rw-r--r--tests/rustdoc/doc-cfg/doc-cfg-hide.rs (renamed from tests/rustdoc/doc-cfg-hide.rs)0
-rw-r--r--tests/rustdoc/doc-cfg/doc-cfg-implicit-gate.rs (renamed from tests/rustdoc/doc-cfg-implicit-gate.rs)0
-rw-r--r--tests/rustdoc/doc-cfg/doc-cfg-implicit.rs (renamed from tests/rustdoc/doc-cfg-implicit.rs)0
-rw-r--r--tests/rustdoc/doc-cfg/doc-cfg-inherit-from-module-79201.rs (renamed from tests/rustdoc/doc-cfg-inherit-from-module-79201.rs)0
-rw-r--r--tests/rustdoc/doc-cfg/doc-cfg-simplification.rs (renamed from tests/rustdoc/doc-cfg-simplification.rs)0
-rw-r--r--tests/rustdoc/doc-cfg/doc-cfg-target-feature.rs (renamed from tests/rustdoc/doc-cfg-target-feature.rs)0
-rw-r--r--tests/rustdoc/doc-cfg/doc-cfg-traits.rs (renamed from tests/rustdoc/doc-cfg-traits.rs)0
-rw-r--r--tests/rustdoc/doc-cfg/doc-cfg.rs (renamed from tests/rustdoc/doc-cfg.rs)0
-rw-r--r--tests/rustdoc/enum/auxiliary/enum-variant.rs (renamed from tests/rustdoc/auxiliary/enum-variant.rs)0
-rw-r--r--tests/rustdoc/enum/auxiliary/variant-struct.rs (renamed from tests/rustdoc/auxiliary/variant-struct.rs)0
-rw-r--r--tests/rustdoc/enum/enum-headings.rs (renamed from tests/rustdoc/enum-headings.rs)0
-rw-r--r--tests/rustdoc/enum/enum-non-exhaustive-108925.rs (renamed from tests/rustdoc/enum-non-exhaustive-108925.rs)0
-rw-r--r--tests/rustdoc/enum/enum-variant-doc-hidden-field-88600.rs (renamed from tests/rustdoc/enum-variant-doc-hidden-field-88600.rs)0
-rw-r--r--tests/rustdoc/enum/enum-variant-fields-heading.rs (renamed from tests/rustdoc/enum-variant-fields-heading.rs)0
-rw-r--r--tests/rustdoc/enum/enum-variant-fields-heading.variants.html (renamed from tests/rustdoc/enum-variant-fields-heading.variants.html)0
-rw-r--r--tests/rustdoc/enum/enum-variant-value.rs (renamed from tests/rustdoc/enum-variant-value.rs)0
-rw-r--r--tests/rustdoc/enum/render-enum-variant-structlike-32395.rs (renamed from tests/rustdoc/render-enum-variant-structlike-32395.rs)0
-rw-r--r--tests/rustdoc/enum/strip-enum-variant.no-not-shown.html (renamed from tests/rustdoc/strip-enum-variant.no-not-shown.html)0
-rw-r--r--tests/rustdoc/enum/strip-enum-variant.rs (renamed from tests/rustdoc/strip-enum-variant.rs)0
-rw-r--r--tests/rustdoc/extern/auxiliary/empty.rs1
-rw-r--r--tests/rustdoc/extern/auxiliary/extern-links.rs (renamed from tests/rustdoc/auxiliary/extern-links.rs)0
-rw-r--r--tests/rustdoc/extern/auxiliary/external-cross-doc.md (renamed from tests/rustdoc/auxiliary/external-cross-doc.md)0
-rw-r--r--tests/rustdoc/extern/auxiliary/external-cross.rs (renamed from tests/rustdoc/auxiliary/external-cross.rs)0
-rw-r--r--tests/rustdoc/extern/auxiliary/external-doc.md (renamed from tests/rustdoc/auxiliary/external-doc.md)0
-rw-r--r--tests/rustdoc/extern/auxiliary/html_root.rs (renamed from tests/rustdoc/auxiliary/html_root.rs)0
-rw-r--r--tests/rustdoc/extern/auxiliary/issue-30109-1.rs (renamed from tests/rustdoc/auxiliary/issue-30109-1.rs)0
-rw-r--r--tests/rustdoc/extern/auxiliary/no_html_root.rs (renamed from tests/rustdoc/auxiliary/no_html_root.rs)0
-rw-r--r--tests/rustdoc/extern/auxiliary/panic-item.rs (renamed from tests/rustdoc/auxiliary/panic-item.rs)0
-rw-r--r--tests/rustdoc/extern/auxiliary/pub-extern-crate.rs (renamed from tests/rustdoc/auxiliary/pub-extern-crate.rs)0
-rw-r--r--tests/rustdoc/extern/auxiliary/rustdoc-extern-default-method.rs (renamed from tests/rustdoc/auxiliary/rustdoc-extern-default-method.rs)0
-rw-r--r--tests/rustdoc/extern/auxiliary/rustdoc-extern-method.rs (renamed from tests/rustdoc/auxiliary/rustdoc-extern-method.rs)0
-rw-r--r--tests/rustdoc/extern/auxiliary/variant-struct.rs5
-rw-r--r--tests/rustdoc/extern/extern-default-method.no_href_on_anchor.html (renamed from tests/rustdoc/extern-default-method.no_href_on_anchor.html)0
-rw-r--r--tests/rustdoc/extern/extern-default-method.rs (renamed from tests/rustdoc/extern-default-method.rs)0
-rw-r--r--tests/rustdoc/extern/extern-fn-22038.rs (renamed from tests/rustdoc/extern-fn-22038.rs)0
-rw-r--r--tests/rustdoc/extern/extern-html-root-url-precedence.rs (renamed from tests/rustdoc/extern-html-root-url-precedence.rs)0
-rw-r--r--tests/rustdoc/extern/extern-html-root-url.rs (renamed from tests/rustdoc/extern-html-root-url.rs)0
-rw-r--r--tests/rustdoc/extern/extern-links.rs (renamed from tests/rustdoc/extern-links.rs)0
-rw-r--r--tests/rustdoc/extern/extern-method.rs (renamed from tests/rustdoc/extern-method.rs)0
-rw-r--r--tests/rustdoc/extern/external-cross.rs (renamed from tests/rustdoc/external-cross.rs)0
-rw-r--r--tests/rustdoc/extern/external-doc.rs (renamed from tests/rustdoc/external-doc.rs)0
-rw-r--r--tests/rustdoc/extern/hidden-extern-34025.rs (renamed from tests/rustdoc/hidden-extern-34025.rs)0
-rw-r--r--tests/rustdoc/extern/link-extern-crate-33178.rs (renamed from tests/rustdoc/link-extern-crate-33178.rs)0
-rw-r--r--tests/rustdoc/extern/link-extern-crate-item-30109.rs (renamed from tests/rustdoc/link-extern-crate-item-30109.rs)0
-rw-r--r--tests/rustdoc/extern/link-extern-crate-title-33178.rs (renamed from tests/rustdoc/link-extern-crate-title-33178.rs)0
-rw-r--r--tests/rustdoc/extern/pub-extern-crate.rs (renamed from tests/rustdoc/pub-extern-crate.rs)0
-rw-r--r--tests/rustdoc/extern/unsafe-extern-blocks.rs (renamed from tests/rustdoc/unsafe-extern-blocks.rs)0
-rw-r--r--tests/rustdoc/extern/unused-extern-crate.rs (renamed from tests/rustdoc/unused-extern-crate.rs)0
-rw-r--r--tests/rustdoc/impl/auxiliary/cross-crate-hidden-impl-parameter.rs (renamed from tests/rustdoc/auxiliary/cross-crate-hidden-impl-parameter.rs)0
-rw-r--r--tests/rustdoc/impl/auxiliary/extern-impl-trait.rs (renamed from tests/rustdoc/auxiliary/extern-impl-trait.rs)0
-rw-r--r--tests/rustdoc/impl/auxiliary/incoherent-impl-types.rs (renamed from tests/rustdoc/auxiliary/incoherent-impl-types.rs)0
-rw-r--r--tests/rustdoc/impl/auxiliary/issue-100204-aux.rs (renamed from tests/rustdoc/auxiliary/issue-100204-aux.rs)0
-rw-r--r--tests/rustdoc/impl/auxiliary/issue-17476.rs (renamed from tests/rustdoc/auxiliary/issue-17476.rs)0
-rw-r--r--tests/rustdoc/impl/auxiliary/issue-21092.rs (renamed from tests/rustdoc/auxiliary/issue-21092.rs)0
-rw-r--r--tests/rustdoc/impl/auxiliary/issue-22025.rs (renamed from tests/rustdoc/auxiliary/issue-22025.rs)0
-rw-r--r--tests/rustdoc/impl/auxiliary/issue-53689.rs (renamed from tests/rustdoc/auxiliary/issue-53689.rs)0
-rw-r--r--tests/rustdoc/impl/auxiliary/precise-capturing.rs (renamed from tests/rustdoc/auxiliary/precise-capturing.rs)0
-rw-r--r--tests/rustdoc/impl/auxiliary/real_gimli.rs (renamed from tests/rustdoc/auxiliary/real_gimli.rs)0
-rw-r--r--tests/rustdoc/impl/auxiliary/realcore.rs (renamed from tests/rustdoc/auxiliary/realcore.rs)0
-rw-r--r--tests/rustdoc/impl/auxiliary/rustdoc-default-impl.rs (renamed from tests/rustdoc/auxiliary/rustdoc-default-impl.rs)0
-rw-r--r--tests/rustdoc/impl/auxiliary/rustdoc-impl-parts-crosscrate.rs (renamed from tests/rustdoc/auxiliary/rustdoc-impl-parts-crosscrate.rs)0
-rw-r--r--tests/rustdoc/impl/blanket-impl-29503.rs (renamed from tests/rustdoc/blanket-impl-29503.rs)0
-rw-r--r--tests/rustdoc/impl/blanket-impl-78673.rs (renamed from tests/rustdoc/blanket-impl-78673.rs)0
-rw-r--r--tests/rustdoc/impl/cross-crate-hidden-impl-parameter.rs (renamed from tests/rustdoc/cross-crate-hidden-impl-parameter.rs)0
-rw-r--r--tests/rustdoc/impl/deduplicate-glob-import-impl-21474.rs (renamed from tests/rustdoc/deduplicate-glob-import-impl-21474.rs)0
-rw-r--r--tests/rustdoc/impl/deduplicate-trait-impl-22025.rs (renamed from tests/rustdoc/deduplicate-trait-impl-22025.rs)0
-rw-r--r--tests/rustdoc/impl/default-impl.rs (renamed from tests/rustdoc/default-impl.rs)0
-rw-r--r--tests/rustdoc/impl/deprecated-impls.rs (renamed from tests/rustdoc/deprecated-impls.rs)0
-rw-r--r--tests/rustdoc/impl/doc-hidden-trait-implementors-33069.rs (renamed from tests/rustdoc/doc-hidden-trait-implementors-33069.rs)0
-rw-r--r--tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs (renamed from tests/rustdoc/doc_auto_cfg_nested_impl.rs)0
-rw-r--r--tests/rustdoc/impl/duplicated_impl.rs (renamed from tests/rustdoc/duplicated_impl.rs)0
-rw-r--r--tests/rustdoc/impl/empty-impl-block.rs (renamed from tests/rustdoc/empty-impl-block.rs)0
-rw-r--r--tests/rustdoc/impl/empty-impls.rs (renamed from tests/rustdoc/empty-impls.rs)0
-rw-r--r--tests/rustdoc/impl/extern-impl-trait.rs (renamed from tests/rustdoc/extern-impl-trait.rs)0
-rw-r--r--tests/rustdoc/impl/extern-impl.rs (renamed from tests/rustdoc/extern-impl.rs)0
-rw-r--r--tests/rustdoc/impl/foreign-implementors-js-43701.rs (renamed from tests/rustdoc/foreign-implementors-js-43701.rs)0
-rw-r--r--tests/rustdoc/impl/generic-impl.rs (renamed from tests/rustdoc/generic-impl.rs)0
-rw-r--r--tests/rustdoc/impl/hidden-implementors-90781.rs (renamed from tests/rustdoc/hidden-implementors-90781.rs)0
-rw-r--r--tests/rustdoc/impl/hidden-impls.rs (renamed from tests/rustdoc/hidden-impls.rs)0
-rw-r--r--tests/rustdoc/impl/hidden-trait-struct-impls.rs (renamed from tests/rustdoc/hidden-trait-struct-impls.rs)0
-rw-r--r--tests/rustdoc/impl/hide-mut-methods-if-no-derefmut-impl-74083.rs (renamed from tests/rustdoc/hide-mut-methods-if-no-derefmut-impl-74083.rs)0
-rw-r--r--tests/rustdoc/impl/impl-alias-substituted.rs (renamed from tests/rustdoc/impl-alias-substituted.rs)0
-rw-r--r--tests/rustdoc/impl/impl-assoc-type-21092.rs (renamed from tests/rustdoc/impl-assoc-type-21092.rs)0
-rw-r--r--tests/rustdoc/impl/impl-associated-items-order.rs (renamed from tests/rustdoc/impl-associated-items-order.rs)0
-rw-r--r--tests/rustdoc/impl/impl-associated-items-sidebar.rs (renamed from tests/rustdoc/impl-associated-items-sidebar.rs)0
-rw-r--r--tests/rustdoc/impl/impl-blanket-53689.rs (renamed from tests/rustdoc/impl-blanket-53689.rs)0
-rw-r--r--tests/rustdoc/impl/impl-box.rs (renamed from tests/rustdoc/impl-box.rs)0
-rw-r--r--tests/rustdoc/impl/impl-disambiguation.rs (renamed from tests/rustdoc/impl-disambiguation.rs)0
-rw-r--r--tests/rustdoc/impl/impl-everywhere.rs (renamed from tests/rustdoc/impl-everywhere.rs)0
-rw-r--r--tests/rustdoc/impl/impl-in-const-block.rs (renamed from tests/rustdoc/impl-in-const-block.rs)0
-rw-r--r--tests/rustdoc/impl/impl-on-ty-alias-issue-119015.rs (renamed from tests/rustdoc/impl-on-ty-alias-issue-119015.rs)0
-rw-r--r--tests/rustdoc/impl/impl-parts-crosscrate.rs (renamed from tests/rustdoc/impl-parts-crosscrate.rs)0
-rw-r--r--tests/rustdoc/impl/impl-parts.rs (renamed from tests/rustdoc/impl-parts.rs)0
-rw-r--r--tests/rustdoc/impl/impl-ref-20175.rs (renamed from tests/rustdoc/impl-ref-20175.rs)0
-rw-r--r--tests/rustdoc/impl/impl-trait-43869.rs (renamed from tests/rustdoc/impl-trait-43869.rs)0
-rw-r--r--tests/rustdoc/impl/impl-trait-alias.rs (renamed from tests/rustdoc/impl-trait-alias.rs)0
-rw-r--r--tests/rustdoc/impl/impl-trait-precise-capturing.rs (renamed from tests/rustdoc/impl-trait-precise-capturing.rs)0
-rw-r--r--tests/rustdoc/impl/impl-type-parameter-33592.rs (renamed from tests/rustdoc/impl-type-parameter-33592.rs)0
-rw-r--r--tests/rustdoc/impl/implementor-stable-version.rs (renamed from tests/rustdoc/implementor-stable-version.rs)0
-rw-r--r--tests/rustdoc/impl/implementors-unstable-75588.rs (renamed from tests/rustdoc/implementors-unstable-75588.rs)0
-rw-r--r--tests/rustdoc/impl/inline-impl-through-glob-import-100204.rs (renamed from tests/rustdoc/inline-impl-through-glob-import-100204.rs)0
-rw-r--r--tests/rustdoc/impl/manual_impl.rs (renamed from tests/rustdoc/manual_impl.rs)0
-rw-r--r--tests/rustdoc/impl/method-link-foreign-trait-impl-17476.rs (renamed from tests/rustdoc/method-link-foreign-trait-impl-17476.rs)0
-rw-r--r--tests/rustdoc/impl/module-impls.rs (renamed from tests/rustdoc/module-impls.rs)0
-rw-r--r--tests/rustdoc/impl/must_implement_one_of.rs (renamed from tests/rustdoc/must_implement_one_of.rs)0
-rw-r--r--tests/rustdoc/impl/negative-impl-no-items.rs (renamed from tests/rustdoc/negative-impl-no-items.rs)0
-rw-r--r--tests/rustdoc/impl/negative-impl-sidebar.rs (renamed from tests/rustdoc/negative-impl-sidebar.rs)0
-rw-r--r--tests/rustdoc/impl/negative-impl.rs (renamed from tests/rustdoc/negative-impl.rs)0
-rw-r--r--tests/rustdoc/impl/return-impl-trait.rs (renamed from tests/rustdoc/return-impl-trait.rs)0
-rw-r--r--tests/rustdoc/impl/rustc-incoherent-impls.rs (renamed from tests/rustdoc/rustc-incoherent-impls.rs)0
-rw-r--r--tests/rustdoc/impl/same-crate-hidden-impl-parameter.rs (renamed from tests/rustdoc/same-crate-hidden-impl-parameter.rs)0
-rw-r--r--tests/rustdoc/impl/sidebar-trait-impl-disambiguate-78701.rs (renamed from tests/rustdoc/sidebar-trait-impl-disambiguate-78701.rs)0
-rw-r--r--tests/rustdoc/impl/struct-implementations-title.rs (renamed from tests/rustdoc/struct-implementations-title.rs)0
-rw-r--r--tests/rustdoc/impl/trait-impl.rs (renamed from tests/rustdoc/trait-impl.rs)0
-rw-r--r--tests/rustdoc/impl/trait-implementations-duplicate-self-45584.rs (renamed from tests/rustdoc/trait-implementations-duplicate-self-45584.rs)0
-rw-r--r--tests/rustdoc/impl/underscore-type-in-trait-impl-96381.rs (renamed from tests/rustdoc/underscore-type-in-trait-impl-96381.rs)0
-rw-r--r--tests/rustdoc/impl/universal-impl-trait.rs (renamed from tests/rustdoc/universal-impl-trait.rs)0
-rw-r--r--tests/rustdoc/impl/unneeded-trait-implementations-title.rs (renamed from tests/rustdoc/unneeded-trait-implementations-title.rs)0
-rw-r--r--tests/rustdoc/intra-doc/ice-intra-doc-links-107995.rs (renamed from tests/rustdoc/ice-intra-doc-links-107995.rs)0
-rw-r--r--tests/rustdoc/intra-doc/intra-doc-link-method-trait-impl-72340.rs (renamed from tests/rustdoc/intra-doc-link-method-trait-impl-72340.rs)0
-rw-r--r--tests/rustdoc/jump-to-def/auxiliary/jump-to-def-macro.rs (renamed from tests/rustdoc/auxiliary/jump-to-def-macro.rs)0
-rw-r--r--tests/rustdoc/jump-to-def/jump-to-def-doc-links-calls.rs (renamed from tests/rustdoc/jump-to-def-doc-links-calls.rs)0
-rw-r--r--tests/rustdoc/jump-to-def/jump-to-def-doc-links.rs (renamed from tests/rustdoc/jump-to-def-doc-links.rs)0
-rw-r--r--tests/rustdoc/jump-to-def/jump-to-def-macro.rs (renamed from tests/rustdoc/jump-to-def-macro.rs)0
-rw-r--r--tests/rustdoc/jump-to-def/jump-to-def-pats.rs (renamed from tests/rustdoc/jump-to-def-pats.rs)0
-rw-r--r--tests/rustdoc/jump-to-def/jump-to-def-prelude-types.rs (renamed from tests/rustdoc/jump-to-def-prelude-types.rs)0
-rw-r--r--tests/rustdoc/jump-to-def/jump-to-non-local-method.rs (renamed from tests/rustdoc/jump-to-non-local-method.rs)0
-rw-r--r--tests/rustdoc/macro/auxiliary/external-macro-src.rs (renamed from tests/rustdoc/auxiliary/external-macro-src.rs)0
-rw-r--r--tests/rustdoc/macro/auxiliary/issue-99221-aux.rs20
-rw-r--r--tests/rustdoc/macro/auxiliary/macro_pub_in_module.rs (renamed from tests/rustdoc/auxiliary/macro_pub_in_module.rs)0
-rw-r--r--tests/rustdoc/macro/auxiliary/pub-use-extern-macros.rs (renamed from tests/rustdoc/auxiliary/pub-use-extern-macros.rs)0
-rw-r--r--tests/rustdoc/macro/compiler-derive-proc-macro.rs (renamed from tests/rustdoc/compiler-derive-proc-macro.rs)0
-rw-r--r--tests/rustdoc/macro/const-rendering-macros-33302.rs (renamed from tests/rustdoc/const-rendering-macros-33302.rs)0
-rw-r--r--tests/rustdoc/macro/decl_macro.rs (renamed from tests/rustdoc/decl_macro.rs)0
-rw-r--r--tests/rustdoc/macro/decl_macro_priv.rs (renamed from tests/rustdoc/decl_macro_priv.rs)0
-rw-r--r--tests/rustdoc/macro/doc-proc-macro.rs (renamed from tests/rustdoc/doc-proc-macro.rs)0
-rw-r--r--tests/rustdoc/macro/external-macro-src.rs (renamed from tests/rustdoc/external-macro-src.rs)0
-rw-r--r--tests/rustdoc/macro/macro-const-display-115295.rs (renamed from tests/rustdoc/macro-const-display-115295.rs)0
-rw-r--r--tests/rustdoc/macro/macro-doc-comment-23812.rs (renamed from tests/rustdoc/macro-doc-comment-23812.rs)0
-rw-r--r--tests/rustdoc/macro/macro-export-crate-root-108231.rs (renamed from tests/rustdoc/macro-export-crate-root-108231.rs)0
-rw-r--r--tests/rustdoc/macro/macro-generated-macro.macro_linebreak_pre.html (renamed from tests/rustdoc/macro-generated-macro.macro_linebreak_pre.html)0
-rw-r--r--tests/rustdoc/macro/macro-generated-macro.macro_morestuff_pre.html (renamed from tests/rustdoc/macro-generated-macro.macro_morestuff_pre.html)0
-rw-r--r--tests/rustdoc/macro/macro-generated-macro.rs (renamed from tests/rustdoc/macro-generated-macro.rs)0
-rw-r--r--tests/rustdoc/macro/macro-higher-kinded-function.rs (renamed from tests/rustdoc/macro-higher-kinded-function.rs)0
-rw-r--r--tests/rustdoc/macro/macro-ice-16019.rs (renamed from tests/rustdoc/macro-ice-16019.rs)0
-rw-r--r--tests/rustdoc/macro/macro-in-async-block.rs (renamed from tests/rustdoc/macro-in-async-block.rs)0
-rw-r--r--tests/rustdoc/macro/macro-in-closure.rs (renamed from tests/rustdoc/macro-in-closure.rs)0
-rw-r--r--tests/rustdoc/macro/macro-indirect-use.rs (renamed from tests/rustdoc/macro-indirect-use.rs)0
-rw-r--r--tests/rustdoc/macro/macro_pub_in_module.rs (renamed from tests/rustdoc/macro_pub_in_module.rs)0
-rw-r--r--tests/rustdoc/macro/macro_rules-matchers.rs (renamed from tests/rustdoc/macro_rules-matchers.rs)0
-rw-r--r--tests/rustdoc/macro/macros.rs (renamed from tests/rustdoc/macros.rs)0
-rw-r--r--tests/rustdoc/macro/multiple-macro-rules-w-same-name-99221.rs (renamed from tests/rustdoc/multiple-macro-rules-w-same-name-99221.rs)0
-rw-r--r--tests/rustdoc/macro/multiple-macro-rules-w-same-name-submodule-99221.rs (renamed from tests/rustdoc/multiple-macro-rules-w-same-name-submodule-99221.rs)0
-rw-r--r--tests/rustdoc/macro/proc-macro.rs (renamed from tests/rustdoc/proc-macro.rs)0
-rw-r--r--tests/rustdoc/macro/pub-use-extern-macros.rs (renamed from tests/rustdoc/pub-use-extern-macros.rs)0
-rw-r--r--tests/rustdoc/macro/rustc-macro-crate.rs (renamed from tests/rustdoc/rustc-macro-crate.rs)0
-rw-r--r--tests/rustdoc/primitive/auxiliary/issue-15318.rs (renamed from tests/rustdoc/auxiliary/issue-15318.rs)0
-rw-r--r--tests/rustdoc/primitive/auxiliary/primitive-doc.rs (renamed from tests/rustdoc/auxiliary/primitive-doc.rs)0
-rw-r--r--tests/rustdoc/primitive/cross-crate-primitive-doc.rs (renamed from tests/rustdoc/cross-crate-primitive-doc.rs)0
-rw-r--r--tests/rustdoc/primitive/no_std-primitive.rs (renamed from tests/rustdoc/no_std-primitive.rs)0
-rw-r--r--tests/rustdoc/primitive/primitive-link.rs (renamed from tests/rustdoc/primitive-link.rs)0
-rw-r--r--tests/rustdoc/primitive/primitive-raw-pointer-dox-15318-3.rs (renamed from tests/rustdoc/primitive-raw-pointer-dox-15318-3.rs)0
-rw-r--r--tests/rustdoc/primitive/primitive-raw-pointer-link-15318.rs (renamed from tests/rustdoc/primitive-raw-pointer-link-15318.rs)0
-rw-r--r--tests/rustdoc/primitive/primitive-raw-pointer-link-no-inlined-15318-2.rs (renamed from tests/rustdoc/primitive-raw-pointer-link-no-inlined-15318-2.rs)0
-rw-r--r--tests/rustdoc/primitive/primitive-reference.rs (renamed from tests/rustdoc/primitive-reference.rs)0
-rw-r--r--tests/rustdoc/primitive/primitive-slice-auto-trait.rs (renamed from tests/rustdoc/primitive-slice-auto-trait.rs)0
-rw-r--r--tests/rustdoc/primitive/primitive-tuple-auto-trait.rs (renamed from tests/rustdoc/primitive-tuple-auto-trait.rs)0
-rw-r--r--tests/rustdoc/primitive/primitive-tuple-variadic.rs (renamed from tests/rustdoc/primitive-tuple-variadic.rs)0
-rw-r--r--tests/rustdoc/primitive/primitive-unit-auto-trait.rs (renamed from tests/rustdoc/primitive-unit-auto-trait.rs)0
-rw-r--r--tests/rustdoc/primitive/search-index-primitive-inherent-method-23511.rs (renamed from tests/rustdoc/search-index-primitive-inherent-method-23511.rs)0
-rw-r--r--tests/rustdoc/private/doc-hidden-private-67851-both.rs (renamed from tests/rustdoc/doc-hidden-private-67851-both.rs)0
-rw-r--r--tests/rustdoc/private/doc-hidden-private-67851-hidden.rs (renamed from tests/rustdoc/doc-hidden-private-67851-hidden.rs)0
-rw-r--r--tests/rustdoc/private/doc-hidden-private-67851-neither.rs (renamed from tests/rustdoc/doc-hidden-private-67851-neither.rs)0
-rw-r--r--tests/rustdoc/private/doc-hidden-private-67851-private.rs (renamed from tests/rustdoc/doc-hidden-private-67851-private.rs)0
-rw-r--r--tests/rustdoc/private/empty-impl-block-private-with-doc.rs (renamed from tests/rustdoc/empty-impl-block-private-with-doc.rs)0
-rw-r--r--tests/rustdoc/private/empty-impl-block-private.rs (renamed from tests/rustdoc/empty-impl-block-private.rs)0
-rw-r--r--tests/rustdoc/private/empty-mod-private.rs (renamed from tests/rustdoc/empty-mod-private.rs)0
-rw-r--r--tests/rustdoc/private/enum-variant-private-46767.rs (renamed from tests/rustdoc/enum-variant-private-46767.rs)0
-rw-r--r--tests/rustdoc/private/files-creation-private.rs (renamed from tests/rustdoc/files-creation-private.rs)0
-rw-r--r--tests/rustdoc/private/hidden-private.rs (renamed from tests/rustdoc/hidden-private.rs)0
-rw-r--r--tests/rustdoc/private/inline-private-with-intermediate-doc-hidden.rs (renamed from tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs)0
-rw-r--r--tests/rustdoc/private/inner-private-110422.rs (renamed from tests/rustdoc/inner-private-110422.rs)0
-rw-r--r--tests/rustdoc/private/macro-document-private-duplicate.rs (renamed from tests/rustdoc/macro-document-private-duplicate.rs)0
-rw-r--r--tests/rustdoc/private/macro-document-private.rs (renamed from tests/rustdoc/macro-document-private.rs)0
-rw-r--r--tests/rustdoc/private/macro-private-not-documented.rs (renamed from tests/rustdoc/macro-private-not-documented.rs)0
-rw-r--r--tests/rustdoc/private/missing-private-inlining-109258.rs (renamed from tests/rustdoc/missing-private-inlining-109258.rs)0
-rw-r--r--tests/rustdoc/private/private-fields-tuple-struct.rs (renamed from tests/rustdoc/private-fields-tuple-struct.rs)0
-rw-r--r--tests/rustdoc/private/private-non-local-fields-2.rs (renamed from tests/rustdoc/private-non-local-fields-2.rs)0
-rw-r--r--tests/rustdoc/private/private-non-local-fields.rs (renamed from tests/rustdoc/private-non-local-fields.rs)0
-rw-r--r--tests/rustdoc/private/private-type-alias.rs (renamed from tests/rustdoc/private-type-alias.rs)0
-rw-r--r--tests/rustdoc/private/private-type-cycle-110629.rs (renamed from tests/rustdoc/private-type-cycle-110629.rs)0
-rw-r--r--tests/rustdoc/private/private-use-decl-macro-47038.rs (renamed from tests/rustdoc/private-use-decl-macro-47038.rs)0
-rw-r--r--tests/rustdoc/private/private-use.rs (renamed from tests/rustdoc/private-use.rs)0
-rw-r--r--tests/rustdoc/private/public-impl-mention-private-generic-46380-2.rs (renamed from tests/rustdoc/public-impl-mention-private-generic-46380-2.rs)0
-rw-r--r--tests/rustdoc/private/traits-in-bodies-private.rs (renamed from tests/rustdoc/traits-in-bodies-private.rs)0
-rw-r--r--tests/rustdoc/reexport/alias-reexport.rs (renamed from tests/rustdoc/alias-reexport.rs)0
-rw-r--r--tests/rustdoc/reexport/alias-reexport2.rs (renamed from tests/rustdoc/alias-reexport2.rs)0
-rw-r--r--tests/rustdoc/reexport/anonymous-reexport-108931.rs (renamed from tests/rustdoc/anonymous-reexport-108931.rs)0
-rw-r--r--tests/rustdoc/reexport/anonymous-reexport.rs (renamed from tests/rustdoc/anonymous-reexport.rs)0
-rw-r--r--tests/rustdoc/reexport/auxiliary/alias-reexport.rs (renamed from tests/rustdoc/auxiliary/alias-reexport.rs)0
-rw-r--r--tests/rustdoc/reexport/auxiliary/alias-reexport2.rs (renamed from tests/rustdoc/auxiliary/alias-reexport2.rs)0
-rw-r--r--tests/rustdoc/reexport/auxiliary/all-item-types.rs22
-rw-r--r--tests/rustdoc/reexport/auxiliary/issue-113982-doc_auto_cfg-reexport-foreign.rs (renamed from tests/rustdoc/auxiliary/issue-113982-doc_auto_cfg-reexport-foreign.rs)0
-rw-r--r--tests/rustdoc/reexport/auxiliary/issue-28927-1.rs (renamed from tests/rustdoc/auxiliary/issue-28927-1.rs)0
-rw-r--r--tests/rustdoc/reexport/auxiliary/issue-28927-2.rs (renamed from tests/rustdoc/auxiliary/issue-28927-2.rs)0
-rw-r--r--tests/rustdoc/reexport/auxiliary/primitive-reexport.rs (renamed from tests/rustdoc/auxiliary/primitive-reexport.rs)0
-rw-r--r--tests/rustdoc/reexport/auxiliary/reexport-check.rs (renamed from tests/rustdoc/auxiliary/reexport-check.rs)0
-rw-r--r--tests/rustdoc/reexport/auxiliary/reexport-doc-aux.rs (renamed from tests/rustdoc/auxiliary/reexport-doc-aux.rs)0
-rw-r--r--tests/rustdoc/reexport/auxiliary/reexports.rs (renamed from tests/rustdoc/auxiliary/reexports.rs)0
-rw-r--r--tests/rustdoc/reexport/blanket-reexport-item.rs (renamed from tests/rustdoc/blanket-reexport-item.rs)0
-rw-r--r--tests/rustdoc/reexport/cfg_doc_reexport.rs (renamed from tests/rustdoc/cfg_doc_reexport.rs)0
-rw-r--r--tests/rustdoc/reexport/doc-hidden-reexports-109449.rs (renamed from tests/rustdoc/doc-hidden-reexports-109449.rs)0
-rw-r--r--tests/rustdoc/reexport/doc_auto_cfg-reexport-foreign-113982.rs (renamed from tests/rustdoc/doc_auto_cfg-reexport-foreign-113982.rs)0
-rw-r--r--tests/rustdoc/reexport/duplicated-glob-reexport-60522.rs (renamed from tests/rustdoc/duplicated-glob-reexport-60522.rs)0
-rw-r--r--tests/rustdoc/reexport/enum-variant-reexport-35488.rs (renamed from tests/rustdoc/enum-variant-reexport-35488.rs)0
-rw-r--r--tests/rustdoc/reexport/foreigntype-reexport.rs (renamed from tests/rustdoc/foreigntype-reexport.rs)0
-rw-r--r--tests/rustdoc/reexport/glob-reexport-attribute-merge-120487.rs (renamed from tests/rustdoc/glob-reexport-attribute-merge-120487.rs)0
-rw-r--r--tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs (renamed from tests/rustdoc/glob-reexport-attribute-merge-doc-auto-cfg.rs)0
-rw-r--r--tests/rustdoc/reexport/ice-reexport-crate-root-28927.rs (renamed from tests/rustdoc/ice-reexport-crate-root-28927.rs)0
-rw-r--r--tests/rustdoc/reexport/local-reexport-doc.rs (renamed from tests/rustdoc/local-reexport-doc.rs)0
-rw-r--r--tests/rustdoc/reexport/no-compiler-reexport.rs (renamed from tests/rustdoc/no-compiler-reexport.rs)0
-rw-r--r--tests/rustdoc/reexport/overlapping-reexport-105735-2.rs (renamed from tests/rustdoc/overlapping-reexport-105735-2.rs)0
-rw-r--r--tests/rustdoc/reexport/overlapping-reexport-105735.rs (renamed from tests/rustdoc/overlapping-reexport-105735.rs)0
-rw-r--r--tests/rustdoc/reexport/primitive-reexport.rs (renamed from tests/rustdoc/primitive-reexport.rs)0
-rw-r--r--tests/rustdoc/reexport/pub-reexport-of-pub-reexport-46506.rs (renamed from tests/rustdoc/pub-reexport-of-pub-reexport-46506.rs)0
-rw-r--r--tests/rustdoc/reexport/reexport-attr-merge.rs (renamed from tests/rustdoc/reexport-attr-merge.rs)0
-rw-r--r--tests/rustdoc/reexport/reexport-cfg.rs (renamed from tests/rustdoc/reexport-cfg.rs)0
-rw-r--r--tests/rustdoc/reexport/reexport-check.rs (renamed from tests/rustdoc/reexport-check.rs)0
-rw-r--r--tests/rustdoc/reexport/reexport-dep-foreign-fn.rs (renamed from tests/rustdoc/reexport-dep-foreign-fn.rs)0
-rw-r--r--tests/rustdoc/reexport/reexport-doc-hidden-inside-private.rs (renamed from tests/rustdoc/reexport-doc-hidden-inside-private.rs)0
-rw-r--r--tests/rustdoc/reexport/reexport-doc-hidden.rs (renamed from tests/rustdoc/reexport-doc-hidden.rs)0
-rw-r--r--tests/rustdoc/reexport/reexport-doc.rs (renamed from tests/rustdoc/reexport-doc.rs)0
-rw-r--r--tests/rustdoc/reexport/reexport-hidden-macro.rs (renamed from tests/rustdoc/reexport-hidden-macro.rs)0
-rw-r--r--tests/rustdoc/reexport/reexport-macro.rs (renamed from tests/rustdoc/reexport-macro.rs)0
-rw-r--r--tests/rustdoc/reexport/reexport-of-doc-hidden.rs (renamed from tests/rustdoc/reexport-of-doc-hidden.rs)0
-rw-r--r--tests/rustdoc/reexport/reexport-of-reexport-108679.rs (renamed from tests/rustdoc/reexport-of-reexport-108679.rs)0
-rw-r--r--tests/rustdoc/reexport/reexport-stability-tags-deprecated-and-portability.rs (renamed from tests/rustdoc/reexport-stability-tags-deprecated-and-portability.rs)0
-rw-r--r--tests/rustdoc/reexport/reexport-stability-tags-unstable-and-portability.rs (renamed from tests/rustdoc/reexport-stability-tags-unstable-and-portability.rs)0
-rw-r--r--tests/rustdoc/reexport/reexport-trait-from-hidden-111064-2.rs (renamed from tests/rustdoc/reexport-trait-from-hidden-111064-2.rs)0
-rw-r--r--tests/rustdoc/reexport/reexport-trait-from-hidden-111064.rs (renamed from tests/rustdoc/reexport-trait-from-hidden-111064.rs)0
-rw-r--r--tests/rustdoc/reexport/reexports-of-same-name.rs (renamed from tests/rustdoc/reexports-of-same-name.rs)0
-rw-r--r--tests/rustdoc/reexport/reexports-priv.rs (renamed from tests/rustdoc/reexports-priv.rs)0
-rw-r--r--tests/rustdoc/reexport/reexports.rs (renamed from tests/rustdoc/reexports.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/assoc-type-source-link.rs (renamed from tests/rustdoc/assoc-type-source-link.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/auxiliary/issue-26606-macro.rs (renamed from tests/rustdoc/auxiliary/issue-26606-macro.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/auxiliary/issue-34274.rs (renamed from tests/rustdoc/auxiliary/issue-34274.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/auxiliary/source-code-bar.rs (renamed from tests/rustdoc/auxiliary/source-code-bar.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/auxiliary/source_code.rs (renamed from tests/rustdoc/auxiliary/source_code.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/auxiliary/src-links-external.rs (renamed from tests/rustdoc/auxiliary/src-links-external.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/check-source-code-urls-to-def-std.rs (renamed from tests/rustdoc/check-source-code-urls-to-def-std.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/check-source-code-urls-to-def.rs (renamed from tests/rustdoc/check-source-code-urls-to-def.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/doc-hidden-source.rs (renamed from tests/rustdoc/doc-hidden-source.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/html-no-source.rs (renamed from tests/rustdoc/html-no-source.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/source-code-highlight.rs (renamed from tests/rustdoc/source-code-highlight.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/source-file.rs (renamed from tests/rustdoc/source-file.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/source-line-numbers.rs (renamed from tests/rustdoc/source-line-numbers.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/source-version-separator.rs (renamed from tests/rustdoc/source-version-separator.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/src-link-external-macro-26606.rs (renamed from tests/rustdoc/src-link-external-macro-26606.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/src-links-auto-impls.rs (renamed from tests/rustdoc/src-links-auto-impls.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/src-links-external.rs (renamed from tests/rustdoc/src-links-external.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/src-links-implementor-43893.rs (renamed from tests/rustdoc/src-links-implementor-43893.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/src-links-inlined-34274.rs (renamed from tests/rustdoc/src-links-inlined-34274.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/src-links.rs (renamed from tests/rustdoc/src-links.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/src-links/compiletest-ignore-dir (renamed from tests/rustdoc/src-links/compiletest-ignore-dir)0
-rw-r--r--tests/rustdoc/source-code-pages/src-links/fizz.rs (renamed from tests/rustdoc/src-links/fizz.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/src-links/mod.rs (renamed from tests/rustdoc/src-links/mod.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/src-mod-path-absolute-26995.rs (renamed from tests/rustdoc/src-mod-path-absolute-26995.rs)0
-rw-r--r--tests/rustdoc/source-code-pages/version-separator-without-source.rs (renamed from tests/rustdoc/version-separator-without-source.rs)0
-rw-r--r--tests/ui-fulldeps/stable-mir/check_assoc_items.rs24
-rw-r--r--tests/ui-fulldeps/stable-mir/check_attribute.rs4
-rw-r--r--tests/ui/abi/lib-defaults.rs15
-rw-r--r--tests/ui/annotate-snippet/missing-type.rs3
-rw-r--r--tests/ui/annotate-snippet/missing-type.stderr2
-rw-r--r--tests/ui/annotate-snippet/multispan.rs3
-rw-r--r--tests/ui/annotate-snippet/multispan.stderr14
-rw-r--r--tests/ui/asm/global-asm-mono-sym-fn.rs27
-rw-r--r--tests/ui/asm/naked-asm-mono-sym-fn.rs35
-rw-r--r--tests/ui/asm/naked-functions.rs6
-rw-r--r--tests/ui/associated-inherent-types/bugs/wf-check-skipped.next.stderr13
-rw-r--r--tests/ui/associated-inherent-types/bugs/wf-check-skipped.rs5
-rw-r--r--tests/ui/async-await/async-closures/def-path.stderr4
-rw-r--r--tests/ui/attributes/export/crate-type-2.rs2
-rw-r--r--tests/ui/attributes/export/crate-type-2.stderr9
-rw-r--r--tests/ui/attributes/export/crate-type.rs2
-rw-r--r--tests/ui/attributes/export/crate-type.stderr9
-rw-r--r--tests/ui/attributes/export/exportable.rs139
-rw-r--r--tests/ui/attributes/export/exportable.stderr130
-rw-r--r--tests/ui/attributes/export/lang-item.rs8
-rw-r--r--tests/ui/attributes/export/lang-item.stderr8
-rw-r--r--tests/ui/attributes/no_link/auxiliary/empty-crate-1.rs (renamed from tests/ui/auxiliary/issue-13560-1.rs)2
-rw-r--r--tests/ui/attributes/no_link/auxiliary/empty-crate-2.rs (renamed from tests/ui/auxiliary/issue-13560-2.rs)0
-rw-r--r--tests/ui/attributes/no_link/auxiliary/no_link-crate.rs6
-rw-r--r--tests/ui/attributes/no_link/multiple-crates-and-no_link.rs17
-rw-r--r--tests/ui/attributes/no_link/no-link-unknown-crate.rs19
-rw-r--r--tests/ui/attributes/no_link/no-link-unknown-crate.stderr (renamed from tests/ui/no-link-unknown-crate.stderr)2
-rw-r--r--tests/ui/auxiliary/inner_static.rs51
-rw-r--r--tests/ui/auxiliary/issue-13560-3.rs6
-rw-r--r--tests/ui/bootstrap/rustc_bootstrap.rs3
-rw-r--r--tests/ui/borrowck/regions-bound-missing-bound-in-impl.rs6
-rw-r--r--tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr83
-rw-r--r--tests/ui/cast/cast-alias-of-array-to-element.rs22
-rw-r--r--tests/ui/cfg/cfg_false_no_std-2.rs9
-rw-r--r--tests/ui/check-cfg/and-more-diagnostic.rs2
-rw-r--r--tests/ui/check-cfg/target_feature.stderr3
-rw-r--r--tests/ui/closures/opaque-upvar.rs19
-rw-r--r--tests/ui/closures/print/closure-print-generic-trim-off-verbose-2.stderr2
-rw-r--r--tests/ui/closures/print/closure-print-generic-verbose-2.stderr2
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs21
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs22
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs20
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs23
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs24
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs22
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs23
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs24
-rw-r--r--tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs22
-rw-r--r--tests/ui/compiletest-self-test/compile-flags-last.rs3
-rw-r--r--tests/ui/conditional-compilation/cfg-arg-invalid-7.rs5
-rw-r--r--tests/ui/const-generics/const-arg-in-const-arg.min.stderr70
-rw-r--r--tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr15
-rw-r--r--tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr34
-rw-r--r--tests/ui/const-generics/invalid-enum.stderr44
-rw-r--r--tests/ui/consts/const_in_pattern/reject_non_structural.rs1
-rw-r--r--tests/ui/consts/const_in_pattern/reject_non_structural.stderr8
-rw-r--r--tests/ui/consts/missing_span_in_backtrace.rs2
-rw-r--r--tests/ui/consts/missing_span_in_backtrace.stderr12
-rw-r--r--tests/ui/cross-crate/auxiliary/inline-cross-crate.rs (renamed from tests/ui/auxiliary/issue-18502.rs)0
-rw-r--r--tests/ui/cross-crate/auxiliary/llvm-miscompile-MarkValue-MaybeLive.rs (renamed from tests/ui/auxiliary/issue-76387.rs)0
-rw-r--r--tests/ui/cross-crate/inline-cross-crate.rs12
-rw-r--r--tests/ui/cross-crate/llvm-miscompile-MarkValue-MaybeLive.rs22
-rw-r--r--tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs6
-rw-r--r--tests/ui/delegation/unsupported.stderr8
-rw-r--r--tests/ui/derives/deriving-with-repr-packed-move-errors.rs18
-rw-r--r--tests/ui/derives/deriving-with-repr-packed-move-errors.stderr39
-rw-r--r--tests/ui/derives/deriving-with-repr-packed.rs2
-rw-r--r--tests/ui/derives/deriving-with-repr-packed.stderr12
-rw-r--r--tests/ui/diagnostic-width/flag-json.rs5
-rw-r--r--tests/ui/diagnostic-width/flag-json.stderr6
-rw-r--r--tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr10
-rw-r--r--tests/ui/error-codes/E0195.rs18
-rw-r--r--tests/ui/error-codes/E0195.stderr39
-rw-r--r--tests/ui/error-codes/E0253.rs10
-rw-r--r--tests/ui/error-codes/E0253.stderr9
-rw-r--r--tests/ui/error-emitter/highlighting.rs3
-rw-r--r--tests/ui/error-emitter/highlighting.svg4
-rw-r--r--tests/ui/error-emitter/highlighting.windows.svg4
-rw-r--r--tests/ui/error-emitter/multiline-multipart-suggestion.rs3
-rw-r--r--tests/ui/error-emitter/multiline-multipart-suggestion.svg6
-rw-r--r--tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg6
-rw-r--r--tests/ui/errors/auxiliary/file-debuginfo.rs11
-rw-r--r--tests/ui/errors/auxiliary/file-diag.rs11
-rw-r--r--tests/ui/errors/auxiliary/file-macro.rs11
-rw-r--r--tests/ui/errors/auxiliary/file.rs8
-rw-r--r--tests/ui/errors/auxiliary/trait-debuginfo.rs4
-rw-r--r--tests/ui/errors/auxiliary/trait-diag.rs4
-rw-r--r--tests/ui/errors/auxiliary/trait-macro.rs4
-rw-r--r--tests/ui/errors/auxiliary/trait.rs1
-rw-r--r--tests/ui/errors/remap-path-prefix-diagnostics.not-diag-in-deps.stderr17
-rw-r--r--tests/ui/errors/remap-path-prefix-diagnostics.only-debuginfo-in-deps.stderr17
-rw-r--r--tests/ui/errors/remap-path-prefix-diagnostics.only-diag-in-deps.stderr17
-rw-r--r--tests/ui/errors/remap-path-prefix-diagnostics.only-macro-in-deps.stderr17
-rw-r--r--tests/ui/errors/remap-path-prefix-diagnostics.rs57
-rw-r--r--tests/ui/errors/remap-path-prefix-diagnostics.with-debuginfo-in-deps.stderr17
-rw-r--r--tests/ui/errors/remap-path-prefix-diagnostics.with-diag-in-deps.stderr17
-rw-r--r--tests/ui/errors/remap-path-prefix-diagnostics.with-macro-in-deps.stderr17
-rw-r--r--tests/ui/errors/remap-path-prefix-macro.normal.run.stdout1
-rw-r--r--tests/ui/errors/remap-path-prefix-macro.not-macro-in-deps.run.stdout3
-rw-r--r--tests/ui/errors/remap-path-prefix-macro.only-debuginfo-in-deps.run.stdout3
-rw-r--r--tests/ui/errors/remap-path-prefix-macro.only-diag-in-deps.run.stdout3
-rw-r--r--tests/ui/errors/remap-path-prefix-macro.only-macro-in-deps.run.stdout3
-rw-r--r--tests/ui/errors/remap-path-prefix-macro.rs47
-rw-r--r--tests/ui/errors/remap-path-prefix-macro.with-debuginfo-in-deps.run.stdout3
-rw-r--r--tests/ui/errors/remap-path-prefix-macro.with-diag-in-deps.run.stdout3
-rw-r--r--tests/ui/errors/remap-path-prefix-macro.with-macro-in-deps.run.stdout3
-rw-r--r--tests/ui/errors/remap-path-prefix-macro.with-macro-scope.run.stdout1
-rw-r--r--tests/ui/errors/remap-path-prefix-macro.without-macro-scope.run.stdout1
-rw-r--r--tests/ui/explain/basic.rs (renamed from tests/ui/explain.rs)0
-rw-r--r--tests/ui/explain/basic.stdout (renamed from tests/ui/explain.stdout)0
-rw-r--r--tests/ui/explain/error-with-no-explanation.rs3
-rw-r--r--tests/ui/explain/error-with-no-explanation.stderr2
-rw-r--r--tests/ui/explain/invalid-error-code.rs2
-rw-r--r--tests/ui/explain/invalid-error-code.stderr2
-rw-r--r--tests/ui/explain/no-E-prefix.rs2
-rw-r--r--tests/ui/explain/no-E-prefix.stdout57
-rw-r--r--tests/ui/explain/overflow-error-code.rs4
-rw-r--r--tests/ui/explain/overflow-error-code.stderr2
-rw-r--r--tests/ui/feature-gates/bench.rs2
-rw-r--r--tests/ui/feature-gates/bench.stderr40
-rw-r--r--tests/ui/feature-gates/feature-gate-apx-target-feature.rs6
-rw-r--r--tests/ui/feature-gates/feature-gate-apx-target-feature.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-avx10_target_feature.rs6
-rw-r--r--tests/ui/feature-gates/feature-gate-avx10_target_feature.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-export_stable.rs5
-rw-r--r--tests/ui/feature-gates/feature-gate-export_stable.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-frontmatter.rs5
-rw-r--r--tests/ui/feature-gates/feature-gate-frontmatter.stderr15
-rw-r--r--tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs3
-rw-r--r--tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr12
-rw-r--r--tests/ui/fn/fn-trait-use-named-params-issue-140169.rs12
-rw-r--r--tests/ui/fn/fn-trait-use-named-params-issue-140169.stderr38
-rw-r--r--tests/ui/fn/param-mismatch-foreign.rs1
-rw-r--r--tests/ui/fn/param-mismatch-foreign.stderr2
-rw-r--r--tests/ui/fn/signature-error-reporting-under-verbose.rs1
-rw-r--r--tests/ui/fn/signature-error-reporting-under-verbose.stderr2
-rw-r--r--tests/ui/frontmatter/auxiliary/lib.rs6
-rw-r--r--tests/ui/frontmatter/auxiliary/makro.rs8
-rw-r--r--tests/ui/frontmatter/dot-in-infostring-leading.rs9
-rw-r--r--tests/ui/frontmatter/dot-in-infostring-leading.stderr10
-rw-r--r--tests/ui/frontmatter/dot-in-infostring-non-leading.rs9
-rw-r--r--tests/ui/frontmatter/escape.rs14
-rw-r--r--tests/ui/frontmatter/extra-after-end.rs7
-rw-r--r--tests/ui/frontmatter/extra-after-end.stderr8
-rw-r--r--tests/ui/frontmatter/frontmatter-after-tokens.rs10
-rw-r--r--tests/ui/frontmatter/frontmatter-after-tokens.stderr10
-rw-r--r--tests/ui/frontmatter/frontmatter-non-lexible-tokens.rs12
-rw-r--r--tests/ui/frontmatter/frontmatter-whitespace-1.rs10
-rw-r--r--tests/ui/frontmatter/frontmatter-whitespace-1.stderr26
-rw-r--r--tests/ui/frontmatter/frontmatter-whitespace-2.rs15
-rw-r--r--tests/ui/frontmatter/frontmatter-whitespace-2.stderr26
-rw-r--r--tests/ui/frontmatter/frontmatter-whitespace-3.rs16
-rw-r--r--tests/ui/frontmatter/frontmatter-whitespace-4.rs9
-rw-r--r--tests/ui/frontmatter/included-frontmatter.rs12
-rw-r--r--tests/ui/frontmatter/infostring-fail.rs9
-rw-r--r--tests/ui/frontmatter/infostring-fail.stderr10
-rw-r--r--tests/ui/frontmatter/mismatch-1.rs10
-rw-r--r--tests/ui/frontmatter/mismatch-1.stderr16
-rw-r--r--tests/ui/frontmatter/mismatch-2.rs8
-rw-r--r--tests/ui/frontmatter/mismatch-2.stderr22
-rw-r--r--tests/ui/frontmatter/multifrontmatter-2.rs12
-rw-r--r--tests/ui/frontmatter/multifrontmatter-2.stderr22
-rw-r--r--tests/ui/frontmatter/multifrontmatter.rs13
-rw-r--r--tests/ui/frontmatter/multifrontmatter.stderr10
-rw-r--r--tests/ui/frontmatter/proc-macro-observer.rs12
-rw-r--r--tests/ui/frontmatter/shebang.rs13
-rw-r--r--tests/ui/frontmatter/unclosed-1.rs10
-rw-r--r--tests/ui/frontmatter/unclosed-1.stderr16
-rw-r--r--tests/ui/frontmatter/unclosed-2.rs15
-rw-r--r--tests/ui/frontmatter/unclosed-2.stderr31
-rw-r--r--tests/ui/frontmatter/unclosed-3.rs16
-rw-r--r--tests/ui/frontmatter/unclosed-3.stderr41
-rw-r--r--tests/ui/frontmatter/unclosed-4.rs9
-rw-r--r--tests/ui/frontmatter/unclosed-4.stderr16
-rw-r--r--tests/ui/frontmatter/unclosed-5.rs10
-rw-r--r--tests/ui/frontmatter/unclosed-5.stderr29
-rw-r--r--tests/ui/generic-const-items/user_type_annotations_pattern.rs14
-rw-r--r--tests/ui/generic-const-items/user_type_annotations_pattern.stderr11
-rw-r--r--tests/ui/impl-privacy-xc-1.rs10
-rw-r--r--tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.rs3
-rw-r--r--tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg6
-rw-r--r--tests/ui/impl-trait/in-trait/doesnt-satisfy.stderr4
-rw-r--r--tests/ui/impl-trait/in-trait/dump.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/dump.stderr2
-rw-r--r--tests/ui/impl-trait/in-trait/method-compatability-via-leakage-cycle.current.stderr4
-rw-r--r--tests/ui/impl-trait/in-trait/method-compatability-via-leakage-cycle.next.stderr8
-rw-r--r--tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr4
-rw-r--r--tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.rs12
-rw-r--r--tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.stderr17
-rw-r--r--tests/ui/imports/issue-30560.rs3
-rw-r--r--tests/ui/imports/issue-30560.stderr8
-rw-r--r--tests/ui/imports/reexports.stderr2
-rw-r--r--tests/ui/inference/detect-old-time-version-format_description-parse.rs13
-rw-r--r--tests/ui/inference/detect-old-time-version-format_description-parse.stderr14
-rw-r--r--tests/ui/inner-static.rs14
-rw-r--r--tests/ui/invalid-compile-flags/emit-output-types-without-args.rs3
-rw-r--r--tests/ui/issue-13560.rs13
-rw-r--r--tests/ui/issue-18502.rs8
-rw-r--r--tests/ui/issue-24106.rs8
-rw-r--r--tests/ui/issue-76387-llvm-miscompile.rs21
-rw-r--r--tests/ui/issues/issue-18959.rs1
-rw-r--r--tests/ui/issues/issue-18959.stderr24
-rw-r--r--tests/ui/issues/issue-48131.rs4
-rw-r--r--tests/ui/issues/issue-48131.stderr2
-rw-r--r--tests/ui/json/json-bom-plus-crlf-multifile.rs5
-rw-r--r--tests/ui/json/json-bom-plus-crlf.rs4
-rw-r--r--tests/ui/json/json-bom-plus-crlf.stderr6
-rw-r--r--tests/ui/json/json-short.rs1
-rw-r--r--tests/ui/json/json-short.stderr2
-rw-r--r--tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr8
-rw-r--r--tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr46
-rw-r--r--tests/ui/lazy-type-alias/inherent-impls-overflow.rs8
-rw-r--r--tests/ui/link-native-libs/lib-defaults.rs17
-rw-r--r--tests/ui/linking/weird-export-names.rs10
-rw-r--r--tests/ui/lint/bare-trait-objects-path.stderr40
-rw-r--r--tests/ui/lint/expansion-time.rs7
-rw-r--r--tests/ui/lint/expansion-time.stderr33
-rw-r--r--tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs10
-rw-r--r--tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr24
-rw-r--r--tests/ui/lint/unused_parens_json_suggestion.fixed2
-rw-r--r--tests/ui/lint/unused_parens_json_suggestion.rs2
-rw-r--r--tests/ui/lint/unused_parens_json_suggestion.stderr6
-rw-r--r--tests/ui/lint/unused_parens_remove_json_suggestion.fixed10
-rw-r--r--tests/ui/lint/unused_parens_remove_json_suggestion.rs10
-rw-r--r--tests/ui/lint/unused_parens_remove_json_suggestion.stderr36
-rw-r--r--tests/ui/macros/auxiliary/fancy-panic.rs (renamed from tests/ui/auxiliary/fancy-panic.rs)0
-rw-r--r--tests/ui/macros/auxiliary/return_from_external_macro.rs11
-rw-r--r--tests/ui/macros/non-fmt-panic.fixed (renamed from tests/ui/non-fmt-panic.fixed)6
-rw-r--r--tests/ui/macros/non-fmt-panic.rs (renamed from tests/ui/non-fmt-panic.rs)6
-rw-r--r--tests/ui/macros/non-fmt-panic.stderr (renamed from tests/ui/non-fmt-panic.stderr)70
-rw-r--r--tests/ui/macros/return_from_external_macro.rs17
-rw-r--r--tests/ui/macros/return_from_external_macro.stderr29
-rw-r--r--tests/ui/methods/disambiguate-multiple-blanket-impl.stderr30
-rw-r--r--tests/ui/methods/disambiguate-multiple-impl.stderr30
-rw-r--r--tests/ui/methods/disambiguate-multiple-trait-2.stderr64
-rw-r--r--tests/ui/methods/disambiguate-multiple-trait.stderr30
-rw-r--r--tests/ui/mir/lint/assignment-overlap.rs3
-rw-r--r--tests/ui/mir/lint/call-overlap.rs3
-rw-r--r--tests/ui/mir/lint/storage-live.rs3
-rw-r--r--tests/ui/mir/lint/storage-live.stderr4
-rw-r--r--tests/ui/mir/lint/storage-return.rs3
-rw-r--r--tests/ui/mir/validate/critical-edge.rs4
-rw-r--r--tests/ui/mismatched_types/dont-point-return-on-E0308.rs1
-rw-r--r--tests/ui/mismatched_types/dont-point-return-on-E0308.stderr2
-rw-r--r--tests/ui/mismatched_types/similar_paths_primitive.rs3
-rw-r--r--tests/ui/mismatched_types/similar_paths_primitive.stderr6
-rw-r--r--tests/ui/nll/nested-bodies-in-dead-code.rs28
-rw-r--r--tests/ui/nll/nested-bodies-in-dead-code.stderr50
-rw-r--r--tests/ui/no-link-unknown-crate.rs4
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix-i32.fixed11
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix-i32.rs11
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix-i32.stderr22
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix-i64.fixed11
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix-i64.rs11
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix-i64.stderr22
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix-isize.fixed11
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix-isize.rs11
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix-isize.stderr22
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix-u32.fixed11
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix-u32.rs11
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix-u32.stderr22
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix-u64.fixed11
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix-u64.rs11
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix-u64.stderr22
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix-usize.fixed11
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix-usize.rs11
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix-usize.stderr22
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix.fixed69
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix.rs69
-rw-r--r--tests/ui/numeric/numeric-suffix/numeric-suffix.stderr136
-rw-r--r--tests/ui/on-unimplemented/bad-annotation.rs131
-rw-r--r--tests/ui/on-unimplemented/bad-annotation.stderr118
-rw-r--r--tests/ui/panic-runtime/two-panic-runtimes.rs14
-rw-r--r--tests/ui/panic-runtime/want-abort-got-unwind.rs12
-rw-r--r--tests/ui/panic-runtime/want-abort-got-unwind2.rs16
-rw-r--r--tests/ui/panics/default-backtrace-ice.rs7
-rw-r--r--tests/ui/panics/default-backtrace-ice.stderr2
-rw-r--r--tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs8
-rw-r--r--tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr45
-rw-r--r--tests/ui/parser/fn-arg-doc-comment.rs3
-rw-r--r--tests/ui/parser/fn-arg-doc-comment.stderr10
-rw-r--r--tests/ui/parser/issues/invalid-parse-format-issue-139104.rs13
-rw-r--r--tests/ui/parser/issues/invalid-parse-format-issue-139104.stderr92
-rw-r--r--tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs5
-rw-r--r--tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr39
-rw-r--r--tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs1
-rw-r--r--tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs1
-rw-r--r--tests/ui/pattern/auxiliary/cross-crate-enum-pattern.rs (renamed from tests/ui/auxiliary/issue-24106.rs)0
-rw-r--r--tests/ui/pattern/cross-crate-enum-pattern.rs13
-rw-r--r--tests/ui/pattern/deref-patterns/bindings.rs2
-rw-r--r--tests/ui/pattern/deref-patterns/byte-string-type-errors.rs19
-rw-r--r--tests/ui/pattern/deref-patterns/byte-string-type-errors.stderr40
-rw-r--r--tests/ui/pattern/deref-patterns/closure_capture.rs8
-rw-r--r--tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.rs54
-rw-r--r--tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.stable.stderr55
-rw-r--r--tests/ui/pattern/deref-patterns/deref-box.rs10
-rw-r--r--tests/ui/pattern/deref-patterns/implicit-cow-deref.rs4
-rw-r--r--tests/ui/pattern/deref-patterns/needs-gate.rs26
-rw-r--r--tests/ui/pattern/deref-patterns/needs-gate.stderr65
-rw-r--r--tests/ui/pattern/deref-patterns/strings.rs44
-rw-r--r--tests/ui/pattern/deref-patterns/typeck_fail.rs13
-rw-r--r--tests/ui/pattern/deref-patterns/typeck_fail.stderr23
-rw-r--r--tests/ui/pattern/deref-patterns/usefulness/empty-types.rs47
-rw-r--r--tests/ui/pattern/deref-patterns/usefulness/empty-types.stderr38
-rw-r--r--tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.rs48
-rw-r--r--tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.stderr43
-rw-r--r--tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.rs28
-rw-r--r--tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.stderr63
-rw-r--r--tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.rs33
-rw-r--r--tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.stderr60
-rw-r--r--tests/ui/pattern/normalize-ty-in-range.rs24
-rw-r--r--tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs1
-rw-r--r--tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr2
-rw-r--r--tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.rs4
-rw-r--r--tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr16
-rw-r--r--tests/ui/privacy/auxiliary/impl-privacy-cross-crate-1.rs (renamed from tests/ui/auxiliary/impl_privacy_xc_1.rs)0
-rw-r--r--tests/ui/privacy/auxiliary/impl-privacy-cross-crate-2.rs (renamed from tests/ui/privacy/auxiliary/impl_privacy_xc_2.rs)0
-rw-r--r--tests/ui/privacy/impl-privacy-cross-crate-1.rs10
-rw-r--r--tests/ui/privacy/impl-privacy-cross-crate-2.rs10
-rw-r--r--tests/ui/privacy/impl-privacy-xc-2.rs10
-rw-r--r--tests/ui/pub/pub-restricted-warning.rs25
-rw-r--r--tests/ui/pub/pub-restricted-warning.stderr27
-rw-r--r--tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.stderr4
-rw-r--r--tests/ui/runtime/backtrace-debuginfo.rs4
-rw-r--r--tests/ui/rust-2024/unsafe-attributes/auxiliary/safe_attr.rs7
-rw-r--r--tests/ui/rust-2024/unsafe-attributes/safe-proc-macro-attribute.rs22
-rw-r--r--tests/ui/rust-2024/unsafe-attributes/safe-proc-macro-attribute.unknown_attr.stderr14
-rw-r--r--tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-allow.rs16
-rw-r--r--tests/ui/stability-attribute/generics-default-stability.stderr48
-rw-r--r--tests/ui/stability-attribute/suggest-vec-allocator-api.stderr16
-rw-r--r--tests/ui/statics/auxiliary/inner_static.rs67
-rw-r--r--tests/ui/statics/inner-static.rs30
-rw-r--r--tests/ui/target-feature/abi-incompatible-target-feature-attribute.riscv.stderr8
-rw-r--r--tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs17
-rw-r--r--tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr8
-rw-r--r--tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.riscv.stderr19
-rw-r--r--tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs22
-rw-r--r--tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.x86.stderr (renamed from tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.stderr)0
-rw-r--r--tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.rs (renamed from tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs)3
-rw-r--r--tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.stderr (renamed from tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.stderr)0
-rw-r--r--tests/ui/target-feature/abi-required-target-feature-attribute.rs (renamed from tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs)2
-rw-r--r--tests/ui/target-feature/abi-required-target-feature-flag-disable.aarch64.stderr (renamed from tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.stderr)0
-rw-r--r--tests/ui/target-feature/abi-required-target-feature-flag-disable.loongarch.stderr11
-rw-r--r--tests/ui/target-feature/abi-required-target-feature-flag-disable.riscv.stderr11
-rw-r--r--tests/ui/target-feature/abi-required-target-feature-flag-disable.rs27
-rw-r--r--tests/ui/target-feature/abi-required-target-feature-flag-disable.x86-implied.stderr (renamed from tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.stderr)0
-rw-r--r--tests/ui/target-feature/abi-required-target-feature-flag-disable.x86.stderr (renamed from tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.stderr)0
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs15
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs13
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs15
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs15
-rw-r--r--tests/ui/target_modifiers/auxiliary/fixed_x18.rs7
-rw-r--r--tests/ui/target_modifiers/incompatible_fixedx18.error_generated.stderr13
-rw-r--r--tests/ui/target_modifiers/incompatible_fixedx18.rs17
-rw-r--r--tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr53
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums-locals.stderr16
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums-xc1.stderr24
-rw-r--r--tests/ui/traits/next-solver/dont-ice-on-bad-transmute-in-typeck.stderr4
-rw-r--r--tests/ui/traits/next-solver/global-param-env-after-norm.rs15
-rw-r--r--tests/ui/traits/next-solver/issue-118950-root-region.rs1
-rw-r--r--tests/ui/traits/next-solver/issue-118950-root-region.stderr14
-rw-r--r--tests/ui/traits/next-solver/non-wf-in-coerce-pointers.stderr4
-rw-r--r--tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr20
-rw-r--r--tests/ui/traits/next-solver/opaques/duplicate-opaque-type-entries.rs25
-rw-r--r--tests/ui/traits/next-solver/overflow-plus-ambiguity-normalizes-to-response.rs56
-rw-r--r--tests/ui/traits/object/constrain-via-unnecessary-bound.rs24
-rw-r--r--tests/ui/traits/object/constrain-via-unnecessary-bound.stderr19
-rw-r--r--tests/ui/traits/object/pretty.stderr6
-rw-r--r--tests/ui/traits/suggest-remove-deref-issue-140166.rs18
-rw-r--r--tests/ui/traits/suggest-remove-deref-issue-140166.stderr22
-rw-r--r--tests/ui/transmute/unnecessary-transmutation.fixed9
-rw-r--r--tests/ui/transmute/unnecessary-transmutation.rs9
-rw-r--r--tests/ui/transmute/unnecessary-transmutation.stderr54
-rw-r--r--tests/ui/treat-err-as-bug/err.rs5
-rw-r--r--tests/ui/treat-err-as-bug/err.stderr2
-rw-r--r--tests/ui/treat-err-as-bug/panic-causes-oom-112708.rs3
-rw-r--r--tests/ui/treat-err-as-bug/span_delayed_bug.rs5
-rw-r--r--tests/ui/treat-err-as-bug/span_delayed_bug.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.rs16
-rw-r--r--tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.stderr26
-rw-r--r--tests/ui/type-inference/regression-issue-81317.rs71
-rw-r--r--tests/ui/type-inference/regression-issue-81317.stderr17
-rw-r--r--tests/ui/type/type-check/point-at-inference-4.rs1
-rw-r--r--tests/ui/type/type-check/point-at-inference-4.stderr4
-rw-r--r--tests/ui/unboxed-closures/arg-constrained-after-closure-inference.rs16
-rw-r--r--tests/ui/unpretty/exhaustive-asm.hir.stdout3
-rw-r--r--tests/ui/unpretty/exhaustive.hir.stdout98
-rw-r--r--tests/ui/unpretty/hir-tree.rs3
-rw-r--r--tests/ui/use/import_trait_associated_item_bad.rs18
-rw-r--r--tests/ui/use/import_trait_associated_item_bad.stderr49
-rw-r--r--tests/ui/use/import_trait_associated_item_glob.rs17
-rw-r--r--tests/ui/use/use-from-trait-xc.rs2
-rw-r--r--tests/ui/use/use-from-trait-xc.stderr12
-rw-r--r--tests/ui/use/use-from-trait.rs2
-rw-r--r--tests/ui/use/use-from-trait.stderr12
-rw-r--r--tests/ui/wf/check-wf-of-normalized-signature.rs24
-rw-r--r--tests/ui/wf/wf-normalization-sized.next.stderr25
-rw-r--r--tests/ui/wf/wf-normalization-sized.rs2
-rw-r--r--triagebot.toml19
1555 files changed, 19522 insertions, 10754 deletions
diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml
index 94553608a2f..ca088ba31fd 100644
--- a/.github/workflows/post-merge.yml
+++ b/.github/workflows/post-merge.yml
@@ -25,12 +25,19 @@ jobs:
         env:
           GH_TOKEN: ${{ github.token }}
         run: |
+          # Give GitHub some time to propagate the information that the PR was merged
+          sleep 60
+
           # Get closest bors merge commit
           PARENT_COMMIT=`git rev-list --author='bors <bors@rust-lang.org>' -n1 --first-parent HEAD^1`
           echo "Parent: ${PARENT_COMMIT}"
 
           # Find PR for the current commit
           HEAD_PR=`gh pr list --search "${{ github.sha }}" --state merged --json number --jq '.[0].number'`
+          if [ -z "${HEAD_PR}" ]; then
+            echo "PR for commit SHA ${{ github.sha }} not found, exiting"
+            exit 1
+          fi
           echo "HEAD: ${{ github.sha }} (#${HEAD_PR})"
 
           cd src/ci/citool
diff --git a/Cargo.lock b/Cargo.lock
index 361d237b3af..fa0fa33ea75 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -158,12 +158,9 @@ dependencies = [
 
 [[package]]
 name = "anyhow"
-version = "1.0.97"
+version = "1.0.98"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
-dependencies = [
- "backtrace",
-]
+checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
 
 [[package]]
 name = "ar_archive_writer"
@@ -188,9 +185,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
 
 [[package]]
 name = "askama"
-version = "0.13.0"
+version = "0.13.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a4e46abb203e00ef226442d452769233142bbfdd79c3941e84c8e61c4112543"
+checksum = "5d4744ed2eef2645831b441d8f5459689ade2ab27c854488fbab1fbe94fce1a7"
 dependencies = [
  "askama_derive",
  "itoa",
@@ -201,9 +198,9 @@ dependencies = [
 
 [[package]]
 name = "askama_derive"
-version = "0.13.0"
+version = "0.13.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54398906821fd32c728135f7b351f0c7494ab95ae421d41b6f5a020e158f28a6"
+checksum = "d661e0f57be36a5c14c48f78d09011e67e0cb618f269cca9f2fd8d15b68c46ac"
 dependencies = [
  "askama_parser",
  "basic-toml",
@@ -213,7 +210,7 @@ dependencies = [
  "rustc-hash 2.1.1",
  "serde",
  "serde_derive",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -225,7 +222,7 @@ dependencies = [
  "memchr",
  "serde",
  "serde_derive",
- "winnow 0.7.6",
+ "winnow 0.7.9",
 ]
 
 [[package]]
@@ -281,9 +278,9 @@ checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
 
 [[package]]
 name = "blake3"
-version = "1.8.1"
+version = "1.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "389a099b34312839e16420d499a9cad9650541715937ffbdd40d36f49e77eeb3"
+checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0"
 dependencies = [
  "arrayref",
  "arrayvec",
@@ -452,9 +449,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
 
 [[package]]
 name = "chrono"
-version = "0.4.40"
+version = "0.4.41"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
+checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
 dependencies = [
  "android-tzdata",
  "iana-time-zone",
@@ -496,9 +493,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.5.36"
+version = "4.5.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2df961d8c8a0d08aa9945718ccf584145eee3f3aa06cddbeac12933781102e04"
+checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -516,9 +513,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.36"
+version = "4.5.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "132dbda40fb6753878316a489d5a1242a8ef2f0d9e47ba01c951ea8aa7d013a5"
+checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2"
 dependencies = [
  "anstream",
  "anstyle",
@@ -535,7 +532,7 @@ dependencies = [
  "heck 0.5.0",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -561,13 +558,13 @@ dependencies = [
  "if_chain",
  "itertools",
  "parking_lot",
- "pulldown-cmark 0.11.3",
+ "pulldown-cmark",
  "quote",
  "regex",
  "rustc_tools_util 0.4.2",
  "serde",
  "serde_json",
- "syn 2.0.100",
+ "syn 2.0.101",
  "tempfile",
  "termize",
  "tokio",
@@ -653,16 +650,16 @@ dependencies = [
 
 [[package]]
 name = "color-eyre"
-version = "0.6.3"
+version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5"
+checksum = "e6e1761c0e16f8883bbbb8ce5990867f4f06bf11a0253da6495a04ce4b6ef0ec"
 dependencies = [
  "backtrace",
  "color-spantrace",
  "eyre",
  "indenter",
  "once_cell",
- "owo-colors",
+ "owo-colors 4.2.0",
  "tracing-error",
 ]
 
@@ -684,17 +681,17 @@ dependencies = [
  "nom",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
 name = "color-spantrace"
-version = "0.2.1"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2"
+checksum = "2ddd8d5bfda1e11a501d0a7303f3bfed9aa632ebdb859be40d0fd70478ed70d5"
 dependencies = [
  "once_cell",
- "owo-colors",
+ "owo-colors 4.2.0",
  "tracing-core",
  "tracing-error",
 ]
@@ -780,6 +777,7 @@ name = "coverage-dump"
 version = "0.1.0"
 dependencies = [
  "anyhow",
+ "itertools",
  "leb128",
  "md-5",
  "miniz_oxide 0.7.4",
@@ -910,7 +908,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "strsim",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -921,7 +919,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
 dependencies = [
  "darling_core",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -943,13 +941,13 @@ dependencies = [
 
 [[package]]
 name = "derive-where"
-version = "1.2.7"
+version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62d671cc41a825ebabc75757b62d3d168c577f9149b2d49ece1dad1f72119d25"
+checksum = "e73f2692d4bd3cac41dca28934a39894200c9fabf49586d77d0e5954af1d7902"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -970,7 +968,7 @@ dependencies = [
  "darling",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -980,7 +978,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c"
 dependencies = [
  "derive_builder_core",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -992,7 +990,7 @@ dependencies = [
  "darling",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -1082,7 +1080,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -1361,7 +1359,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -1434,9 +1432,9 @@ dependencies = [
 
 [[package]]
 name = "getrandom"
-version = "0.2.15"
+version = "0.2.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
+checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
 dependencies = [
  "cfg-if",
  "libc",
@@ -1502,9 +1500,9 @@ dependencies = [
 
 [[package]]
 name = "hashbrown"
-version = "0.15.2"
+version = "0.15.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
+checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
 dependencies = [
  "allocator-api2",
  "equivalent",
@@ -1761,7 +1759,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -1919,9 +1917,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
 
 [[package]]
 name = "jiff"
-version = "0.2.6"
+version = "0.2.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f33145a5cbea837164362c7bd596106eb7c5198f97d1ba6f6ebb3223952e488"
+checksum = "d07d8d955d798e7a4d6f9c58cd1f1916e790b42b092758a9ef6e16fef9f1b3fd"
 dependencies = [
  "jiff-static",
  "log",
@@ -1932,13 +1930,13 @@ dependencies = [
 
 [[package]]
 name = "jiff-static"
-version = "0.2.6"
+version = "0.2.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43ce13c40ec6956157a3635d97a1ee2df323b263f09ea14165131289cb0f5c19"
+checksum = "f244cfe006d98d26f859c7abd1318d85327e1882dc9cef80f62daeeb0adcf300"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -2071,14 +2069,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
 dependencies = [
  "cfg-if",
- "windows-targets 0.52.6",
+ "windows-targets 0.48.5",
 ]
 
 [[package]]
 name = "libm"
-version = "0.2.11"
+version = "0.2.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa"
+checksum = "c9627da5196e5d8ed0b0495e61e518847578da83483c37288316d9b2e03a7f72"
 
 [[package]]
 name = "libredox"
@@ -2202,7 +2200,7 @@ checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -2307,7 +2305,7 @@ dependencies = [
  "libffi",
  "libloading",
  "measureme",
- "rand 0.9.0",
+ "rand 0.9.1",
  "regex",
  "rustc_version",
  "smallvec",
@@ -2467,6 +2465,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
 
 [[package]]
+name = "objc2-core-foundation"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "objc2-io-kit"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71c1c64d6120e51cd86033f67176b1cb66780c2efe34dec55176f77befd93c0a"
+dependencies = [
+ "libc",
+ "objc2-core-foundation",
+]
+
+[[package]]
 name = "object"
 version = "0.32.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2525,9 +2542,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.107"
+version = "0.9.108"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07"
+checksum = "e145e1651e858e820e4860f7b9c5e169bc1d8ce1c86043be79fa7b7634821847"
 dependencies = [
  "cc",
  "libc",
@@ -2550,7 +2567,6 @@ dependencies = [
  "humansize",
  "humantime",
  "log",
- "serde",
  "serde_json",
  "sysinfo",
  "tabled",
@@ -2578,6 +2594,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
 
 [[package]]
+name = "owo-colors"
+version = "4.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1036865bb9422d3300cf723f657c2851d0e9ab12567854b1f4eba3d77decf564"
+
+[[package]]
 name = "pad"
 version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2681,7 +2703,7 @@ dependencies = [
  "pest_meta",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -2798,7 +2820,7 @@ version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "abec3fb083c10660b3854367697da94c674e9e82aa7511014dc958beeb7215e9"
 dependencies = [
- "owo-colors",
+ "owo-colors 3.5.0",
  "pad",
 ]
 
@@ -2810,35 +2832,24 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.94"
+version = "1.0.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
 dependencies = [
  "unicode-ident",
 ]
 
 [[package]]
 name = "psm"
-version = "0.1.25"
+version = "0.1.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f58e5423e24c18cc840e1c98370b3993c6649cd1678b4d24318bcf0a083cbe88"
+checksum = "6e944464ec8536cd1beb0bbfd96987eb5e3b72f2ecdafdc5c769a37f1fa2ae1f"
 dependencies = [
  "cc",
 ]
 
 [[package]]
 name = "pulldown-cmark"
-version = "0.9.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b"
-dependencies = [
- "bitflags",
- "memchr",
- "unicase",
-]
-
-[[package]]
-name = "pulldown-cmark"
 version = "0.11.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "679341d22c78c6c649893cbd6c3278dcbe9fc4faa62fea3a9296ae2b50c14625"
@@ -2895,13 +2906,12 @@ dependencies = [
 
 [[package]]
 name = "rand"
-version = "0.9.0"
+version = "0.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
+checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97"
 dependencies = [
  "rand_chacha 0.9.0",
  "rand_core 0.9.3",
- "zerocopy",
 ]
 
 [[package]]
@@ -2930,7 +2940,7 @@ version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
 dependencies = [
- "getrandom 0.2.15",
+ "getrandom 0.2.16",
 ]
 
 [[package]]
@@ -2973,9 +2983,9 @@ dependencies = [
 
 [[package]]
 name = "redox_syscall"
-version = "0.5.11"
+version = "0.5.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3"
+checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af"
 dependencies = [
  "bitflags",
 ]
@@ -2986,7 +2996,7 @@ version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
 dependencies = [
- "getrandom 0.2.15",
+ "getrandom 0.2.16",
  "libredox",
  "thiserror 1.0.69",
 ]
@@ -2997,7 +3007,7 @@ version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
 dependencies = [
- "getrandom 0.2.15",
+ "getrandom 0.2.16",
  "libredox",
  "thiserror 2.0.12",
 ]
@@ -3179,7 +3189,7 @@ name = "rustc_abi"
 version = "0.0.0"
 dependencies = [
  "bitflags",
- "rand 0.9.0",
+ "rand 0.9.1",
  "rand_xoshiro",
  "rustc_data_structures",
  "rustc_hashes",
@@ -3583,13 +3593,13 @@ dependencies = [
  "rustc_query_system",
  "rustc_resolve",
  "rustc_session",
- "rustc_smir",
  "rustc_span",
  "rustc_target",
  "rustc_trait_selection",
  "rustc_ty_utils",
  "serde_json",
  "shlex",
+ "stable_mir",
  "tracing",
  "windows 0.59.0",
 ]
@@ -3693,7 +3703,7 @@ dependencies = [
  "fluent-syntax",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
  "unic-langid",
 ]
 
@@ -3805,7 +3815,7 @@ dependencies = [
 name = "rustc_incremental"
 version = "0.0.0"
 dependencies = [
- "rand 0.9.0",
+ "rand 0.9.1",
  "rustc_ast",
  "rustc_data_structures",
  "rustc_errors",
@@ -3839,7 +3849,7 @@ version = "0.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -3985,7 +3995,7 @@ version = "0.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
  "synstructure",
 ]
 
@@ -4015,6 +4025,7 @@ dependencies = [
  "rustc_session",
  "rustc_span",
  "rustc_target",
+ "tempfile",
  "tracing",
 ]
 
@@ -4314,7 +4325,7 @@ version = "0.0.0"
 dependencies = [
  "bitflags",
  "itertools",
- "pulldown-cmark 0.11.3",
+ "pulldown-cmark",
  "rustc_arena",
  "rustc_ast",
  "rustc_ast_pretty",
@@ -4371,7 +4382,7 @@ dependencies = [
  "bitflags",
  "getopts",
  "libc",
- "rand 0.9.0",
+ "rand 0.9.1",
  "rustc_abi",
  "rustc_ast",
  "rustc_data_structures",
@@ -4481,7 +4492,6 @@ dependencies = [
  "itertools",
  "rustc_abi",
  "rustc_ast",
- "rustc_attr_parsing",
  "rustc_data_structures",
  "rustc_errors",
  "rustc_fluent_macro",
@@ -4575,7 +4585,7 @@ version = "0.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
  "synstructure",
 ]
 
@@ -4599,7 +4609,6 @@ dependencies = [
  "indexmap",
  "itertools",
  "minifier",
- "pulldown-cmark 0.9.6",
  "pulldown-cmark-escape",
  "regex",
  "rustdoc-json-types",
@@ -4666,7 +4675,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "serde",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -4700,9 +4709,9 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "1.0.5"
+version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf"
+checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
 dependencies = [
  "bitflags",
  "errno",
@@ -4803,7 +4812,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -4840,9 +4849,9 @@ dependencies = [
 
 [[package]]
 name = "sha2"
-version = "0.10.8"
+version = "0.10.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
+checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
 dependencies = [
  "cfg-if",
  "cpufeatures",
@@ -4961,9 +4970,9 @@ dependencies = [
 
 [[package]]
 name = "stacker"
-version = "0.1.20"
+version = "0.1.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "601f9201feb9b09c00266478bf459952b9ef9a6b94edb2f21eba14ab681a60a9"
+checksum = "cddb07e32ddb770749da91081d8d0ac3a16f1a569a18b20348cd371f5dead06b"
 dependencies = [
  "cc",
  "cfg-if",
@@ -5049,9 +5058,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.100"
+version = "2.0.101"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
+checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -5060,24 +5069,25 @@ dependencies = [
 
 [[package]]
 name = "synstructure"
-version = "0.13.1"
+version = "0.13.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
+checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
 name = "sysinfo"
-version = "0.31.4"
+version = "0.35.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "355dbe4f8799b304b05e1b0f05fc59b2a18d36645cf169607da45bde2f69a1be"
+checksum = "b897c8ea620e181c7955369a31be5f48d9a9121cb59fd33ecef9ff2a34323422"
 dependencies = [
- "core-foundation-sys",
  "libc",
- "windows 0.57.0",
+ "objc2-core-foundation",
+ "objc2-io-kit",
+ "windows 0.61.1",
 ]
 
 [[package]]
@@ -5161,7 +5171,7 @@ version = "0.1.0"
 dependencies = [
  "indicatif",
  "num",
- "rand 0.9.0",
+ "rand 0.9.1",
  "rand_chacha 0.9.0",
  "rayon",
 ]
@@ -5198,7 +5208,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -5209,7 +5219,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -5335,9 +5345,9 @@ dependencies = [
 
 [[package]]
 name = "toml_datetime"
-version = "0.6.8"
+version = "0.6.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
+checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3"
 dependencies = [
  "serde",
 ]
@@ -5375,7 +5385,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -5546,7 +5556,7 @@ checksum = "1ed7f4237ba393424195053097c1516bd4590dc82b84f2f97c5c69e12704555b"
 dependencies = [
  "proc-macro-hack",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
  "unic-langid-impl",
 ]
 
@@ -5762,7 +5772,7 @@ dependencies = [
  "log",
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
  "wasm-bindgen-shared",
 ]
 
@@ -5784,7 +5794,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
@@ -5954,22 +5964,25 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
 [[package]]
 name = "windows"
-version = "0.57.0"
+version = "0.59.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"
+checksum = "7f919aee0a93304be7f62e8e5027811bbba96bcb1de84d6618be56e43f8a32a1"
 dependencies = [
- "windows-core 0.57.0",
- "windows-targets 0.52.6",
+ "windows-core 0.59.0",
+ "windows-targets 0.53.0",
 ]
 
 [[package]]
 name = "windows"
-version = "0.59.0"
+version = "0.61.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f919aee0a93304be7f62e8e5027811bbba96bcb1de84d6618be56e43f8a32a1"
+checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419"
 dependencies = [
- "windows-core 0.59.0",
- "windows-targets 0.53.0",
+ "windows-collections",
+ "windows-core 0.61.0",
+ "windows-future",
+ "windows-link",
+ "windows-numerics",
 ]
 
 [[package]]
@@ -5984,15 +5997,12 @@ dependencies = [
 ]
 
 [[package]]
-name = "windows-core"
-version = "0.57.0"
+name = "windows-collections"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
+checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
 dependencies = [
- "windows-implement 0.57.0",
- "windows-interface 0.57.0",
- "windows-result 0.1.2",
- "windows-targets 0.52.6",
+ "windows-core 0.61.0",
 ]
 
 [[package]]
@@ -6002,8 +6012,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "810ce18ed2112484b0d4e15d022e5f598113e220c53e373fb31e67e21670c1ce"
 dependencies = [
  "windows-implement 0.59.0",
- "windows-interface 0.59.1",
- "windows-result 0.3.2",
+ "windows-interface",
+ "windows-result",
  "windows-strings 0.3.1",
  "windows-targets 0.53.0",
 ]
@@ -6015,21 +6025,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980"
 dependencies = [
  "windows-implement 0.60.0",
- "windows-interface 0.59.1",
+ "windows-interface",
  "windows-link",
- "windows-result 0.3.2",
+ "windows-result",
  "windows-strings 0.4.0",
 ]
 
 [[package]]
-name = "windows-implement"
-version = "0.57.0"
+name = "windows-future"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
+checksum = "7a1d6bbefcb7b60acd19828e1bc965da6fcf18a7e39490c5f8be71e54a19ba32"
 dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.100",
+ "windows-core 0.61.0",
+ "windows-link",
 ]
 
 [[package]]
@@ -6040,7 +6049,7 @@ checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -6051,18 +6060,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
-]
-
-[[package]]
-name = "windows-interface"
-version = "0.57.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -6073,7 +6071,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -6083,12 +6081,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
 
 [[package]]
-name = "windows-result"
-version = "0.1.2"
+name = "windows-numerics"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
+checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
 dependencies = [
- "windows-targets 0.52.6",
+ "windows-core 0.61.0",
+ "windows-link",
 ]
 
 [[package]]
@@ -6341,9 +6340,9 @@ dependencies = [
 
 [[package]]
 name = "winnow"
-version = "0.7.6"
+version = "0.7.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10"
+checksum = "d9fb597c990f03753e08d3c29efbfcf2019a003b4bf4ba19225c158e1549f0f3"
 dependencies = [
  "memchr",
 ]
@@ -6464,28 +6463,28 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
  "synstructure",
 ]
 
 [[package]]
 name = "zerocopy"
-version = "0.8.24"
+version = "0.8.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"
+checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb"
 dependencies = [
  "zerocopy-derive",
 ]
 
 [[package]]
 name = "zerocopy-derive"
-version = "0.8.24"
+version = "0.8.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"
+checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
 
 [[package]]
@@ -6505,7 +6504,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
  "synstructure",
 ]
 
@@ -6528,5 +6527,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.100",
+ "syn 2.0.101",
 ]
diff --git a/RELEASES.md b/RELEASES.md
index 0948eb85192..1a77c33b995 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,169 @@
+Version 1.87.0 (2025-05-15)
+==========================
+
+<a id="1.87.0-Language"></a>
+
+Language
+--------
+- [Stabilize `asm_goto` feature](https://github.com/rust-lang/rust/pull/133870)
+- [Allow parsing open beginning ranges (`..EXPR`) after unary operators `!`, `~`, `-`, and `*`}](https://github.com/rust-lang/rust/pull/134900).
+- [Don't require method impls for methods with `Self: Sized` bounds in `impl`s for unsized types](https://github.com/rust-lang/rust/pull/135480)
+- [Stabilize `feature(precise_capturing_in_traits)` allowing `use<...>` bounds on return position `impl Trait` in `trait`s](https://github.com/rust-lang/rust/pull/138128)
+
+<a id="1.87.0-Compiler"></a>
+
+Compiler
+--------
+- [x86: make SSE2 required for i686 targets and use it to pass SIMD types](https://github.com/rust-lang/rust/pull/135408)
+
+<a id="1.87.0-Platform-Support"></a>
+
+Platform Support
+----------------
+- [Remove `i586-pc-windows-msvc` target](https://github.com/rust-lang/rust/pull/137957)
+
+Refer to Rust's [platform support page][platform-support-doc]
+for more information on Rust's tiered platform support.
+
+[platform-support-doc]: https://doc.rust-lang.org/rustc/platform-support.html
+
+<a id="1.87.0-Libraries"></a>
+
+Libraries
+---------
+- [Stabilize the anonymous pipe API](https://github.com/rust-lang/rust/issues/127154)
+- [Add support for unbounded left/right shift operations](https://github.com/rust-lang/rust/issues/129375) 
+- [Print pointer metadata in `Debug` impl of raw pointers](https://github.com/rust-lang/rust/pull/135080)
+- [`Vec::with_capacity` guarantees it allocates with the amount requested, even if `Vec::capacity` returns a different number.](https://github.com/rust-lang/rust/pull/135933)
+- Most `std::arch` intrinsics which don't take pointer arguments can now be called from safe code if the caller has the appropriate target features already enabled (https://github.com/rust-lang/stdarch/pull/1714, https://github.com/rust-lang/stdarch/pull/1716, https://github.com/rust-lang/stdarch/pull/1717)
+- [Undeprecate `env::home_dir`](https://github.com/rust-lang/rust/pull/137327)
+- [Denote `ControlFlow` as `#[must_use]`](https://github.com/rust-lang/rust/pull/137449)
+- [Macros such as `assert_eq!` and `vec!` now support `const {...}` expressions](https://github.com/rust-lang/rust/pull/138162)
+
+<a id="1.87.0-Stabilized-APIs"></a>
+
+Stabilized APIs
+---------------
+
+- [`Vec::extract_if`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.extract_if)
+- [`vec::ExtractIf`](https://doc.rust-lang.org/nightly/std/vec/struct.ExtractIf.html)
+- [`LinkedList::extract_if`](https://doc.rust-lang.org/nightly/std/collections/struct.LinkedList.html#method.extract_if)
+- [`linked_list::ExtractIf`](https://doc.rust-lang.org/nightly/std/collections/linked_list/struct.ExtractIf.html)
+- [`<[T]>::split_off`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off)
+- [`<[T]>::split_off_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_mut)
+- [`<[T]>::split_off_first`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_first)
+- [`<[T]>::split_off_first_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_first_mut)
+- [`<[T]>::split_off_last`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_last)
+- [`<[T]>::split_off_last_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_last_mut)
+- [`String::extend_from_within`](https://doc.rust-lang.org/stable/alloc/string/struct.String.html#method.extend_from_within)
+- [`os_str::Display`](https://doc.rust-lang.org/nightly/std/ffi/os_str/struct.Display.html)
+- [`OsString::display`](https://doc.rust-lang.org/nightly/std/ffi/struct.OsString.html#method.display)
+- [`OsStr::display`](https://doc.rust-lang.org/nightly/std/ffi/struct.OsStr.html#method.display)
+- [`io::pipe`](https://doc.rust-lang.org/nightly/std/io/fn.pipe.html)
+- [`io::PipeReader`](https://doc.rust-lang.org/nightly/std/io/struct.PipeReader.html)
+- [`io::PipeWriter`](https://doc.rust-lang.org/nightly/std/io/struct.PipeWriter.html)
+- [`impl From<PipeReader> for OwnedHandle`](https://doc.rust-lang.org/nightly/std/os/windows/io/struct.OwnedHandle.html#impl-From%3CPipeReader%3E-for-OwnedHandle)
+- [`impl From<PipeWriter> for OwnedHandle`](https://doc.rust-lang.org/nightly/std/os/windows/io/struct.OwnedHandle.html#impl-From%3CPipeWriter%3E-for-OwnedHandle)
+- [`impl From<PipeReader> for Stdio`](https://doc.rust-lang.org/nightly/std/process/struct.Stdio.html)
+- [`impl From<PipeWriter> for Stdio`](https://doc.rust-lang.org/nightly/std/process/struct.Stdio.html#impl-From%3CPipeWriter%3E-for-Stdio)
+- [`impl From<PipeReader> for OwnedFd`](https://doc.rust-lang.org/nightly/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeReader%3E-for-OwnedFd)
+- [`impl From<PipeWriter> for OwnedFd`](https://doc.rust-lang.org/nightly/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeWriter%3E-for-OwnedFd)
+- [`Box<MaybeUninit<T>>::write`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.write)
+- [`impl TryFrom<Vec<u8>> for String`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#impl-TryFrom%3CVec%3Cu8%3E%3E-for-String)
+
+These APIs are now stable in const contexts:
+
+- [`<*const T>::offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.offset_from_unsigned)
+- [`<*const T>::byte_offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.byte_offset_from_unsigned)
+- [`<*mut T>::offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.offset_from_unsigned-1)
+- [`<*mut T>::byte_offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.byte_offset_from_unsigned-1)
+- [`NonNull::offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/ptr/struct.NonNull.html#method.offset_from_unsigned)
+- [`NonNull::byte_offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/ptr/struct.NonNull.html#method.byte_offset_from_unsigned)
+- [`<uN>::cast_signed`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.cast_signed)
+- [`NonZero::<uN>::cast_signed`](https://doc.rust-lang.org/nightly/std/num/struct.NonZero.html#method.cast_signed-5).
+- [`<iN>::cast_signed`](https://doc.rust-lang.org/nightly/std/primitive.isize.html#method.cast_signed).
+- [`NonZero::<iN>::cast_unsigned`](https://doc.rust-lang.org/nightly/std/num/struct.NonZero.html#method.cast_unsigned-5).
+- [`<uN>::is_multiple_of`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.is_multiple_of)
+- [`<uN>::unbounded_shl`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.unbounded_shl)
+- [`<uN>::unbounded_shr`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.unbounded_shr)
+- [`<iN>::unbounded_shl`](https://doc.rust-lang.org/nightly/std/primitive.isize.html#method.unbounded_shl)
+- [`<iN>::unbounded_shr`](https://doc.rust-lang.org/nightly/std/primitive.isize.html#method.unbounded_shr)
+- [`<str>::from_utf8`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8)
+- [`<str>::from_utf8_mut`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8_mut)
+- [`<str>::from_utf8_unchecked`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8_unchecked)
+- [`<str>::from_utf8_unchecked_mut`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8_unchecked_mut)
+- [`core::str::from_utf8_mut`](https://doc.rust-lang.org/nightly/std/str/fn.from_utf8_mut.html)
+- [`<[T]>::copy_from_slice`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.copy_from_slice)
+- [`SocketAddr::set_ip`](https://doc.rust-lang.org/nightly/std/net/enum.SocketAddr.html#method.set_ip)
+- [`SocketAddr::set_port`](https://doc.rust-lang.org/nightly/std/net/enum.SocketAddr.html#method.set_port),
+- [`SocketAddrV4::set_ip`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV4.html#method.set_ip)
+- [`SocketAddrV4::set_port`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV4.html#method.set_port),
+- [`SocketAddrV6::set_ip`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_ip)
+- [`SocketAddrV6::set_port`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_port)
+- [`SocketAddrV6::set_flowinfo`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_flowinfo)
+- [`SocketAddrV6::set_scope_id`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_scope_id)
+- [`char::is_digit`](https://doc.rust-lang.org/nightly/std/primitive.char.html#method.is_digit)
+- [`char::is_whitespace`](https://doc.rust-lang.org/nightly/std/primitive.char.html#method.is_whitespace)
+- [`<iN>::midpoint`](https://doc.rust-lang.org/std/primitive.isize.html#method.midpoint)
+- [`<[[T; N]]>::as_flattened`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_flattened)
+- [`<[[T; N]]>::as_flattened_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_flattened_mut) 
+- [`String::into_bytes`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.into_bytes)
+- [`String::as_str`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_str)
+- [`String::capacity`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.capacity)
+- [`String::as_bytes`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_bytes)
+- [`String::len`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.len)
+- [`String::is_empty`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.is_empty)
+- [`String::as_mut_str`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_mut_str)
+- [`String::as_mut_vec`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_mut_vec)
+- [`Vec::as_ptr`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_ptr)
+- [`Vec::as_slice`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_slice)
+- [`Vec::capacity`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.capacity)
+- [`Vec::len`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.len)
+- [`Vec::is_empty`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.is_empty)
+- [`Vec::as_mut_slice`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_mut_slice)
+- [`Vec::as_mut_ptr`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_mut_ptr)
+
+<a id="1.87.0-Cargo"></a>
+
+Cargo
+-----
+- [Add terminal integration via ANSI OSC 9;4 sequences](https://github.com/rust-lang/cargo/pull/14615/)
+- [chore: bump openssl to v3](https://github.com/rust-lang/cargo/pull/15232/)
+- [feat(package): add --exclude-lockfile flag](https://github.com/rust-lang/cargo/pull/15234/)
+
+<a id="1.87.0-Compatibility-Notes"></a>
+
+Compatibility Notes
+-------------------
+- [Rust now raises an error for macro invocations inside the `#![crate_name]` attribute](https://github.com/rust-lang/rust/pull/127581)
+- [Unstable fields are now always considered to be inhabited](https://github.com/rust-lang/rust/pull/133889)
+- [Macro arguments of unary operators followed by open beginning ranges may now be matched differently](https://github.com/rust-lang/rust/pull/134900)
+- [Make `Debug` impl of raw pointers print metadata if present](https://github.com/rust-lang/rust/pull/135080)
+- [Warn against function pointers using unsupported ABI strings in dependencies](https://github.com/rust-lang/rust/pull/135767)
+- [Associated types on `dyn` types are no longer deduplicated](https://github.com/rust-lang/rust/pull/136458)
+- [Forbid attributes on `..` inside of struct patterns (`let Struct { #[attribute] .. }) =`](https://github.com/rust-lang/rust/pull/136490)
+- [Make `ptr_cast_add_auto_to_object` lint into hard error](https://github.com/rust-lang/rust/pull/136764)
+- Many `std::arch` intrinsics are now safe to call in some contexts, there may now be new `unused_unsafe` warnings in existing codebases.
+- [Limit `width` and `precision` formatting options to 16 bits on all targets](https://github.com/rust-lang/rust/pull/136932)
+- [Turn order dependent trait objects future incompat warning into a hard error](https://github.com/rust-lang/rust/pull/136968)
+- [Denote `ControlFlow` as `#[must_use]`](https://github.com/rust-lang/rust/pull/137449)
+- [Windows: The standard library no longer links `advapi32`, except on win7.](https://github.com/rust-lang/rust/pull/138233) Code such as C libraries that were relying on this assumption may need to explicitly link advapi32.
+- [Proc macros can no longer observe expanded `cfg(true)` attributes.](https://github.com/rust-lang/rust/pull/138844)
+- [Start changing the internal representation of pasted tokens](https://github.com/rust-lang/rust/pull/124141). Certain invalid declarative macros that were previously accepted in obscure circumstances are now correctly rejected by the compiler. Use of a `tt` fragment specifier can often fix these macros.
+- [Don't allow flattened format_args in const.](https://github.com/rust-lang/rust/pull/139624)
+
+<a id="1.87.0-Internal-Changes"></a>
+
+Internal Changes
+----------------
+
+These changes do not affect any public interfaces of Rust, but they represent
+significant improvements to the performance or internals of rustc and related
+tools.
+
+- [Update to LLVM 20](https://github.com/rust-lang/rust/pull/135763)
+
+
 Version 1.86.0 (2025-04-03)
 ==========================
 
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 8e1a3cd1435..9f3aed9216c 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -492,9 +492,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let mut generic_args = ThinVec::new();
         for (idx, arg) in args.iter().cloned().enumerate() {
             if legacy_args_idx.contains(&idx) {
-                let parent_def_id = self.current_hir_id_owner.def_id;
                 let node_id = self.next_node_id();
-                self.create_def(parent_def_id, node_id, None, DefKind::AnonConst, f.span);
+                self.create_def(node_id, None, DefKind::AnonConst, f.span);
                 let mut visitor = WillCreateDefIdsVisitor {};
                 let const_value = if let ControlFlow::Break(span) = visitor.visit_expr(&arg) {
                     AstP(Expr {
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index c009abd729d..f48a571b86a 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1310,7 +1310,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
             // create a fake body so that the entire rest of the compiler doesn't have to deal with
             // this as a special case.
             return self.lower_fn_body(decl, contract, |this| {
-                if attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic)) {
+                if attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic))
+                    || this.tcx.is_sdylib_interface_build()
+                {
                     let span = this.lower_span(span);
                     let empty_block = hir::Block {
                         hir_id: this.next_id(),
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 9f9d1f9a556..8597820073a 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -500,12 +500,12 @@ enum GenericArgsMode {
 impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn create_def(
         &mut self,
-        parent: LocalDefId,
         node_id: ast::NodeId,
         name: Option<Symbol>,
         def_kind: DefKind,
         span: Span,
     ) -> LocalDefId {
+        let parent = self.current_hir_id_owner.def_id;
         debug_assert_ne!(node_id, ast::DUMMY_NODE_ID);
         assert!(
             self.opt_local_def_id(node_id).is_none(),
@@ -515,7 +515,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             self.tcx.hir_def_key(self.local_def_id(node_id)),
         );
 
-        let def_id = self.tcx.at(span).create_def(parent, name, def_kind).def_id();
+        let def_id = self
+            .tcx
+            .at(span)
+            .create_def(parent, name, def_kind, None, &mut self.resolver.disambiguator)
+            .def_id();
 
         debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
         self.resolver.node_id_to_def_id.insert(node_id, def_id);
@@ -787,7 +791,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             LifetimeRes::Fresh { param, kind, .. } => {
                 // Late resolution delegates to us the creation of the `LocalDefId`.
                 let _def_id = self.create_def(
-                    self.current_hir_id_owner.def_id,
                     param,
                     Some(kw::UnderscoreLifetime),
                     DefKind::LifetimeParam,
@@ -2113,8 +2116,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             hir::ConstArgKind::Path(qpath)
         } else {
             // Construct an AnonConst where the expr is the "ty"'s path.
-
-            let parent_def_id = self.current_hir_id_owner.def_id;
             let node_id = self.next_node_id();
             let span = self.lower_span(span);
 
@@ -2122,7 +2123,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             // We're lowering a const argument that was originally thought to be a type argument,
             // so the def collector didn't create the def ahead of time. That's why we have to do
             // it here.
-            let def_id = self.create_def(parent_def_id, node_id, None, DefKind::AnonConst, span);
+            let def_id = self.create_def(node_id, None, DefKind::AnonConst, span);
             let hir_id = self.lower_node_id(node_id);
 
             let path_expr = Expr {
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index 4a6929ef011..58dea472f1d 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -522,14 +522,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         span: Span,
         base_type: Span,
     ) -> &'hir hir::ConstArg<'hir> {
-        let parent_def_id = self.current_hir_id_owner.def_id;
         let node_id = self.next_node_id();
 
         // Add a definition for the in-band const def.
         // We're generating a range end that didn't exist in the AST,
         // so the def collector didn't create the def ahead of time. That's why we have to do
         // it here.
-        let def_id = self.create_def(parent_def_id, node_id, None, DefKind::AnonConst, span);
+        let def_id = self.create_def(node_id, None, DefKind::AnonConst, span);
         let hir_id = self.lower_node_id(node_id);
 
         let unstable_span = self.mark_span_with_reason(
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 1feb3e9bf9b..cbf4f2f5eb2 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -82,6 +82,10 @@ struct AstValidator<'a> {
     /// Used to ban explicit safety on foreign items when the extern block is not marked as unsafe.
     extern_mod_safety: Option<Safety>,
 
+    lint_node_id: NodeId,
+
+    is_sdylib_interface: bool,
+
     lint_buffer: &'a mut LintBuffer,
 }
 
@@ -826,7 +830,7 @@ fn validate_generic_param_order(dcx: DiagCtxtHandle<'_>, generics: &[GenericPara
 
 impl<'a> Visitor<'a> for AstValidator<'a> {
     fn visit_attribute(&mut self, attr: &Attribute) {
-        validate_attr::check_attr(&self.sess.psess, attr);
+        validate_attr::check_attr(&self.sess.psess, attr, self.lint_node_id);
     }
 
     fn visit_ty(&mut self, ty: &'a Ty) {
@@ -839,6 +843,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             self.has_proc_macro_decls = true;
         }
 
+        let previous_lint_node_id = mem::replace(&mut self.lint_node_id, item.id);
+
         if let Some(ident) = item.kind.ident()
             && attr::contains_name(&item.attrs, sym::no_mangle)
         {
@@ -948,7 +954,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 self.check_defaultness(item.span, *defaultness);
 
                 let is_intrinsic = item.attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic));
-                if body.is_none() && !is_intrinsic {
+                if body.is_none() && !is_intrinsic && !self.is_sdylib_interface {
                     self.dcx().emit_err(errors::FnWithoutBody {
                         span: item.span,
                         replace_span: self.ending_semi_or_hi(item.span),
@@ -1128,6 +1134,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             }
             _ => visit::walk_item(self, item),
         }
+
+        self.lint_node_id = previous_lint_node_id;
     }
 
     fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
@@ -1435,7 +1443,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     });
                 }
                 AssocItemKind::Fn(box Fn { body, .. }) => {
-                    if body.is_none() {
+                    if body.is_none() && !self.is_sdylib_interface {
                         self.dcx().emit_err(errors::AssocFnWithoutBody {
                             span: item.span,
                             replace_span: self.ending_semi_or_hi(item.span),
@@ -1683,6 +1691,7 @@ pub fn check_crate(
     sess: &Session,
     features: &Features,
     krate: &Crate,
+    is_sdylib_interface: bool,
     lints: &mut LintBuffer,
 ) -> bool {
     let mut validator = AstValidator {
@@ -1694,6 +1703,8 @@ pub fn check_crate(
         outer_impl_trait_span: None,
         disallow_tilde_const: Some(TildeConstReason::Item),
         extern_mod_safety: None,
+        lint_node_id: CRATE_NODE_ID,
+        is_sdylib_interface,
         lint_buffer: lints,
     };
     visit::walk_crate(&mut validator, krate);
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index e312f15f05b..915613a3913 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -514,6 +514,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
     gate_all!(contracts_internals, "contract internal machinery is for internal use only");
     gate_all!(where_clause_attrs, "attributes in `where` clause are unstable");
     gate_all!(super_let, "`super let` is experimental");
+    gate_all!(frontmatter, "frontmatters are experimental");
 
     if !visitor.features.never_patterns() {
         if let Some(spans) = spans.get(&sym::never_patterns) {
diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs
index 142c80b8e39..8a0dbadf18c 100644
--- a/compiler/rustc_ast_pretty/src/pp.rs
+++ b/compiler/rustc_ast_pretty/src/pp.rs
@@ -244,9 +244,6 @@ struct BufEntry {
 // forgotten will trigger a panic in `drop`. (Closing a box more than once
 // isn't possible because `BoxMarker` doesn't implement `Copy` or `Clone`.)
 //
-// FIXME(nnethercote): the panic in `drop` is currently disabled because a few
-// places fail to close their boxes. It can be enabled once they are fixed.
-//
 // Note: it would be better to make open/close mismatching impossible and avoid
 // the need for this marker type altogether by having functions like
 // `with_ibox` that open a box, call a closure, and then close the box. That
@@ -261,8 +258,7 @@ impl !Copy for BoxMarker {}
 
 impl Drop for BoxMarker {
     fn drop(&mut self) {
-        // FIXME(nnethercote): enable once the bad cases are fixed
-        //panic!("BoxMarker not ended with `Printer::end()`");
+        panic!("BoxMarker not ended with `Printer::end()`");
     }
 }
 
diff --git a/compiler/rustc_ast_pretty/src/pprust/mod.rs b/compiler/rustc_ast_pretty/src/pprust/mod.rs
index 551506f2aef..a05e2bd6a5d 100644
--- a/compiler/rustc_ast_pretty/src/pprust/mod.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/mod.rs
@@ -7,7 +7,9 @@ use std::borrow::Cow;
 use rustc_ast as ast;
 use rustc_ast::token::{Token, TokenKind};
 use rustc_ast::tokenstream::{TokenStream, TokenTree};
-pub use state::{AnnNode, Comments, PpAnn, PrintState, State, print_crate};
+pub use state::{
+    AnnNode, Comments, PpAnn, PrintState, State, print_crate, print_crate_as_interface,
+};
 
 /// Print the token kind precisely, without converting `$crate` into its respective crate name.
 pub fn token_kind_to_string(tok: &TokenKind) -> Cow<'static, str> {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 28d5eb87c27..0990c9b27eb 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -221,6 +221,7 @@ pub struct State<'a> {
     pub s: pp::Printer,
     comments: Option<Comments<'a>>,
     ann: &'a (dyn PpAnn + 'a),
+    is_sdylib_interface: bool,
 }
 
 const INDENT_UNIT: isize = 4;
@@ -237,9 +238,36 @@ pub fn print_crate<'a>(
     edition: Edition,
     g: &AttrIdGenerator,
 ) -> String {
+    let mut s = State {
+        s: pp::Printer::new(),
+        comments: Some(Comments::new(sm, filename, input)),
+        ann,
+        is_sdylib_interface: false,
+    };
+
+    print_crate_inner(&mut s, krate, is_expanded, edition, g);
+    s.s.eof()
+}
+
+pub fn print_crate_as_interface(
+    krate: &ast::Crate,
+    edition: Edition,
+    g: &AttrIdGenerator,
+) -> String {
     let mut s =
-        State { s: pp::Printer::new(), comments: Some(Comments::new(sm, filename, input)), ann };
+        State { s: pp::Printer::new(), comments: None, ann: &NoAnn, is_sdylib_interface: true };
 
+    print_crate_inner(&mut s, krate, false, edition, g);
+    s.s.eof()
+}
+
+fn print_crate_inner<'a>(
+    s: &mut State<'a>,
+    krate: &ast::Crate,
+    is_expanded: bool,
+    edition: Edition,
+    g: &AttrIdGenerator,
+) {
     // We need to print shebang before anything else
     // otherwise the resulting code will not compile
     // and shebang will be useless.
@@ -282,8 +310,7 @@ pub fn print_crate<'a>(
         s.print_item(item);
     }
     s.print_remaining_comments();
-    s.ann.post(&mut s, AnnNode::Crate(krate));
-    s.s.eof()
+    s.ann.post(s, AnnNode::Crate(krate));
 }
 
 /// Should two consecutive tokens be printed with a space between them?
@@ -1111,7 +1138,7 @@ impl<'a> PrintState<'a> for State<'a> {
 
 impl<'a> State<'a> {
     pub fn new() -> State<'a> {
-        State { s: pp::Printer::new(), comments: None, ann: &NoAnn }
+        State { s: pp::Printer::new(), comments: None, ann: &NoAnn, is_sdylib_interface: false }
     }
 
     fn commasep_cmnt<T, F, G>(&mut self, b: Breaks, elts: &[T], mut op: F, mut get_span: G)
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index 38cadc77b77..c9a7e2aebd0 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -13,7 +13,7 @@ use rustc_ast::{
 
 use crate::pp::Breaks::Inconsistent;
 use crate::pprust::state::fixup::FixupContext;
-use crate::pprust::state::{AnnNode, BoxMarker, INDENT_UNIT, PrintState, State};
+use crate::pprust::state::{AnnNode, INDENT_UNIT, PrintState, State};
 
 impl<'a> State<'a> {
     fn print_else(&mut self, els: Option<&ast::Expr>) {
@@ -485,12 +485,12 @@ impl<'a> State<'a> {
                 self.print_block_with_attrs(body, attrs, cb, ib);
             }
             ast::ExprKind::Loop(blk, opt_label, _) => {
+                let cb = self.cbox(0);
+                let ib = self.ibox(0);
                 if let Some(label) = opt_label {
                     self.print_ident(label.ident);
                     self.word_space(":");
                 }
-                let cb = self.cbox(0);
-                let ib = self.ibox(0);
                 self.word_nbsp("loop");
                 self.print_block_with_attrs(blk, attrs, cb, ib);
             }
@@ -542,15 +542,6 @@ impl<'a> State<'a> {
                 self.print_fn_params_and_ret(fn_decl, true);
                 self.space();
                 self.print_expr(body, FixupContext::default());
-                // FIXME(nnethercote): Bogus. Reduce visibility of `ended` once it's fixed.
-                let fake_ib = BoxMarker;
-                self.end(fake_ib);
-
-                // A box will be closed by print_expr, but we didn't want an overall
-                // wrapper so we closed the corresponding opening. so create an
-                // empty box to satisfy the close.
-                // FIXME(nnethercote): Bogus.
-                let _ib = self.ibox(0);
             }
             ast::ExprKind::Block(blk, opt_label) => {
                 if let Some(label) = opt_label {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
index 1e02ac8fd5d..70cf2f2a459 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
@@ -160,6 +160,10 @@ impl<'a> State<'a> {
 
     /// Pretty-prints an item.
     pub(crate) fn print_item(&mut self, item: &ast::Item) {
+        if self.is_sdylib_interface && item.span.is_dummy() {
+            // Do not print prelude for interface files.
+            return;
+        }
         self.hardbreak_if_not_bol();
         self.maybe_print_comment(item.span.lo());
         self.print_outer_attributes(&item.attrs);
@@ -682,6 +686,13 @@ impl<'a> State<'a> {
             self.print_contract(contract);
         }
         if let Some((body, (cb, ib))) = body_cb_ib {
+            if self.is_sdylib_interface {
+                self.word(";");
+                self.end(ib); // end inner head-block
+                self.end(cb); // end outer head-block
+                return;
+            }
+
             self.nbsp();
             self.print_block_with_attrs(body, attrs, cb, ib);
         } else {
diff --git a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs
index d37ede86cfd..c1d95d07f4c 100644
--- a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs
@@ -53,7 +53,7 @@ fn parse_unstable<'a>(
 
     for param in list.mixed() {
         let param_span = param.span();
-        if let Some(ident) = param.meta_item().and_then(|i| i.word_without_args()) {
+        if let Some(ident) = param.meta_item().and_then(|i| i.path_without_args().word()) {
             res.push(ident.name);
         } else {
             cx.emit_err(session_diagnostics::ExpectsFeatures {
diff --git a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs
index 7d1417446b2..fb3d5f57d4f 100644
--- a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs
@@ -1,5 +1,4 @@
 use rustc_attr_data_structures::{AttributeKind, DeprecatedSince, Deprecation};
-use rustc_span::symbol::Ident;
 use rustc_span::{Span, Symbol, sym};
 
 use super::SingleAttributeParser;
@@ -13,16 +12,13 @@ pub(crate) struct DeprecationParser;
 
 fn get(
     cx: &AcceptContext<'_>,
-    ident: Ident,
+    name: Symbol,
     param_span: Span,
     arg: &ArgParser<'_>,
     item: &Option<Symbol>,
 ) -> Option<Symbol> {
     if item.is_some() {
-        cx.emit_err(session_diagnostics::MultipleItem {
-            span: param_span,
-            item: ident.to_string(),
-        });
+        cx.emit_err(session_diagnostics::MultipleItem { span: param_span, item: name.to_string() });
         return None;
     }
     if let Some(v) = arg.name_value() {
@@ -83,16 +79,16 @@ impl SingleAttributeParser for DeprecationParser {
                     return None;
                 };
 
-                let (ident, arg) = param.word_or_empty();
+                let ident_name = param.path_without_args().word_sym();
 
-                match ident.name {
-                    sym::since => {
-                        since = Some(get(cx, ident, param_span, arg, &since)?);
+                match ident_name {
+                    Some(name @ sym::since) => {
+                        since = Some(get(cx, name, param_span, param.args(), &since)?);
                     }
-                    sym::note => {
-                        note = Some(get(cx, ident, param_span, arg, &note)?);
+                    Some(name @ sym::note) => {
+                        note = Some(get(cx, name, param_span, param.args(), &note)?);
                     }
-                    sym::suggestion => {
+                    Some(name @ sym::suggestion) => {
                         if !features.deprecated_suggestion() {
                             cx.emit_err(session_diagnostics::DeprecatedItemSuggestion {
                                 span: param_span,
@@ -101,12 +97,12 @@ impl SingleAttributeParser for DeprecationParser {
                             });
                         }
 
-                        suggestion = Some(get(cx, ident, param_span, arg, &suggestion)?);
+                        suggestion = Some(get(cx, name, param_span, param.args(), &suggestion)?);
                     }
                     _ => {
                         cx.emit_err(session_diagnostics::UnknownMetaItem {
                             span: param_span,
-                            item: ident.to_string(),
+                            item: param.path_without_args().to_string(),
                             expected: if features.deprecated_suggestion() {
                                 &["since", "note", "suggestion"]
                             } else {
diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs
index 26ca637faec..43dfb85a7c4 100644
--- a/compiler/rustc_attr_parsing/src/attributes/repr.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs
@@ -96,58 +96,75 @@ fn parse_repr(cx: &AcceptContext<'_>, param: &MetaItemParser<'_>) -> Option<Repr
 
     // FIXME(jdonszelmann): invert the parsing here to match on the word first and then the
     // structure.
-    let (ident, args) = param.word_or_empty();
+    let (name, ident_span) = if let Some(ident) = param.path_without_args().word() {
+        (Some(ident.name), ident.span)
+    } else {
+        (None, rustc_span::DUMMY_SP)
+    };
+
+    let args = param.args();
 
-    match (ident.name, args) {
-        (sym::align, ArgParser::NoArgs) => {
-            cx.emit_err(session_diagnostics::InvalidReprAlignNeedArg { span: ident.span });
+    match (name, args) {
+        (Some(sym::align), ArgParser::NoArgs) => {
+            cx.emit_err(session_diagnostics::InvalidReprAlignNeedArg { span: ident_span });
             None
         }
-        (sym::align, ArgParser::List(l)) => parse_repr_align(cx, l, param.span(), AlignKind::Align),
+        (Some(sym::align), ArgParser::List(l)) => {
+            parse_repr_align(cx, l, param.span(), AlignKind::Align)
+        }
 
-        (sym::packed, ArgParser::NoArgs) => Some(ReprPacked(Align::ONE)),
-        (sym::packed, ArgParser::List(l)) => {
+        (Some(sym::packed), ArgParser::NoArgs) => Some(ReprPacked(Align::ONE)),
+        (Some(sym::packed), ArgParser::List(l)) => {
             parse_repr_align(cx, l, param.span(), AlignKind::Packed)
         }
 
-        (sym::align | sym::packed, ArgParser::NameValue(l)) => {
+        (Some(name @ sym::align | name @ sym::packed), ArgParser::NameValue(l)) => {
             cx.emit_err(session_diagnostics::IncorrectReprFormatGeneric {
                 span: param.span(),
                 // FIXME(jdonszelmann) can just be a string in the diag type
-                repr_arg: &ident.to_string(),
+                repr_arg: name,
                 cause: IncorrectReprFormatGenericCause::from_lit_kind(
                     param.span(),
                     &l.value_as_lit().kind,
-                    ident.name.as_str(),
+                    name,
                 ),
             });
             None
         }
 
-        (sym::Rust, ArgParser::NoArgs) => Some(ReprRust),
-        (sym::C, ArgParser::NoArgs) => Some(ReprC),
-        (sym::simd, ArgParser::NoArgs) => Some(ReprSimd),
-        (sym::transparent, ArgParser::NoArgs) => Some(ReprTransparent),
-        (i @ int_pat!(), ArgParser::NoArgs) => {
+        (Some(sym::Rust), ArgParser::NoArgs) => Some(ReprRust),
+        (Some(sym::C), ArgParser::NoArgs) => Some(ReprC),
+        (Some(sym::simd), ArgParser::NoArgs) => Some(ReprSimd),
+        (Some(sym::transparent), ArgParser::NoArgs) => Some(ReprTransparent),
+        (Some(name @ int_pat!()), ArgParser::NoArgs) => {
             // int_pat!() should make sure it always parses
-            Some(ReprInt(int_type_of_word(i).unwrap()))
+            Some(ReprInt(int_type_of_word(name).unwrap()))
         }
 
         (
-            sym::Rust | sym::C | sym::simd | sym::transparent | int_pat!(),
+            Some(
+                name @ sym::Rust
+                | name @ sym::C
+                | name @ sym::simd
+                | name @ sym::transparent
+                | name @ int_pat!(),
+            ),
             ArgParser::NameValue(_),
         ) => {
-            cx.emit_err(session_diagnostics::InvalidReprHintNoValue {
-                span: param.span(),
-                name: ident.to_string(),
-            });
+            cx.emit_err(session_diagnostics::InvalidReprHintNoValue { span: param.span(), name });
             None
         }
-        (sym::Rust | sym::C | sym::simd | sym::transparent | int_pat!(), ArgParser::List(_)) => {
-            cx.emit_err(session_diagnostics::InvalidReprHintNoParen {
-                span: param.span(),
-                name: ident.to_string(),
-            });
+        (
+            Some(
+                name @ sym::Rust
+                | name @ sym::C
+                | name @ sym::simd
+                | name @ sym::transparent
+                | name @ int_pat!(),
+            ),
+            ArgParser::List(_),
+        ) => {
+            cx.emit_err(session_diagnostics::InvalidReprHintNoParen { span: param.span(), name });
             None
         }
 
diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs
index bdad6b50186..cd1f21d92e7 100644
--- a/compiler/rustc_attr_parsing/src/attributes/stability.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs
@@ -242,9 +242,9 @@ pub(crate) fn parse_stability(
             return None;
         };
 
-        match param.word_or_empty_without_args().name {
-            sym::feature => insert_value_into_option_or_error(cx, &param, &mut feature)?,
-            sym::since => insert_value_into_option_or_error(cx, &param, &mut since)?,
+        match param.path_without_args().word_sym() {
+            Some(sym::feature) => insert_value_into_option_or_error(cx, &param, &mut feature)?,
+            Some(sym::since) => insert_value_into_option_or_error(cx, &param, &mut since)?,
             _ => {
                 cx.emit_err(session_diagnostics::UnknownMetaItem {
                     span: param_span,
@@ -310,11 +310,10 @@ pub(crate) fn parse_unstability(
             return None;
         };
 
-        let (word, args) = param.word_or_empty();
-        match word.name {
-            sym::feature => insert_value_into_option_or_error(cx, &param, &mut feature)?,
-            sym::reason => insert_value_into_option_or_error(cx, &param, &mut reason)?,
-            sym::issue => {
+        match param.path_without_args().word_sym() {
+            Some(sym::feature) => insert_value_into_option_or_error(cx, &param, &mut feature)?,
+            Some(sym::reason) => insert_value_into_option_or_error(cx, &param, &mut reason)?,
+            Some(sym::issue) => {
                 insert_value_into_option_or_error(cx, &param, &mut issue)?;
 
                 // These unwraps are safe because `insert_value_into_option_or_error` ensures the meta item
@@ -328,7 +327,7 @@ pub(crate) fn parse_unstability(
                                 session_diagnostics::InvalidIssueString {
                                     span: param.span(),
                                     cause: session_diagnostics::InvalidIssueStringCause::from_int_error_kind(
-                                        args.name_value().unwrap().value_span,
+                                        param.args().name_value().unwrap().value_span,
                                         err.kind(),
                                     ),
                                 },
@@ -338,13 +337,15 @@ pub(crate) fn parse_unstability(
                     },
                 };
             }
-            sym::soft => {
-                if !args.no_args() {
+            Some(sym::soft) => {
+                if !param.args().no_args() {
                     cx.emit_err(session_diagnostics::SoftNoArgs { span: param.span() });
                 }
                 is_soft = true;
             }
-            sym::implied_by => insert_value_into_option_or_error(cx, &param, &mut implied_by)?,
+            Some(sym::implied_by) => {
+                insert_value_into_option_or_error(cx, &param, &mut implied_by)?
+            }
             _ => {
                 cx.emit_err(session_diagnostics::UnknownMetaItem {
                     span: param.span(),
diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs
index 40aa39711d3..077d953cfa3 100644
--- a/compiler/rustc_attr_parsing/src/parser.rs
+++ b/compiler/rustc_attr_parsing/src/parser.rs
@@ -78,8 +78,8 @@ impl<'a> PathParser<'a> {
         (self.len() == 1).then(|| **self.segments().next().as_ref().unwrap())
     }
 
-    pub fn word_or_empty(&self) -> Ident {
-        self.word().unwrap_or_else(Ident::empty)
+    pub fn word_sym(&self) -> Option<Symbol> {
+        self.word().map(|ident| ident.name)
     }
 
     /// Asserts that this MetaItem is some specific word.
@@ -284,11 +284,6 @@ impl<'a> MetaItemParser<'a> {
         Some(self.word()?.0)
     }
 
-    /// Like [`word`](Self::word), but returns an empty symbol instead of None
-    pub fn word_or_empty_without_args(&self) -> Ident {
-        self.word_or_empty().0
-    }
-
     /// Asserts that this MetaItem starts with a word, or single segment path.
     ///
     /// Some examples:
@@ -300,12 +295,6 @@ impl<'a> MetaItemParser<'a> {
         Some((path.word()?, args))
     }
 
-    /// Like [`word`](Self::word), but returns an empty symbol instead of None
-    pub fn word_or_empty(&self) -> (Ident, &ArgParser<'a>) {
-        let (path, args) = self.deconstruct();
-        (path.word().unwrap_or(Ident::empty()), args)
-    }
-
     /// Asserts that this MetaItem starts with some specific word.
     ///
     /// See [`word`](Self::word) for examples of what a word is.
diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs
index 9d34b807ac2..2c434175b4b 100644
--- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs
+++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs
@@ -204,7 +204,7 @@ pub(crate) struct InvalidReprHintNoParen {
     #[primary_span]
     pub span: Span,
 
-    pub name: String,
+    pub name: Symbol,
 }
 
 #[derive(Diagnostic)]
@@ -213,7 +213,7 @@ pub(crate) struct InvalidReprHintNoValue {
     #[primary_span]
     pub span: Span,
 
-    pub name: String,
+    pub name: Symbol,
 }
 
 /// Error code: E0565
@@ -295,21 +295,21 @@ pub(crate) struct IncorrectReprFormatExpectInteger {
 
 #[derive(Diagnostic)]
 #[diag(attr_parsing_incorrect_repr_format_generic, code = E0693)]
-pub(crate) struct IncorrectReprFormatGeneric<'a> {
+pub(crate) struct IncorrectReprFormatGeneric {
     #[primary_span]
     pub span: Span,
 
-    pub repr_arg: &'a str,
+    pub repr_arg: Symbol,
 
     #[subdiagnostic]
-    pub cause: Option<IncorrectReprFormatGenericCause<'a>>,
+    pub cause: Option<IncorrectReprFormatGenericCause>,
 }
 
 #[derive(Subdiagnostic)]
-pub(crate) enum IncorrectReprFormatGenericCause<'a> {
+pub(crate) enum IncorrectReprFormatGenericCause {
     #[suggestion(
         attr_parsing_suggestion,
-        code = "{name}({int})",
+        code = "{name}({value})",
         applicability = "machine-applicable"
     )]
     Int {
@@ -317,15 +317,15 @@ pub(crate) enum IncorrectReprFormatGenericCause<'a> {
         span: Span,
 
         #[skip_arg]
-        name: &'a str,
+        name: Symbol,
 
         #[skip_arg]
-        int: u128,
+        value: u128,
     },
 
     #[suggestion(
         attr_parsing_suggestion,
-        code = "{name}({symbol})",
+        code = "{name}({value})",
         applicability = "machine-applicable"
     )]
     Symbol {
@@ -333,20 +333,20 @@ pub(crate) enum IncorrectReprFormatGenericCause<'a> {
         span: Span,
 
         #[skip_arg]
-        name: &'a str,
+        name: Symbol,
 
         #[skip_arg]
-        symbol: Symbol,
+        value: Symbol,
     },
 }
 
-impl<'a> IncorrectReprFormatGenericCause<'a> {
-    pub(crate) fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option<Self> {
-        match kind {
-            ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
-                Some(Self::Int { span, name, int: int.get() })
+impl IncorrectReprFormatGenericCause {
+    pub(crate) fn from_lit_kind(span: Span, kind: &ast::LitKind, name: Symbol) -> Option<Self> {
+        match *kind {
+            ast::LitKind::Int(value, ast::LitIntType::Unsuffixed) => {
+                Some(Self::Int { span, name, value: value.get() })
             }
-            ast::LitKind::Str(symbol, _) => Some(Self::Symbol { span, name, symbol: *symbol }),
+            ast::LitKind::Str(value, _) => Some(Self::Symbol { span, name, value }),
             _ => None,
         }
     }
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 0f8acadb978..3b7d31b1b13 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -2954,12 +2954,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
             }
         }
 
-        let name = if borrow_span.in_external_macro(self.infcx.tcx.sess.source_map()) {
-            // Don't name local variables in external macros.
-            "value".to_string()
-        } else {
-            format!("`{name}`")
-        };
+        let name = format!("`{name}`");
 
         let mut err = self.path_does_not_live_long_enough(borrow_span, &name);
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index f9f63ae92a8..5e3f3ffa2ea 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -317,6 +317,14 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         opt: DescribePlaceOpt,
     ) -> Option<String> {
         let local = place.local;
+        if self.body.local_decls[local]
+            .source_info
+            .span
+            .in_external_macro(self.infcx.tcx.sess.source_map())
+        {
+            return None;
+        }
+
         let mut autoderef_index = None;
         let mut buf = String::new();
         let mut ok = self.append_local_to_string(local, &mut buf);
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 44af1b76539..3e075d420a3 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -47,7 +47,7 @@ use rustc_mir_dataflow::impls::{
 use rustc_mir_dataflow::move_paths::{
     InitIndex, InitLocation, LookupResult, MoveData, MovePathIndex,
 };
-use rustc_mir_dataflow::{Analysis, EntryStates, Results, ResultsVisitor, visit_results};
+use rustc_mir_dataflow::{Analysis, Results, ResultsVisitor, visit_results};
 use rustc_session::lint::builtin::{TAIL_EXPR_DROP_ORDER, UNUSED_MUT};
 use rustc_span::{ErrorGuaranteed, Span, Symbol};
 use smallvec::SmallVec;
@@ -127,6 +127,14 @@ fn mir_borrowck(
         Ok(tcx.arena.alloc(opaque_types))
     } else {
         let mut root_cx = BorrowCheckRootCtxt::new(tcx, def);
+        // We need to manually borrowck all nested bodies from the HIR as
+        // we do not generate MIR for dead code. Not doing so causes us to
+        // never check closures in dead code.
+        let nested_bodies = tcx.nested_bodies_within(def);
+        for def_id in nested_bodies {
+            root_cx.get_or_insert_nested(def_id);
+        }
+
         let PropagatedBorrowCheckResults { closure_requirements, used_mut_upvars } =
             do_mir_borrowck(&mut root_cx, def, None).0;
         debug_assert!(closure_requirements.is_none());
@@ -461,11 +469,13 @@ fn do_mir_borrowck<'tcx>(
     // Compute and report region errors, if any.
     mbcx.report_region_errors(nll_errors);
 
-    let mut flow_results = get_flow_results(tcx, body, &move_data, &borrow_set, &regioncx);
+    let (mut flow_analysis, flow_entry_states) =
+        get_flow_results(tcx, body, &move_data, &borrow_set, &regioncx);
     visit_results(
         body,
         traversal::reverse_postorder(body).map(|(bb, _)| bb),
-        &mut flow_results,
+        &mut flow_analysis,
+        &flow_entry_states,
         &mut mbcx,
     );
 
@@ -525,7 +535,7 @@ fn get_flow_results<'a, 'tcx>(
     move_data: &'a MoveData<'tcx>,
     borrow_set: &'a BorrowSet<'tcx>,
     regioncx: &RegionInferenceContext<'tcx>,
-) -> Results<'tcx, Borrowck<'a, 'tcx>> {
+) -> (Borrowck<'a, 'tcx>, Results<BorrowckDomain>) {
     // We compute these three analyses individually, but them combine them into
     // a single results so that `mbcx` can visit them all together.
     let borrows = Borrows::new(tcx, body, regioncx, borrow_set).iterate_to_fixpoint(
@@ -550,14 +560,14 @@ fn get_flow_results<'a, 'tcx>(
         ever_inits: ever_inits.analysis,
     };
 
-    assert_eq!(borrows.entry_states.len(), uninits.entry_states.len());
-    assert_eq!(borrows.entry_states.len(), ever_inits.entry_states.len());
-    let entry_states: EntryStates<'_, Borrowck<'_, '_>> =
-        itertools::izip!(borrows.entry_states, uninits.entry_states, ever_inits.entry_states)
+    assert_eq!(borrows.results.len(), uninits.results.len());
+    assert_eq!(borrows.results.len(), ever_inits.results.len());
+    let results: Results<_> =
+        itertools::izip!(borrows.results, uninits.results, ever_inits.results)
             .map(|(borrows, uninits, ever_inits)| BorrowckDomain { borrows, uninits, ever_inits })
             .collect();
 
-    Results { analysis, entry_states }
+    (analysis, results)
 }
 
 pub(crate) struct BorrowckInferCtxt<'tcx> {
@@ -705,7 +715,7 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
 impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a, '_, 'tcx> {
     fn visit_after_early_statement_effect(
         &mut self,
-        _results: &mut Results<'tcx, Borrowck<'a, 'tcx>>,
+        _analysis: &mut Borrowck<'a, 'tcx>,
         state: &BorrowckDomain,
         stmt: &Statement<'tcx>,
         location: Location,
@@ -781,7 +791,7 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a,
 
     fn visit_after_early_terminator_effect(
         &mut self,
-        _results: &mut Results<'tcx, Borrowck<'a, 'tcx>>,
+        _analysis: &mut Borrowck<'a, 'tcx>,
         state: &BorrowckDomain,
         term: &Terminator<'tcx>,
         loc: Location,
@@ -901,7 +911,7 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a,
 
     fn visit_after_primary_terminator_effect(
         &mut self,
-        _results: &mut Results<'tcx, Borrowck<'a, 'tcx>>,
+        _analysis: &mut Borrowck<'a, 'tcx>,
         state: &BorrowckDomain,
         term: &Terminator<'tcx>,
         loc: Location,
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 550c57338d3..25cbd579ea1 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -267,13 +267,13 @@ impl<'tcx> InferCtxt<'tcx> {
             return Ty::new_error(self.tcx, e);
         }
 
-        if let Err(guar) = check_opaque_type_parameter_valid(
+        if let Err(err) = check_opaque_type_parameter_valid(
             self,
             opaque_type_key,
             instantiated_ty.span,
             DefiningScopeKind::MirBorrowck,
         ) {
-            return Ty::new_error(self.tcx, guar);
+            return Ty::new_error(self.tcx, err.report(self));
         }
 
         let definition_ty = instantiated_ty
diff --git a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs
index b2ed8a35827..8e04791461b 100644
--- a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs
+++ b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs
@@ -7,6 +7,8 @@ use rustc_middle::ty::RegionVid;
 
 use crate::RegionInferenceContext;
 use crate::constraints::ConstraintSccIndex;
+use crate::region_infer::ConstraintSccs;
+use crate::universal_regions::UniversalRegions;
 
 pub(crate) struct ReverseSccGraph {
     graph: VecGraph<ConstraintSccIndex>,
@@ -19,6 +21,29 @@ pub(crate) struct ReverseSccGraph {
 }
 
 impl ReverseSccGraph {
+    pub(super) fn compute(
+        constraint_sccs: &ConstraintSccs,
+        universal_regions: &UniversalRegions<'_>,
+    ) -> Self {
+        let graph = constraint_sccs.reverse();
+        let mut paired_scc_regions = universal_regions
+            .universal_regions_iter()
+            .map(|region| (constraint_sccs.scc(region), region))
+            .collect::<Vec<_>>();
+        paired_scc_regions.sort();
+        let universal_regions = paired_scc_regions.iter().map(|&(_, region)| region).collect();
+
+        let mut scc_regions = FxIndexMap::default();
+        let mut start = 0;
+        for chunk in paired_scc_regions.chunk_by(|&(scc1, _), &(scc2, _)| scc1 == scc2) {
+            let (scc, _) = chunk[0];
+
+            scc_regions.insert(scc, start..start + chunk.len());
+            start += chunk.len();
+        }
+        ReverseSccGraph { graph, scc_regions, universal_regions }
+    }
+
     /// Find all universal regions that are required to outlive the given SCC.
     pub(super) fn upper_bounds(&self, scc0: ConstraintSccIndex) -> impl Iterator<Item = RegionVid> {
         let mut duplicates = FxIndexSet::default();
@@ -40,23 +65,7 @@ impl RegionInferenceContext<'_> {
             return;
         }
 
-        let graph = self.constraint_sccs.reverse();
-        let mut paired_scc_regions = self
-            .universal_regions()
-            .universal_regions_iter()
-            .map(|region| (self.constraint_sccs.scc(region), region))
-            .collect::<Vec<_>>();
-        paired_scc_regions.sort();
-        let universal_regions = paired_scc_regions.iter().map(|&(_, region)| region).collect();
-
-        let mut scc_regions = FxIndexMap::default();
-        let mut start = 0;
-        for chunk in paired_scc_regions.chunk_by(|&(scc1, _), &(scc2, _)| scc1 == scc2) {
-            let (scc, _) = chunk[0];
-            scc_regions.insert(scc, start..start + chunk.len());
-            start += chunk.len();
-        }
-
-        self.rev_scc_graph = Some(ReverseSccGraph { graph, scc_regions, universal_regions });
+        self.rev_scc_graph =
+            Some(ReverseSccGraph::compute(&self.constraint_sccs, self.universal_regions()));
     }
 }
diff --git a/compiler/rustc_borrowck/src/root_cx.rs b/compiler/rustc_borrowck/src/root_cx.rs
index 13daa5c7221..66b526fa02a 100644
--- a/compiler/rustc_borrowck/src/root_cx.rs
+++ b/compiler/rustc_borrowck/src/root_cx.rs
@@ -62,7 +62,10 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
         self.tainted_by_errors = Some(guar);
     }
 
-    fn get_or_insert_nested(&mut self, def_id: LocalDefId) -> &PropagatedBorrowCheckResults<'tcx> {
+    pub(super) fn get_or_insert_nested(
+        &mut self,
+        def_id: LocalDefId,
+    ) -> &PropagatedBorrowCheckResults<'tcx> {
         debug_assert_eq!(
             self.tcx.typeck_root_def_id(def_id.to_def_id()),
             self.root_def_id.to_def_id()
diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
index 536a27763d2..92732aba29b 100644
--- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
+++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
@@ -41,8 +41,8 @@ type NormalizedInputsAndOutput<'tcx> = Vec<Ty<'tcx>>;
 
 pub(crate) struct CreateResult<'tcx> {
     pub(crate) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
-    pub(crate) region_bound_pairs: RegionBoundPairs<'tcx>,
-    pub(crate) known_type_outlives_obligations: Vec<ty::PolyTypeOutlivesPredicate<'tcx>>,
+    pub(crate) region_bound_pairs: Frozen<RegionBoundPairs<'tcx>>,
+    pub(crate) known_type_outlives_obligations: Frozen<Vec<ty::PolyTypeOutlivesPredicate<'tcx>>>,
     pub(crate) normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>,
 }
 
@@ -333,8 +333,8 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
                 outlives: self.outlives.freeze(),
                 inverse_outlives: self.inverse_outlives.freeze(),
             }),
-            known_type_outlives_obligations,
-            region_bound_pairs: self.region_bound_pairs,
+            known_type_outlives_obligations: Frozen::freeze(known_type_outlives_obligations),
+            region_bound_pairs: Frozen::freeze(self.region_bound_pairs),
             normalized_inputs_and_output,
         }
     }
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 99a544279b9..8c512257120 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -151,8 +151,8 @@ pub(crate) fn type_check<'a, 'tcx>(
         body,
         promoted,
         user_type_annotations: &body.user_type_annotations,
-        region_bound_pairs,
-        known_type_outlives_obligations,
+        region_bound_pairs: &region_bound_pairs,
+        known_type_outlives_obligations: &known_type_outlives_obligations,
         reported_errors: Default::default(),
         universal_regions: &universal_region_relations.universal_regions,
         location_table,
@@ -216,8 +216,8 @@ struct TypeChecker<'a, 'tcx> {
     /// User type annotations are shared between the main MIR and the MIR of
     /// all of the promoted items.
     user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>,
-    region_bound_pairs: RegionBoundPairs<'tcx>,
-    known_type_outlives_obligations: Vec<ty::PolyTypeOutlivesPredicate<'tcx>>,
+    region_bound_pairs: &'a RegionBoundPairs<'tcx>,
+    known_type_outlives_obligations: &'a [ty::PolyTypeOutlivesPredicate<'tcx>],
     reported_errors: FxIndexSet<(Ty<'tcx>, Span)>,
     universal_regions: &'a UniversalRegions<'tcx>,
     location_table: &'a PoloniusLocationTable,
@@ -412,9 +412,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         constraint_conversion::ConstraintConversion::new(
             self.infcx,
             self.universal_regions,
-            &self.region_bound_pairs,
+            self.region_bound_pairs,
             self.infcx.param_env,
-            &self.known_type_outlives_obligations,
+            self.known_type_outlives_obligations,
             locations,
             locations.span(self.body),
             category,
@@ -2506,9 +2506,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             constraint_conversion::ConstraintConversion::new(
                 self.infcx,
                 self.universal_regions,
-                &self.region_bound_pairs,
+                self.region_bound_pairs,
                 self.infcx.param_env,
-                &self.known_type_outlives_obligations,
+                self.known_type_outlives_obligations,
                 locations,
                 self.body.span,             // irrelevant; will be overridden.
                 ConstraintCategory::Boring, // same as above.
diff --git a/compiler/rustc_borrowck/src/type_check/opaque_types.rs b/compiler/rustc_borrowck/src/type_check/opaque_types.rs
index d41cbf757d7..341c50c37f6 100644
--- a/compiler/rustc_borrowck/src/type_check/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/type_check/opaque_types.rs
@@ -266,10 +266,6 @@ impl<'tcx, OP> TypeVisitor<TyCtxt<'tcx>> for ConstrainOpaqueTypeRegionVisitor<'t
 where
     OP: FnMut(ty::Region<'tcx>),
 {
-    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
-        t.super_visit_with(self);
-    }
-
     fn visit_region(&mut self, r: ty::Region<'tcx>) {
         match r.kind() {
             // ignore bound regions, keep visiting
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 12654001a1e..39f9d5f9005 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -1,3 +1,5 @@
+use std::ops::Range;
+
 use parse::Position::ArgumentNamed;
 use rustc_ast::ptr::P;
 use rustc_ast::tokenstream::TokenStream;
@@ -335,7 +337,7 @@ fn make_format_args(
         return ExpandResult::Ready(Err(guar));
     }
 
-    let to_span = |inner_span: parse::InnerSpan| {
+    let to_span = |inner_span: Range<usize>| {
         is_source_literal.then(|| {
             fmt_span.from_inner(InnerSpan { start: inner_span.start, end: inner_span.end })
         })
@@ -407,7 +409,7 @@ fn make_format_args(
     let mut placeholder_index = 0;
 
     for piece in &pieces {
-        match *piece {
+        match piece.clone() {
             parse::Piece::Lit(s) => {
                 unfinished_literal.push_str(s);
             }
@@ -417,7 +419,8 @@ fn make_format_args(
                     unfinished_literal.clear();
                 }
 
-                let span = parser.arg_places.get(placeholder_index).and_then(|&s| to_span(s));
+                let span =
+                    parser.arg_places.get(placeholder_index).and_then(|s| to_span(s.clone()));
                 placeholder_index += 1;
 
                 let position_span = to_span(position_span);
@@ -609,7 +612,7 @@ fn make_format_args(
 fn invalid_placeholder_type_error(
     ecx: &ExtCtxt<'_>,
     ty: &str,
-    ty_span: Option<parse::InnerSpan>,
+    ty_span: Option<Range<usize>>,
     fmt_span: Span,
 ) {
     let sp = ty_span.map(|sp| fmt_span.from_inner(InnerSpan::new(sp.start, sp.end)));
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index d3f47ad7263..e866b896255 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -1282,7 +1282,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                     intrinsic.name,
                 );
             }
-            return Err(Instance::new(instance.def_id(), instance.args));
+            return Err(Instance::new_raw(instance.def_id(), instance.args));
         }
     }
 
diff --git a/compiler/rustc_codegen_gcc/src/back/lto.rs b/compiler/rustc_codegen_gcc/src/back/lto.rs
index e5221c7da31..faeb2643ecb 100644
--- a/compiler/rustc_codegen_gcc/src/back/lto.rs
+++ b/compiler/rustc_codegen_gcc/src/back/lto.rs
@@ -44,7 +44,11 @@ use crate::{GccCodegenBackend, GccContext, SyncContext, to_gcc_opt_level};
 
 pub fn crate_type_allows_lto(crate_type: CrateType) -> bool {
     match crate_type {
-        CrateType::Executable | CrateType::Dylib | CrateType::Staticlib | CrateType::Cdylib => true,
+        CrateType::Executable
+        | CrateType::Dylib
+        | CrateType::Staticlib
+        | CrateType::Cdylib
+        | CrateType::Sdylib => true,
         CrateType::Rlib | CrateType::ProcMacro => false,
     }
 }
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
index d22f4229e23..2ed5ec4381e 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -399,7 +399,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
             }
 
             // Fall back to default body
-            _ => return Err(Instance::new(instance.def_id(), instance.args)),
+            _ => return Err(Instance::new_raw(instance.def_id(), instance.args)),
         };
 
         if !fn_abi.ret.is_ignore() {
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index 39b3a23e0b1..cb329323f5d 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -42,7 +42,8 @@ fn crate_type_allows_lto(crate_type: CrateType) -> bool {
         | CrateType::Dylib
         | CrateType::Staticlib
         | CrateType::Cdylib
-        | CrateType::ProcMacro => true,
+        | CrateType::ProcMacro
+        | CrateType::Sdylib => true,
         CrateType::Rlib => false,
     }
 }
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index bf81eb648f8..cbac55c7153 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -364,7 +364,12 @@ impl<'ll> CodegenCx<'ll, '_> {
 
         if !def_id.is_local() {
             let needs_dll_storage_attr = self.use_dll_storage_attrs
-                && !self.tcx.is_foreign_item(def_id)
+                // If the symbol is a foreign item, then don't automatically apply DLLImport, as
+                // we'll rely on the #[link] attribute instead. BUT, if this is an internal symbol
+                // then it may be generated by the compiler in some crate, so we do need to apply
+                // DLLImport when linking with the MSVC linker.
+                && (!self.tcx.is_foreign_item(def_id)
+                    || (self.sess().target.is_like_msvc && fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)))
                 // Local definitions can never be imported, so we must not apply
                 // the DLLImport annotation.
                 && !dso_local
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs
index 68f60f169b5..fe3a7a1580b 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs
@@ -157,7 +157,7 @@ fn make_dummy_instance<'tcx>(tcx: TyCtxt<'tcx>, local_def_id: LocalDefId) -> ty:
     let def_id = local_def_id.to_def_id();
 
     // Make a dummy instance that fills in all generics with placeholders.
-    ty::Instance::new(
+    ty::Instance::new_raw(
         def_id,
         ty::GenericArgs::for_item(tcx, def_id, |param, _| {
             if let ty::GenericParamDefKind::Lifetime = param.kind {
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
index 4ffe551df09..8f0948b8183 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
@@ -95,7 +95,11 @@ pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
     // in the `.debug_gdb_scripts` section. For that reason, we make sure that the
     // section is only emitted for leaf crates.
     let embed_visualizers = cx.tcx.crate_types().iter().any(|&crate_type| match crate_type {
-        CrateType::Executable | CrateType::Dylib | CrateType::Cdylib | CrateType::Staticlib => {
+        CrateType::Executable
+        | CrateType::Dylib
+        | CrateType::Cdylib
+        | CrateType::Staticlib
+        | CrateType::Sdylib => {
             // These are crate types for which we will embed pretty printers since they
             // are treated as leaf crates.
             true
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index ffeab59b05c..bfaad8f2f1e 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -613,7 +613,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
             _ => {
                 debug!("unknown intrinsic '{}' -- falling back to default body", name);
                 // Call the fallback body instead of generating the intrinsic code
-                return Err(ty::Instance::new(instance.def_id(), instance.args));
+                return Err(ty::Instance::new_raw(instance.def_id(), instance.args));
             }
         };
 
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 507cbf20d89..8f57f0983ab 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -19,6 +19,7 @@ use rustc_session::config::{PrintKind, PrintRequest};
 use rustc_span::Symbol;
 use rustc_target::spec::{MergeFunctions, PanicStrategy, SmallDataThresholdSupport};
 use rustc_target::target_features::{RUSTC_SPECIAL_FEATURES, RUSTC_SPECIFIC_FEATURES};
+use smallvec::{SmallVec, smallvec};
 
 use crate::back::write::create_informational_target_machine;
 use crate::errors::{
@@ -180,27 +181,27 @@ impl<'a> TargetFeatureFoldStrength<'a> {
 
 pub(crate) struct LLVMFeature<'a> {
     llvm_feature_name: &'a str,
-    dependency: Option<TargetFeatureFoldStrength<'a>>,
+    dependencies: SmallVec<[TargetFeatureFoldStrength<'a>; 1]>,
 }
 
 impl<'a> LLVMFeature<'a> {
     fn new(llvm_feature_name: &'a str) -> Self {
-        Self { llvm_feature_name, dependency: None }
+        Self { llvm_feature_name, dependencies: SmallVec::new() }
     }
 
-    fn with_dependency(
+    fn with_dependencies(
         llvm_feature_name: &'a str,
-        dependency: TargetFeatureFoldStrength<'a>,
+        dependencies: SmallVec<[TargetFeatureFoldStrength<'a>; 1]>,
     ) -> Self {
-        Self { llvm_feature_name, dependency: Some(dependency) }
+        Self { llvm_feature_name, dependencies }
     }
 
-    fn contains(&self, feat: &str) -> bool {
+    fn contains(&'a self, feat: &str) -> bool {
         self.iter().any(|dep| dep == feat)
     }
 
     fn iter(&'a self) -> impl Iterator<Item = &'a str> {
-        let dependencies = self.dependency.iter().map(|feat| feat.as_str());
+        let dependencies = self.dependencies.iter().map(|feat| feat.as_str());
         std::iter::once(self.llvm_feature_name).chain(dependencies)
     }
 }
@@ -210,7 +211,7 @@ impl<'a> IntoIterator for LLVMFeature<'a> {
     type IntoIter = impl Iterator<Item = &'a str>;
 
     fn into_iter(self) -> Self::IntoIter {
-        let dependencies = self.dependency.into_iter().map(|feat| feat.as_str());
+        let dependencies = self.dependencies.into_iter().map(|feat| feat.as_str());
         std::iter::once(self.llvm_feature_name).chain(dependencies)
     }
 }
@@ -240,9 +241,9 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
         &*sess.target.arch
     };
     match (arch, s) {
-        ("x86", "sse4.2") => Some(LLVMFeature::with_dependency(
+        ("x86", "sse4.2") => Some(LLVMFeature::with_dependencies(
             "sse4.2",
-            TargetFeatureFoldStrength::EnableOnly("crc32"),
+            smallvec![TargetFeatureFoldStrength::EnableOnly("crc32")],
         )),
         ("x86", "pclmulqdq") => Some(LLVMFeature::new("pclmul")),
         ("x86", "rdrand") => Some(LLVMFeature::new("rdrnd")),
@@ -262,9 +263,10 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
         ("aarch64", "sme-b16b16") if get_version().0 < 20 => Some(LLVMFeature::new("b16b16")),
         ("aarch64", "flagm2") => Some(LLVMFeature::new("altnzcv")),
         // Rust ties fp and neon together.
-        ("aarch64", "neon") => {
-            Some(LLVMFeature::with_dependency("neon", TargetFeatureFoldStrength::Both("fp-armv8")))
-        }
+        ("aarch64", "neon") => Some(LLVMFeature::with_dependencies(
+            "neon",
+            smallvec![TargetFeatureFoldStrength::Both("fp-armv8")],
+        )),
         // In LLVM neon implicitly enables fp, but we manually enable
         // neon when a feature only implicitly enables fp
         ("aarch64", "fhm") => Some(LLVMFeature::new("fp16fml")),
@@ -281,9 +283,10 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
         // Filter out features that are not supported by the current LLVM version
         ("riscv32" | "riscv64", "zacas") if get_version().0 < 20 => None,
         // Enable the evex512 target feature if an avx512 target feature is enabled.
-        ("x86", s) if s.starts_with("avx512") => {
-            Some(LLVMFeature::with_dependency(s, TargetFeatureFoldStrength::EnableOnly("evex512")))
-        }
+        ("x86", s) if s.starts_with("avx512") => Some(LLVMFeature::with_dependencies(
+            s,
+            smallvec![TargetFeatureFoldStrength::EnableOnly("evex512")],
+        )),
         // Support for `wide-arithmetic` will first land in LLVM 20 as part of
         // llvm/llvm-project#111598
         ("wasm32" | "wasm64", "wide-arithmetic") if get_version() < (20, 0, 0) => None,
@@ -301,6 +304,21 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
             None
         }
         ("x86", "movrs") if get_version().0 < 20 => None,
+        ("x86", "avx10.1") => Some(LLVMFeature::new("avx10.1-512")),
+        ("x86", "avx10.2") if get_version().0 < 20 => None,
+        ("x86", "avx10.2") if get_version().0 >= 20 => Some(LLVMFeature::new("avx10.2-512")),
+        ("x86", "apxf") => Some(LLVMFeature::with_dependencies(
+            "egpr",
+            smallvec![
+                TargetFeatureFoldStrength::Both("push2pop2"),
+                TargetFeatureFoldStrength::Both("ppx"),
+                TargetFeatureFoldStrength::Both("ndd"),
+                TargetFeatureFoldStrength::Both("ccmp"),
+                TargetFeatureFoldStrength::Both("cf"),
+                TargetFeatureFoldStrength::Both("nf"),
+                TargetFeatureFoldStrength::Both("zu"),
+            ],
+        )),
         (_, s) => Some(LLVMFeature::new(s)),
     }
 }
@@ -850,7 +868,7 @@ pub(crate) fn global_llvm_features(
                         "{}{}",
                         enable_disable, llvm_feature.llvm_feature_name
                     ))
-                    .chain(llvm_feature.dependency.into_iter().filter_map(
+                    .chain(llvm_feature.dependencies.into_iter().filter_map(
                         move |feat| match (enable, feat) {
                             (_, TargetFeatureFoldStrength::Both(f))
                             | (true, TargetFeatureFoldStrength::EnableOnly(f)) => {
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 323538969d7..159c17b0af7 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1053,9 +1053,10 @@ fn link_natively(
                 strip_with_external_utility(sess, stripcmd, out_filename, &["--strip-debug"])
             }
             // Per the manpage, `-x` is the maximum safe strip level for dynamic libraries. (#93988)
-            (Strip::Symbols, CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro) => {
-                strip_with_external_utility(sess, stripcmd, out_filename, &["-x"])
-            }
+            (
+                Strip::Symbols,
+                CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro | CrateType::Sdylib,
+            ) => strip_with_external_utility(sess, stripcmd, out_filename, &["-x"]),
             (Strip::Symbols, _) => {
                 strip_with_external_utility(sess, stripcmd, out_filename, &["--strip-all"])
             }
@@ -1243,8 +1244,10 @@ fn add_sanitizer_libraries(
     // which should be linked to both executables and dynamic libraries.
     // Everywhere else the runtimes are currently distributed as static
     // libraries which should be linked to executables only.
-    if matches!(crate_type, CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro)
-        && !(sess.target.is_like_darwin || sess.target.is_like_msvc)
+    if matches!(
+        crate_type,
+        CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro | CrateType::Sdylib
+    ) && !(sess.target.is_like_darwin || sess.target.is_like_msvc)
     {
         return;
     }
@@ -1938,6 +1941,7 @@ fn add_late_link_args(
     codegen_results: &CodegenResults,
 ) {
     let any_dynamic_crate = crate_type == CrateType::Dylib
+        || crate_type == CrateType::Sdylib
         || codegen_results.crate_info.dependency_formats.iter().any(|(ty, list)| {
             *ty == crate_type && list.iter().any(|&linkage| linkage == Linkage::Dynamic)
         });
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index a09eec5dd74..80ee8ea2228 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -337,7 +337,12 @@ pub(crate) trait Linker {
     fn debuginfo(&mut self, strip: Strip, natvis_debugger_visualizers: &[PathBuf]);
     fn no_crt_objects(&mut self);
     fn no_default_libraries(&mut self);
-    fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]);
+    fn export_symbols(
+        &mut self,
+        tmpdir: &Path,
+        crate_type: CrateType,
+        symbols: &[(String, SymbolExportKind)],
+    );
     fn subsystem(&mut self, subsystem: &str);
     fn linker_plugin_lto(&mut self);
     fn add_eh_frame_header(&mut self) {}
@@ -770,7 +775,12 @@ impl<'a> Linker for GccLinker<'a> {
         }
     }
 
-    fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]) {
+    fn export_symbols(
+        &mut self,
+        tmpdir: &Path,
+        crate_type: CrateType,
+        symbols: &[(String, SymbolExportKind)],
+    ) {
         // Symbol visibility in object files typically takes care of this.
         if crate_type == CrateType::Executable {
             let should_export_executable_symbols =
@@ -799,7 +809,7 @@ impl<'a> Linker for GccLinker<'a> {
             // Write a plain, newline-separated list of symbols
             let res: io::Result<()> = try {
                 let mut f = File::create_buffered(&path)?;
-                for sym in symbols {
+                for (sym, _) in symbols {
                     debug!("  _{sym}");
                     writeln!(f, "_{sym}")?;
                 }
@@ -814,9 +824,12 @@ impl<'a> Linker for GccLinker<'a> {
                 // .def file similar to MSVC one but without LIBRARY section
                 // because LD doesn't like when it's empty
                 writeln!(f, "EXPORTS")?;
-                for symbol in symbols {
+                for (symbol, kind) in symbols {
+                    let kind_marker = if *kind == SymbolExportKind::Data { " DATA" } else { "" };
                     debug!("  _{symbol}");
-                    writeln!(f, "  {symbol}")?;
+                    // Quote the name in case it's reserved by linker in some way
+                    // (this accounts for names with dots in particular).
+                    writeln!(f, "  \"{symbol}\"{kind_marker}")?;
                 }
             };
             if let Err(error) = res {
@@ -829,7 +842,7 @@ impl<'a> Linker for GccLinker<'a> {
                 writeln!(f, "{{")?;
                 if !symbols.is_empty() {
                     writeln!(f, "  global:")?;
-                    for sym in symbols {
+                    for (sym, _) in symbols {
                         debug!("    {sym};");
                         writeln!(f, "    {sym};")?;
                     }
@@ -1096,7 +1109,12 @@ impl<'a> Linker for MsvcLinker<'a> {
     // crates. Upstream rlibs may be linked statically to this dynamic library,
     // in which case they may continue to transitively be used and hence need
     // their symbols exported.
-    fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]) {
+    fn export_symbols(
+        &mut self,
+        tmpdir: &Path,
+        crate_type: CrateType,
+        symbols: &[(String, SymbolExportKind)],
+    ) {
         // Symbol visibility takes care of this typically
         if crate_type == CrateType::Executable {
             let should_export_executable_symbols =
@@ -1114,9 +1132,10 @@ impl<'a> Linker for MsvcLinker<'a> {
             // straight to exports.
             writeln!(f, "LIBRARY")?;
             writeln!(f, "EXPORTS")?;
-            for symbol in symbols {
+            for (symbol, kind) in symbols {
+                let kind_marker = if *kind == SymbolExportKind::Data { " DATA" } else { "" };
                 debug!("  _{symbol}");
-                writeln!(f, "  {symbol}")?;
+                writeln!(f, "  {symbol}{kind_marker}")?;
             }
         };
         if let Err(error) = res {
@@ -1257,14 +1276,19 @@ impl<'a> Linker for EmLinker<'a> {
         self.cc_arg("-nodefaultlibs");
     }
 
-    fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
+    fn export_symbols(
+        &mut self,
+        _tmpdir: &Path,
+        _crate_type: CrateType,
+        symbols: &[(String, SymbolExportKind)],
+    ) {
         debug!("EXPORTED SYMBOLS:");
 
         self.cc_arg("-s");
 
         let mut arg = OsString::from("EXPORTED_FUNCTIONS=");
         let encoded = serde_json::to_string(
-            &symbols.iter().map(|sym| "_".to_owned() + sym).collect::<Vec<_>>(),
+            &symbols.iter().map(|(sym, _)| "_".to_owned() + sym).collect::<Vec<_>>(),
         )
         .unwrap();
         debug!("{encoded}");
@@ -1426,8 +1450,13 @@ impl<'a> Linker for WasmLd<'a> {
 
     fn no_default_libraries(&mut self) {}
 
-    fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
-        for sym in symbols {
+    fn export_symbols(
+        &mut self,
+        _tmpdir: &Path,
+        _crate_type: CrateType,
+        symbols: &[(String, SymbolExportKind)],
+    ) {
+        for (sym, _) in symbols {
             self.link_args(&["--export", sym]);
         }
 
@@ -1561,7 +1590,7 @@ impl<'a> Linker for L4Bender<'a> {
         self.cc_arg("-nostdlib");
     }
 
-    fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[String]) {
+    fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[(String, SymbolExportKind)]) {
         // ToDo, not implemented, copy from GCC
         self.sess.dcx().emit_warn(errors::L4BenderExportingSymbolsUnimplemented);
     }
@@ -1718,12 +1747,17 @@ impl<'a> Linker for AixLinker<'a> {
 
     fn no_default_libraries(&mut self) {}
 
-    fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
+    fn export_symbols(
+        &mut self,
+        tmpdir: &Path,
+        _crate_type: CrateType,
+        symbols: &[(String, SymbolExportKind)],
+    ) {
         let path = tmpdir.join("list.exp");
         let res: io::Result<()> = try {
             let mut f = File::create_buffered(&path)?;
             // FIXME: use llvm-nm to generate export list.
-            for symbol in symbols {
+            for (symbol, _) in symbols {
                 debug!("  _{symbol}");
                 writeln!(f, "  {symbol}")?;
             }
@@ -1767,9 +1801,12 @@ fn for_each_exported_symbols_include_dep<'tcx>(
     }
 }
 
-pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
+pub(crate) fn exported_symbols(
+    tcx: TyCtxt<'_>,
+    crate_type: CrateType,
+) -> Vec<(String, SymbolExportKind)> {
     if let Some(ref exports) = tcx.sess.target.override_export_symbols {
-        return exports.iter().map(ToString::to_string).collect();
+        return exports.iter().map(|name| (name.to_string(), SymbolExportKind::Text)).collect();
     }
 
     if let CrateType::ProcMacro = crate_type {
@@ -1779,7 +1816,10 @@ pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<St
     }
 }
 
-fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
+fn exported_symbols_for_non_proc_macro(
+    tcx: TyCtxt<'_>,
+    crate_type: CrateType,
+) -> Vec<(String, SymbolExportKind)> {
     let mut symbols = Vec::new();
     let export_threshold = symbol_export::crates_export_threshold(&[crate_type]);
     for_each_exported_symbols_include_dep(tcx, crate_type, |symbol, info, cnum| {
@@ -1787,17 +1827,18 @@ fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -
         // from any cdylib. The latter doesn't work anyway as we use hidden visibility for
         // compiler-builtins. Most linkers silently ignore it, but ld64 gives a warning.
         if info.level.is_below_threshold(export_threshold) && !tcx.is_compiler_builtins(cnum) {
-            symbols.push(symbol_export::exporting_symbol_name_for_instance_in_crate(
-                tcx, symbol, cnum,
+            symbols.push((
+                symbol_export::exporting_symbol_name_for_instance_in_crate(tcx, symbol, cnum),
+                info.kind,
             ));
-            symbol_export::extend_exported_symbols(&mut symbols, tcx, symbol, cnum);
+            symbol_export::extend_exported_symbols(&mut symbols, tcx, symbol, info, cnum);
         }
     });
 
     symbols
 }
 
-fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<String> {
+fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<(String, SymbolExportKind)> {
     // `exported_symbols` will be empty when !should_codegen.
     if !tcx.sess.opts.output_types.should_codegen() {
         return Vec::new();
@@ -1807,7 +1848,10 @@ fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<String> {
     let proc_macro_decls_name = tcx.sess.generate_proc_macro_decls_symbol(stable_crate_id);
     let metadata_symbol_name = exported_symbols::metadata_symbol_name(tcx);
 
-    vec![proc_macro_decls_name, metadata_symbol_name]
+    vec![
+        (proc_macro_decls_name, SymbolExportKind::Text),
+        (metadata_symbol_name, SymbolExportKind::Text),
+    ]
 }
 
 pub(crate) fn linked_symbols(
@@ -1815,7 +1859,7 @@ pub(crate) fn linked_symbols(
     crate_type: CrateType,
 ) -> Vec<(String, SymbolExportKind)> {
     match crate_type {
-        CrateType::Executable | CrateType::Cdylib | CrateType::Dylib => (),
+        CrateType::Executable | CrateType::Cdylib | CrateType::Dylib | CrateType::Sdylib => (),
         CrateType::Staticlib | CrateType::ProcMacro | CrateType::Rlib => {
             return Vec::new();
         }
@@ -1829,7 +1873,9 @@ pub(crate) fn linked_symbols(
             || info.used
         {
             symbols.push((
-                symbol_export::linking_symbol_name_for_instance_in_crate(tcx, symbol, cnum),
+                symbol_export::linking_symbol_name_for_instance_in_crate(
+                    tcx, symbol, info.kind, cnum,
+                ),
                 info.kind,
             ));
         }
@@ -1904,7 +1950,13 @@ impl<'a> Linker for PtxLinker<'a> {
 
     fn ehcont_guard(&mut self) {}
 
-    fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, _symbols: &[String]) {}
+    fn export_symbols(
+        &mut self,
+        _tmpdir: &Path,
+        _crate_type: CrateType,
+        _symbols: &[(String, SymbolExportKind)],
+    ) {
+    }
 
     fn subsystem(&mut self, _subsystem: &str) {}
 
@@ -1973,10 +2025,15 @@ impl<'a> Linker for LlbcLinker<'a> {
 
     fn ehcont_guard(&mut self) {}
 
-    fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
+    fn export_symbols(
+        &mut self,
+        _tmpdir: &Path,
+        _crate_type: CrateType,
+        symbols: &[(String, SymbolExportKind)],
+    ) {
         match _crate_type {
             CrateType::Cdylib => {
-                for sym in symbols {
+                for (sym, _) in symbols {
                     self.link_args(&["--export-symbol", sym]);
                 }
             }
@@ -2050,11 +2107,16 @@ impl<'a> Linker for BpfLinker<'a> {
 
     fn ehcont_guard(&mut self) {}
 
-    fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
+    fn export_symbols(
+        &mut self,
+        tmpdir: &Path,
+        _crate_type: CrateType,
+        symbols: &[(String, SymbolExportKind)],
+    ) {
         let path = tmpdir.join("symbols");
         let res: io::Result<()> = try {
             let mut f = File::create_buffered(&path)?;
-            for sym in symbols {
+            for (sym, _) in symbols {
                 writeln!(f, "{sym}")?;
             }
         };
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index ebcccf1b97d..ec46c71b0e4 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -270,45 +270,61 @@ pub(super) fn elf_os_abi(sess: &Session) -> u8 {
 
 pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 {
     match architecture {
-        Architecture::Mips => {
-            let arch = match sess.target.options.cpu.as_ref() {
-                "mips1" => elf::EF_MIPS_ARCH_1,
-                "mips2" => elf::EF_MIPS_ARCH_2,
+        Architecture::Mips | Architecture::Mips64 | Architecture::Mips64_N32 => {
+            // "N32" indicates an "ILP32" data model on a 64-bit MIPS CPU
+            // like SPARC's "v8+", x86_64's "x32", or the watchOS "arm64_32".
+            let is_32bit = architecture == Architecture::Mips;
+            let mut e_flags = match sess.target.options.cpu.as_ref() {
+                "mips1" if is_32bit => elf::EF_MIPS_ARCH_1,
+                "mips2" if is_32bit => elf::EF_MIPS_ARCH_2,
                 "mips3" => elf::EF_MIPS_ARCH_3,
                 "mips4" => elf::EF_MIPS_ARCH_4,
                 "mips5" => elf::EF_MIPS_ARCH_5,
-                s if s.contains("r6") => elf::EF_MIPS_ARCH_32R6,
-                _ => elf::EF_MIPS_ARCH_32R2,
+                "mips32r2" if is_32bit => elf::EF_MIPS_ARCH_32R2,
+                "mips32r6" if is_32bit => elf::EF_MIPS_ARCH_32R6,
+                "mips64r2" if !is_32bit => elf::EF_MIPS_ARCH_64R2,
+                "mips64r6" if !is_32bit => elf::EF_MIPS_ARCH_64R6,
+                s if s.starts_with("mips32") && !is_32bit => {
+                    sess.dcx().fatal(format!("invalid CPU `{}` for 64-bit MIPS target", s))
+                }
+                s if s.starts_with("mips64") && is_32bit => {
+                    sess.dcx().fatal(format!("invalid CPU `{}` for 32-bit MIPS target", s))
+                }
+                _ if is_32bit => elf::EF_MIPS_ARCH_32R2,
+                _ => elf::EF_MIPS_ARCH_64R2,
             };
 
-            let mut e_flags = elf::EF_MIPS_CPIC | arch;
-
-            // If the ABI is explicitly given, use it or default to O32.
-            match sess.target.options.llvm_abiname.to_lowercase().as_str() {
-                "n32" => e_flags |= elf::EF_MIPS_ABI2,
-                "o32" => e_flags |= elf::EF_MIPS_ABI_O32,
-                _ => e_flags |= elf::EF_MIPS_ABI_O32,
+            // If the ABI is explicitly given, use it, or default to O32 on 32-bit MIPS,
+            // which is the only "true" 32-bit option that LLVM supports.
+            match sess.target.options.llvm_abiname.as_ref() {
+                "o32" if is_32bit => e_flags |= elf::EF_MIPS_ABI_O32,
+                "n32" if !is_32bit => e_flags |= elf::EF_MIPS_ABI2,
+                "n64" if !is_32bit => {}
+                "" if is_32bit => e_flags |= elf::EF_MIPS_ABI_O32,
+                "" => sess.dcx().fatal("LLVM ABI must be specifed for 64-bit MIPS targets"),
+                s if is_32bit => {
+                    sess.dcx().fatal(format!("invalid LLVM ABI `{}` for 32-bit MIPS target", s))
+                }
+                s => sess.dcx().fatal(format!("invalid LLVM ABI `{}` for 64-bit MIPS target", s)),
             };
 
             if sess.target.options.relocation_model != RelocModel::Static {
-                e_flags |= elf::EF_MIPS_PIC;
+                // PIC means position-independent code. CPIC means "calls PIC".
+                // CPIC was mutually exclusive with PIC according to
+                // the SVR4 MIPS ABI https://refspecs.linuxfoundation.org/elf/mipsabi.pdf
+                // and should have only appeared on static objects with dynamically calls.
+                // At some point someone (GCC?) decided to set CPIC even for PIC.
+                // Nowadays various things expect both set on the same object file
+                // and may even error if you mix CPIC and non-CPIC object files,
+                // despite that being the entire point of the CPIC ABI extension!
+                // As we are in Rome, we do as the Romans do.
+                e_flags |= elf::EF_MIPS_PIC | elf::EF_MIPS_CPIC;
             }
             if sess.target.options.cpu.contains("r6") {
                 e_flags |= elf::EF_MIPS_NAN2008;
             }
             e_flags
         }
-        Architecture::Mips64 => {
-            // copied from `mips64el-linux-gnuabi64-gcc foo.c -c`
-            let e_flags = elf::EF_MIPS_CPIC
-                | elf::EF_MIPS_PIC
-                | if sess.target.options.cpu.contains("r6") {
-                    elf::EF_MIPS_ARCH_64R6 | elf::EF_MIPS_NAN2008
-                } else {
-                    elf::EF_MIPS_ARCH_64R2
-                };
-            e_flags
-        }
         Architecture::Riscv32 | Architecture::Riscv64 => {
             // Source: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/079772828bd10933d34121117a222b4cc0ee2200/riscv-elf.adoc
             let mut e_flags: u32 = 0x0;
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index 50fb08b2868..06ba5b4f6a7 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -29,7 +29,7 @@ fn crate_export_threshold(crate_type: CrateType) -> SymbolExportLevel {
         CrateType::Executable | CrateType::Staticlib | CrateType::ProcMacro | CrateType::Cdylib => {
             SymbolExportLevel::C
         }
-        CrateType::Rlib | CrateType::Dylib => SymbolExportLevel::Rust,
+        CrateType::Rlib | CrateType::Dylib | CrateType::Sdylib => SymbolExportLevel::Rust,
     }
 }
 
@@ -45,7 +45,7 @@ pub fn crates_export_threshold(crate_types: &[CrateType]) -> SymbolExportLevel {
 }
 
 fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<SymbolExportInfo> {
-    if !tcx.sess.opts.output_types.should_codegen() {
+    if !tcx.sess.opts.output_types.should_codegen() && !tcx.is_sdylib_interface_build() {
         return Default::default();
     }
 
@@ -168,7 +168,7 @@ fn exported_symbols_provider_local<'tcx>(
     tcx: TyCtxt<'tcx>,
     _: LocalCrate,
 ) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
-    if !tcx.sess.opts.output_types.should_codegen() {
+    if !tcx.sess.opts.output_types.should_codegen() && !tcx.is_sdylib_interface_build() {
         return &[];
     }
 
@@ -612,7 +612,7 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>(
         ExportedSymbol::Generic(def_id, args) => {
             rustc_symbol_mangling::symbol_name_for_instance_in_crate(
                 tcx,
-                Instance::new(def_id, args),
+                Instance::new_raw(def_id, args),
                 instantiating_crate,
             )
         }
@@ -660,7 +660,7 @@ fn calling_convention_for_symbol<'tcx>(
             None
         }
         ExportedSymbol::NonGeneric(def_id) => Some(Instance::mono(tcx, def_id)),
-        ExportedSymbol::Generic(def_id, args) => Some(Instance::new(def_id, args)),
+        ExportedSymbol::Generic(def_id, args) => Some(Instance::new_raw(def_id, args)),
         // DropGlue always use the Rust calling convention and thus follow the target's default
         // symbol decoration scheme.
         ExportedSymbol::DropGlue(..) => None,
@@ -692,6 +692,7 @@ fn calling_convention_for_symbol<'tcx>(
 pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
     tcx: TyCtxt<'tcx>,
     symbol: ExportedSymbol<'tcx>,
+    export_kind: SymbolExportKind,
     instantiating_crate: CrateNum,
 ) -> String {
     let mut undecorated = symbol_name_for_instance_in_crate(tcx, symbol, instantiating_crate);
@@ -712,8 +713,9 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
     let prefix = match &target.arch[..] {
         "x86" => Some('_'),
         "x86_64" => None,
-        "arm64ec" => Some('#'),
-        // Only x86/64 use symbol decorations.
+        // Only functions are decorated for arm64ec.
+        "arm64ec" if export_kind == SymbolExportKind::Text => Some('#'),
+        // Only x86/64 and arm64ec use symbol decorations.
         _ => return undecorated,
     };
 
@@ -753,9 +755,10 @@ pub(crate) fn exporting_symbol_name_for_instance_in_crate<'tcx>(
 /// Add it to the symbols list for all kernel functions, so that it is exported in the linked
 /// object.
 pub(crate) fn extend_exported_symbols<'tcx>(
-    symbols: &mut Vec<String>,
+    symbols: &mut Vec<(String, SymbolExportKind)>,
     tcx: TyCtxt<'tcx>,
     symbol: ExportedSymbol<'tcx>,
+    info: SymbolExportInfo,
     instantiating_crate: CrateNum,
 ) {
     let (conv, _) = calling_convention_for_symbol(tcx, symbol);
@@ -767,7 +770,7 @@ pub(crate) fn extend_exported_symbols<'tcx>(
     let undecorated = symbol_name_for_instance_in_crate(tcx, symbol, instantiating_crate);
 
     // Add the symbol for the kernel descriptor (with .kd suffix)
-    symbols.push(format!("{undecorated}.kd"));
+    symbols.push((format!("{undecorated}.kd"), info.kind));
 }
 
 fn maybe_emutls_symbol_name<'tcx>(
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index f5480da2808..93cbd4cbb7c 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -12,9 +12,9 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
 use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
 use rustc_data_structures::sync::{IntoDynSyncSend, par_map};
 use rustc_data_structures::unord::UnordMap;
-use rustc_hir::ItemId;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::lang_items::LangItem;
+use rustc_hir::{ItemId, Target};
 use rustc_metadata::EncodedMetadata;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
 use rustc_middle::middle::debugger_visualizer::{DebuggerVisualizerFile, DebuggerVisualizerType};
@@ -457,7 +457,13 @@ where
                 rustc_hir::InlineAsmOperand::SymFn { expr } => {
                     let ty = cx.tcx().typeck(item_id.owner_id).expr_ty(expr);
                     let instance = match ty.kind() {
-                        &ty::FnDef(def_id, args) => Instance::new(def_id, args),
+                        &ty::FnDef(def_id, args) => Instance::expect_resolve(
+                            cx.tcx(),
+                            ty::TypingEnv::fully_monomorphized(),
+                            def_id,
+                            args,
+                            expr.span,
+                        ),
                         _ => span_bug!(*op_sp, "asm sym is not a function"),
                     };
 
@@ -1032,21 +1038,35 @@ impl CrateInfo {
         // by the compiler, but that's ok because all this stuff is unstable anyway.
         let target = &tcx.sess.target;
         if !are_upstream_rust_objects_already_included(tcx.sess) {
-            let missing_weak_lang_items: FxIndexSet<Symbol> = info
+            let add_prefix = match (target.is_like_windows, target.arch.as_ref()) {
+                (true, "x86") => |name: String, _: SymbolExportKind| format!("_{name}"),
+                (true, "arm64ec") => {
+                    // Only functions are decorated for arm64ec.
+                    |name: String, export_kind: SymbolExportKind| match export_kind {
+                        SymbolExportKind::Text => format!("#{name}"),
+                        _ => name,
+                    }
+                }
+                _ => |name: String, _: SymbolExportKind| name,
+            };
+            let missing_weak_lang_items: FxIndexSet<(Symbol, SymbolExportKind)> = info
                 .used_crates
                 .iter()
                 .flat_map(|&cnum| tcx.missing_lang_items(cnum))
                 .filter(|l| l.is_weak())
                 .filter_map(|&l| {
                     let name = l.link_name()?;
-                    lang_items::required(tcx, l).then_some(name)
+                    let export_kind = match l.target() {
+                        Target::Fn => SymbolExportKind::Text,
+                        Target::Static => SymbolExportKind::Data,
+                        _ => bug!(
+                            "Don't know what the export kind is for lang item of kind {:?}",
+                            l.target()
+                        ),
+                    };
+                    lang_items::required(tcx, l).then_some((name, export_kind))
                 })
                 .collect();
-            let prefix = match (target.is_like_windows, target.arch.as_ref()) {
-                (true, "x86") => "_",
-                (true, "arm64ec") => "#",
-                _ => "",
-            };
 
             // This loop only adds new items to values of the hash map, so the order in which we
             // iterate over the values is not important.
@@ -1059,10 +1079,13 @@ impl CrateInfo {
                 .for_each(|(_, linked_symbols)| {
                     let mut symbols = missing_weak_lang_items
                         .iter()
-                        .map(|item| {
+                        .map(|(item, export_kind)| {
                             (
-                                format!("{prefix}{}", mangle_internal_symbol(tcx, item.as_str())),
-                                SymbolExportKind::Text,
+                                add_prefix(
+                                    mangle_internal_symbol(tcx, item.as_str()),
+                                    *export_kind,
+                                ),
+                                *export_kind,
                             )
                         })
                         .collect::<Vec<_>>();
@@ -1077,12 +1100,12 @@ impl CrateInfo {
                         // errors.
                         linked_symbols.extend(ALLOCATOR_METHODS.iter().map(|method| {
                             (
-                                format!(
-                                    "{prefix}{}",
+                                add_prefix(
                                     mangle_internal_symbol(
                                         tcx,
-                                        global_fn_name(method.name).as_str()
-                                    )
+                                        global_fn_name(method.name).as_str(),
+                                    ),
+                                    SymbolExportKind::Text,
                                 ),
                                 SymbolExportKind::Text,
                             )
@@ -1092,7 +1115,7 @@ impl CrateInfo {
         }
 
         let embed_visualizers = tcx.crate_types().iter().any(|&crate_type| match crate_type {
-            CrateType::Executable | CrateType::Dylib | CrateType::Cdylib => {
+            CrateType::Executable | CrateType::Dylib | CrateType::Cdylib | CrateType::Sdylib => {
                 // These are crate types for which we invoke the linker and can embed
                 // NatVis visualizers.
                 true
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index bfec208c4ae..4f9757f198b 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -219,7 +219,7 @@ pub struct CrateInfo {
     pub target_cpu: String,
     pub target_features: Vec<String>,
     pub crate_types: Vec<CrateType>,
-    pub exported_symbols: UnordMap<CrateType, Vec<String>>,
+    pub exported_symbols: UnordMap<CrateType, Vec<(String, SymbolExportKind)>>,
     pub linked_symbols: FxIndexMap<CrateType, Vec<(String, SymbolExportKind)>>,
     pub local_crate_name: Symbol,
     pub compiler_builtins: Option<CrateNum>,
diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
index 0301ef437c0..d2a687359e0 100644
--- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
@@ -95,7 +95,9 @@ fn inline_to_global_operand<'a, 'tcx, Cx: LayoutOf<'tcx, LayoutOfResult = TyAndL
             );
 
             let instance = match mono_type.kind() {
-                &ty::FnDef(def_id, args) => Instance::new(def_id, args),
+                &ty::FnDef(def_id, args) => {
+                    Instance::expect_resolve(cx.tcx(), cx.typing_env(), def_id, args, value.span)
+                }
                 _ => bug!("asm sym is not a function"),
             };
 
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs
index 8f0cb197c44..1dd96297d1f 100644
--- a/compiler/rustc_const_eval/src/interpret/intern.rs
+++ b/compiler/rustc_const_eval/src/interpret/intern.rs
@@ -17,13 +17,13 @@ use hir::def::DefKind;
 use rustc_ast::Mutability;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_hir as hir;
+use rustc_hir::definitions::{DefPathData, DisambiguatorState};
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
 use rustc_middle::mir::interpret::{ConstAllocation, CtfeProvenance, InterpResult};
 use rustc_middle::query::TyCtxtAt;
 use rustc_middle::span_bug;
 use rustc_middle::ty::layout::TyAndLayout;
 use rustc_span::def_id::LocalDefId;
-use rustc_span::sym;
 use tracing::{instrument, trace};
 
 use super::{
@@ -66,6 +66,7 @@ fn intern_shallow<'tcx, T, M: CompileTimeMachine<'tcx, T>>(
     ecx: &mut InterpCx<'tcx, M>,
     alloc_id: AllocId,
     mutability: Mutability,
+    disambiguator: Option<&mut DisambiguatorState>,
 ) -> Result<impl Iterator<Item = CtfeProvenance> + 'tcx, ()> {
     trace!("intern_shallow {:?}", alloc_id);
     // remove allocation
@@ -88,7 +89,13 @@ fn intern_shallow<'tcx, T, M: CompileTimeMachine<'tcx, T>>(
     // link the alloc id to the actual allocation
     let alloc = ecx.tcx.mk_const_alloc(alloc);
     if let Some(static_id) = ecx.machine.static_def_id() {
-        intern_as_new_static(ecx.tcx, static_id, alloc_id, alloc);
+        intern_as_new_static(
+            ecx.tcx,
+            static_id,
+            alloc_id,
+            alloc,
+            disambiguator.expect("disambiguator needed"),
+        );
     } else {
         ecx.tcx.set_alloc_id_memory(alloc_id, alloc);
     }
@@ -102,11 +109,18 @@ fn intern_as_new_static<'tcx>(
     static_id: LocalDefId,
     alloc_id: AllocId,
     alloc: ConstAllocation<'tcx>,
+    disambiguator: &mut DisambiguatorState,
 ) {
+    // `intern_const_alloc_recursive` is called once per static and it contains the `DisambiguatorState`.
+    //  The `<static_id>::{{nested}}` path is thus unique to `intern_const_alloc_recursive` and the
+    // `DisambiguatorState` ensures the generated path is unique for this call as we generate
+    // `<static_id>::{{nested#n}}` where `n` is the `n`th `intern_as_new_static` call.
     let feed = tcx.create_def(
         static_id,
-        Some(sym::nested),
+        None,
         DefKind::Static { safety: hir::Safety::Safe, mutability: alloc.0.mutability, nested: true },
+        Some(DefPathData::NestedStatic),
+        disambiguator,
     );
     tcx.set_nested_alloc_id_static(alloc_id, feed.def_id());
 
@@ -154,6 +168,8 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval
     intern_kind: InternKind,
     ret: &MPlaceTy<'tcx>,
 ) -> Result<(), InternResult> {
+    let mut disambiguator = DisambiguatorState::new();
+
     // We are interning recursively, and for mutability we are distinguishing the "root" allocation
     // that we are starting in, and all other allocations that we are encountering recursively.
     let (base_mutability, inner_mutability, is_static) = match intern_kind {
@@ -197,7 +213,9 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval
         alloc.1.mutability = base_mutability;
         alloc.1.provenance().ptrs().iter().map(|&(_, prov)| prov).collect()
     } else {
-        intern_shallow(ecx, base_alloc_id, base_mutability).unwrap().collect()
+        intern_shallow(ecx, base_alloc_id, base_mutability, Some(&mut disambiguator))
+            .unwrap()
+            .collect()
     };
     // We need to distinguish "has just been interned" from "was already in `tcx`",
     // so we track this in a separate set.
@@ -291,7 +309,7 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval
         // okay with losing some potential for immutability here. This can anyway only affect
         // `static mut`.
         just_interned.insert(alloc_id);
-        match intern_shallow(ecx, alloc_id, inner_mutability) {
+        match intern_shallow(ecx, alloc_id, inner_mutability, Some(&mut disambiguator)) {
             Ok(nested) => todo.extend(nested),
             Err(()) => {
                 ecx.tcx.dcx().delayed_bug("found dangling pointer during const interning");
@@ -313,8 +331,9 @@ pub fn intern_const_alloc_for_constprop<'tcx, T, M: CompileTimeMachine<'tcx, T>>
         return interp_ok(());
     }
     // Move allocation to `tcx`.
-    if let Some(_) =
-        (intern_shallow(ecx, alloc_id, Mutability::Not).map_err(|()| err_ub!(DeadLocal))?).next()
+    if let Some(_) = intern_shallow(ecx, alloc_id, Mutability::Not, None)
+        .map_err(|()| err_ub!(DeadLocal))?
+        .next()
     {
         // We are not doing recursive interning, so we don't currently support provenance.
         // (If this assertion ever triggers, we should just implement a
@@ -340,7 +359,7 @@ impl<'tcx> InterpCx<'tcx, DummyMachine> {
         let dest = self.allocate(layout, MemoryKind::Stack)?;
         f(self, &dest.clone().into())?;
         let alloc_id = dest.ptr().provenance.unwrap().alloc_id(); // this was just allocated, it must have provenance
-        for prov in intern_shallow(self, alloc_id, Mutability::Not).unwrap() {
+        for prov in intern_shallow(self, alloc_id, Mutability::Not, None).unwrap() {
             // We are not doing recursive interning, so we don't currently support provenance.
             // (If this assertion ever triggers, we should just implement a
             // proper recursive interning loop -- or just call `intern_const_alloc_recursive`.
diff --git a/compiler/rustc_data_structures/src/graph/implementation/mod.rs b/compiler/rustc_data_structures/src/graph/linked_graph/mod.rs
index a80365938b9..ecb0095626b 100644
--- a/compiler/rustc_data_structures/src/graph/implementation/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/linked_graph/mod.rs
@@ -1,4 +1,4 @@
-//! A graph module for use in dataflow, region resolution, and elsewhere.
+//! See [`LinkedGraph`].
 //!
 //! # Interface details
 //!
@@ -28,7 +28,23 @@ use tracing::debug;
 #[cfg(test)]
 mod tests;
 
-pub struct Graph<N, E> {
+/// A concrete graph implementation that supports:
+/// - Nodes and/or edges labelled with custom data types (`N` and `E` respectively).
+/// - Incremental addition of new nodes/edges (but not removal).
+/// - Flat storage of node/edge data in a pair of vectors.
+/// - Iteration over any node's out-edges or in-edges, via linked lists
+///   threaded through the node/edge data.
+///
+/// # Caution
+/// This is an older graph implementation that is still used by some pieces
+/// of diagnostic/debugging code. New code that needs a graph data structure
+/// should consider using `VecGraph` instead, or implementing its own
+/// special-purpose graph with the specific features needed.
+///
+/// This graph implementation predates the later [graph traits](crate::graph),
+/// and does not implement those traits, so it has its own implementations of a
+/// few basic graph algorithms.
+pub struct LinkedGraph<N, E> {
     nodes: Vec<Node<N>>,
     edges: Vec<Edge<E>>,
 }
@@ -71,13 +87,13 @@ impl NodeIndex {
     }
 }
 
-impl<N: Debug, E: Debug> Graph<N, E> {
-    pub fn new() -> Graph<N, E> {
-        Graph { nodes: Vec::new(), edges: Vec::new() }
+impl<N: Debug, E: Debug> LinkedGraph<N, E> {
+    pub fn new() -> Self {
+        Self { nodes: Vec::new(), edges: Vec::new() }
     }
 
-    pub fn with_capacity(nodes: usize, edges: usize) -> Graph<N, E> {
-        Graph { nodes: Vec::with_capacity(nodes), edges: Vec::with_capacity(edges) }
+    pub fn with_capacity(nodes: usize, edges: usize) -> Self {
+        Self { nodes: Vec::with_capacity(nodes), edges: Vec::with_capacity(edges) }
     }
 
     // # Simple accessors
@@ -249,7 +265,7 @@ impl<N: Debug, E: Debug> Graph<N, E> {
 // # Iterators
 
 pub struct AdjacentEdges<'g, N, E> {
-    graph: &'g Graph<N, E>,
+    graph: &'g LinkedGraph<N, E>,
     direction: Direction,
     next: EdgeIndex,
 }
@@ -285,7 +301,7 @@ impl<'g, N: Debug, E: Debug> Iterator for AdjacentEdges<'g, N, E> {
 }
 
 pub struct DepthFirstTraversal<'g, N, E> {
-    graph: &'g Graph<N, E>,
+    graph: &'g LinkedGraph<N, E>,
     stack: Vec<NodeIndex>,
     visited: DenseBitSet<usize>,
     direction: Direction,
@@ -293,7 +309,7 @@ pub struct DepthFirstTraversal<'g, N, E> {
 
 impl<'g, N: Debug, E: Debug> DepthFirstTraversal<'g, N, E> {
     pub fn with_start_node(
-        graph: &'g Graph<N, E>,
+        graph: &'g LinkedGraph<N, E>,
         start_node: NodeIndex,
         direction: Direction,
     ) -> Self {
diff --git a/compiler/rustc_data_structures/src/graph/implementation/tests.rs b/compiler/rustc_data_structures/src/graph/linked_graph/tests.rs
index 32a6d9ec881..357aa81a57c 100644
--- a/compiler/rustc_data_structures/src/graph/implementation/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/linked_graph/tests.rs
@@ -1,11 +1,11 @@
 use tracing::debug;
 
-use crate::graph::implementation::*;
+use super::{Debug, LinkedGraph, NodeIndex};
 
-type TestGraph = Graph<&'static str, &'static str>;
+type TestGraph = LinkedGraph<&'static str, &'static str>;
 
 fn create_graph() -> TestGraph {
-    let mut graph = Graph::new();
+    let mut graph = LinkedGraph::new();
 
     // Create a simple graph
     //
@@ -56,7 +56,7 @@ fn each_edge() {
 }
 
 fn test_adjacent_edges<N: PartialEq + Debug, E: PartialEq + Debug>(
-    graph: &Graph<N, E>,
+    graph: &LinkedGraph<N, E>,
     start_index: NodeIndex,
     start_data: N,
     expected_incoming: &[(E, N)],
diff --git a/compiler/rustc_data_structures/src/graph/mod.rs b/compiler/rustc_data_structures/src/graph/mod.rs
index 4a1e5db6768..20416b472b2 100644
--- a/compiler/rustc_data_structures/src/graph/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/mod.rs
@@ -1,8 +1,8 @@
 use rustc_index::Idx;
 
 pub mod dominators;
-pub mod implementation;
 pub mod iterate;
+pub mod linked_graph;
 mod reference;
 pub mod reversed;
 pub mod scc;
diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs
index 80d49effbf8..b28c333d860 100644
--- a/compiler/rustc_data_structures/src/sync.rs
+++ b/compiler/rustc_data_structures/src/sync.rs
@@ -43,7 +43,7 @@ pub use self::freeze::{FreezeLock, FreezeReadGuard, FreezeWriteGuard};
 pub use self::lock::{Lock, LockGuard, Mode};
 pub use self::mode::{is_dyn_thread_safe, set_dyn_thread_safe_mode};
 pub use self::parallel::{
-    join, par_for_each_in, par_map, parallel_guard, scope, spawn, try_par_for_each_in,
+    broadcast, join, par_for_each_in, par_map, parallel_guard, scope, spawn, try_par_for_each_in,
 };
 pub use self::vec::{AppendOnlyIndexVec, AppendOnlyVec};
 pub use self::worker_local::{Registry, WorkerLocal};
diff --git a/compiler/rustc_data_structures/src/sync/parallel.rs b/compiler/rustc_data_structures/src/sync/parallel.rs
index 64db39cc4c6..ab65c7f3a6b 100644
--- a/compiler/rustc_data_structures/src/sync/parallel.rs
+++ b/compiler/rustc_data_structures/src/sync/parallel.rs
@@ -237,3 +237,13 @@ pub fn par_map<I: DynSend, T: IntoIterator<Item = I>, R: DynSend, C: FromIterato
         }
     })
 }
+
+pub fn broadcast<R: DynSend>(op: impl Fn(usize) -> R + DynSync) -> Vec<R> {
+    if mode::is_dyn_thread_safe() {
+        let op = FromDyn::from(op);
+        let results = rayon_core::broadcast(|context| op.derive(op(context.index())));
+        results.into_iter().map(|r| r.into_inner()).collect()
+    } else {
+        vec![op(0)]
+    }
+}
diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml
index c823d11126e..9da4f2dbc27 100644
--- a/compiler/rustc_driver_impl/Cargo.toml
+++ b/compiler/rustc_driver_impl/Cargo.toml
@@ -44,13 +44,13 @@ rustc_privacy = { path = "../rustc_privacy" }
 rustc_query_system = { path = "../rustc_query_system" }
 rustc_resolve = { path = "../rustc_resolve" }
 rustc_session = { path = "../rustc_session" }
-rustc_smir = { path = "../rustc_smir" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 rustc_ty_utils = { path = "../rustc_ty_utils" }
 serde_json = "1.0.59"
 shlex = "1.0"
+stable_mir = { path = "../stable_mir", features = ["rustc_internal"] }
 tracing = { version = "0.1.35" }
 # tidy-alphabetical-end
 
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index d18fa892814..95cfe221d3f 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -54,8 +54,8 @@ use rustc_metadata::locator;
 use rustc_middle::ty::TyCtxt;
 use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
 use rustc_session::config::{
-    CG_OPTIONS, ErrorOutputType, Input, OptionDesc, OutFileName, OutputType, UnstableOptions,
-    Z_OPTIONS, nightly_options, parse_target_triple,
+    CG_OPTIONS, CrateType, ErrorOutputType, Input, OptionDesc, OutFileName, OutputType,
+    UnstableOptions, Z_OPTIONS, nightly_options, parse_target_triple,
 };
 use rustc_session::getopts::{self, Matches};
 use rustc_session::lint::{Lint, LintId};
@@ -352,6 +352,8 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
 
             passes::write_dep_info(tcx);
 
+            passes::write_interface(tcx);
+
             if sess.opts.output_types.contains_key(&OutputType::DepInfo)
                 && sess.opts.output_types.len() == 1
             {
@@ -461,6 +463,7 @@ fn handle_explain(early_dcx: &EarlyDiagCtxt, registry: Registry, code: &str, col
     // Allow "E0123" or "0123" form.
     let upper_cased_code = code.to_ascii_uppercase();
     if let Ok(code) = upper_cased_code.strip_prefix('E').unwrap_or(&upper_cased_code).parse::<u32>()
+        && code <= ErrCode::MAX_AS_U32
         && let Ok(description) = registry.try_find_description(ErrCode::from_u32(code))
     {
         let mut is_in_code_block = false;
@@ -816,6 +819,7 @@ fn print_crate_info(
                 let supported_crate_types = CRATE_TYPES
                     .iter()
                     .filter(|(_, crate_type)| !invalid_output_for_target(&sess, *crate_type))
+                    .filter(|(_, crate_type)| *crate_type != CrateType::Sdylib)
                     .map(|(crate_type_sym, _)| *crate_type_sym)
                     .collect::<BTreeSet<_>>();
                 for supported_crate_type in supported_crate_types {
diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs
index 16d70af7e05..ec77043cd12 100644
--- a/compiler/rustc_driver_impl/src/pretty.rs
+++ b/compiler/rustc_driver_impl/src/pretty.rs
@@ -10,8 +10,8 @@ use rustc_middle::ty::{self, TyCtxt};
 use rustc_mir_build::thir::print::{thir_flat, thir_tree};
 use rustc_session::Session;
 use rustc_session::config::{OutFileName, PpHirMode, PpMode, PpSourceMode};
-use rustc_smir::rustc_internal::pretty::write_smir_pretty;
 use rustc_span::{FileName, Ident};
+use stable_mir::rustc_internal::pretty::write_smir_pretty;
 use tracing::debug;
 use {rustc_ast as ast, rustc_hir_pretty as pprust_hir};
 
diff --git a/compiler/rustc_error_codes/src/error_codes/E0253.md b/compiler/rustc_error_codes/src/error_codes/E0253.md
index 705d1bfc53e..628f5e252fb 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0253.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0253.md
@@ -1,9 +1,13 @@
+#### Note: this error code is no longer emitted by the compiler.
+
 Attempt was made to import an unimportable type. This can happen when trying
 to import a type from a trait.
 
 Erroneous code example:
 
-```compile_fail,E0253
+```
+#![feature(import_trait_associated_functions)]
+
 mod foo {
     pub trait MyTrait {
         type SomeType;
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index 2df3281568b..0994813ecb9 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -274,7 +274,12 @@ impl<'a> StripUnconfigured<'a> {
     /// is in the original source file. Gives a compiler error if the syntax of
     /// the attribute is incorrect.
     pub(crate) fn expand_cfg_attr(&self, cfg_attr: &Attribute, recursive: bool) -> Vec<Attribute> {
-        validate_attr::check_attribute_safety(&self.sess.psess, AttributeSafety::Normal, &cfg_attr);
+        validate_attr::check_attribute_safety(
+            &self.sess.psess,
+            Some(AttributeSafety::Normal),
+            &cfg_attr,
+            ast::CRATE_NODE_ID,
+        );
 
         // A trace attribute left in AST in place of the original `cfg_attr` attribute.
         // It can later be used by lints or other diagnostics.
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 1f430b0018f..d4853d1357f 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -1983,7 +1983,11 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
         let mut span: Option<Span> = None;
         while let Some(attr) = attrs.next() {
             rustc_ast_passes::feature_gate::check_attribute(attr, self.cx.sess, features);
-            validate_attr::check_attr(&self.cx.sess.psess, attr);
+            validate_attr::check_attr(
+                &self.cx.sess.psess,
+                attr,
+                self.cx.current_expansion.lint_node_id,
+            );
 
             let current_span = if let Some(sp) = span { sp.to(attr.span) } else { attr.span };
             span = Some(current_span);
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index a5e6b1c00d6..c117e0fcf7c 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -536,6 +536,12 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     // Unstable attributes:
     // ==========================================================================
 
+    // Linking:
+    gated!(
+        export_stable, Normal, template!(Word), WarnFollowing,
+        EncodeCrossCrate::No, experimental!(export_stable)
+    ),
+
     // Testing:
     gated!(
         test_runner, CrateLevel, template!(List: "path"), ErrorFollowing,
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 75e09cacb1f..a5f89b7a076 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -316,6 +316,7 @@ declare_features! (
     // Unstable `#[target_feature]` directives.
     (unstable, aarch64_unstable_target_feature, "1.82.0", Some(44839)),
     (unstable, aarch64_ver_target_feature, "1.27.0", Some(44839)),
+    (unstable, apx_target_feature, "CURRENT_RUSTC_VERSION", Some(139284)),
     (unstable, arm_target_feature, "1.27.0", Some(44839)),
     (unstable, avx512_target_feature, "1.27.0", Some(44839)),
     (unstable, bpf_target_feature, "1.54.0", Some(44839)),
@@ -393,6 +394,8 @@ declare_features! (
     (unstable, async_for_loop, "1.77.0", Some(118898)),
     /// Allows `async` trait bound modifier.
     (unstable, async_trait_bounds, "1.85.0", Some(62290)),
+    /// Allows using Intel AVX10 target features and intrinsics
+    (unstable, avx10_target_feature, "CURRENT_RUSTC_VERSION", Some(138843)),
     /// Allows using C-variadics.
     (unstable, c_variadic, "1.34.0", Some(44930)),
     /// Allows the use of `#[cfg(contract_checks)` to check if contract checks are enabled.
@@ -483,6 +486,8 @@ declare_features! (
     (unstable, explicit_extern_abis, "CURRENT_RUSTC_VERSION", Some(134986)),
     /// Allows explicit tail calls via `become` expression.
     (incomplete, explicit_tail_calls, "1.72.0", Some(112788)),
+    /// Allows using `#[export_stable]` which indicates that an item is exportable.
+    (incomplete, export_stable, "CURRENT_RUSTC_VERSION", Some(139939)),
     /// Allows using `aapcs`, `efiapi`, `sysv64` and `win64` as calling conventions
     /// for functions with varargs.
     (unstable, extended_varargs_abi_support, "1.65.0", Some(100189)),
@@ -506,6 +511,8 @@ declare_features! (
     (incomplete, fn_delegation, "1.76.0", Some(118212)),
     /// Allows impls for the Freeze trait.
     (internal, freeze_impls, "1.78.0", Some(121675)),
+    /// Frontmatter `---` blocks for use by external tools.
+    (unstable, frontmatter, "CURRENT_RUSTC_VERSION", Some(136889)),
     /// Allows defining gen blocks and `gen fn`.
     (unstable, gen_blocks, "1.75.0", Some(117078)),
     /// Infer generic args for both consts and types.
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 9372ab532bf..507c94aca8b 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -269,18 +269,10 @@ impl DefKind {
             | DefKind::TyParam
             | DefKind::ExternCrate => DefPathData::TypeNs(name.unwrap()),
 
-            // An associated type name will be missing for an RPITIT.
-            DefKind::AssocTy => {
-                if let Some(name) = name {
-                    DefPathData::TypeNs(name)
-                } else {
-                    DefPathData::AnonAssocTy
-                }
-            }
+            // An associated type name will be missing for an RPITIT (DefPathData::AnonAssocTy),
+            // but those provide their own DefPathData.
+            DefKind::AssocTy => DefPathData::TypeNs(name.unwrap()),
 
-            // It's not exactly an anon const, but wrt DefPathData, there
-            // is no difference.
-            DefKind::Static { nested: true, .. } => DefPathData::AnonConst,
             DefKind::Fn
             | DefKind::Const
             | DefKind::ConstParam
diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs
index bf7b1eefcf6..f93b9e5af53 100644
--- a/compiler/rustc_hir/src/definitions.rs
+++ b/compiler/rustc_hir/src/definitions.rs
@@ -68,7 +68,7 @@ impl DefPathTable {
             //
             // See the documentation for DefPathHash for more information.
             panic!(
-                "found DefPathHash collision between {def_path1:?} and {def_path2:?}. \
+                "found DefPathHash collision between {def_path1:#?} and {def_path2:#?}. \
                     Compilation cannot continue."
             );
         }
@@ -97,13 +97,31 @@ impl DefPathTable {
     }
 }
 
+#[derive(Debug)]
+pub struct DisambiguatorState {
+    next: UnordMap<(LocalDefId, DefPathData), u32>,
+}
+
+impl DisambiguatorState {
+    pub fn new() -> Self {
+        Self { next: Default::default() }
+    }
+
+    /// Creates a `DisambiguatorState` where the next allocated `(LocalDefId, DefPathData)` pair
+    /// will have `index` as the disambiguator.
+    pub fn with(def_id: LocalDefId, data: DefPathData, index: u32) -> Self {
+        let mut this = Self::new();
+        this.next.insert((def_id, data), index);
+        this
+    }
+}
+
 /// The definition table containing node definitions.
 /// It holds the `DefPathTable` for `LocalDefId`s/`DefPath`s.
 /// It also stores mappings to convert `LocalDefId`s to/from `HirId`s.
 #[derive(Debug)]
 pub struct Definitions {
     table: DefPathTable,
-    next_disambiguator: UnordMap<(LocalDefId, DefPathData), u32>,
 }
 
 /// A unique identifier that we can use to lookup a definition
@@ -127,7 +145,7 @@ impl DefKey {
         let DisambiguatedDefPathData { ref data, disambiguator } = self.disambiguated_data;
 
         std::mem::discriminant(data).hash(&mut hasher);
-        if let Some(name) = data.get_opt_name() {
+        if let Some(name) = data.hashed_symbol() {
             // Get a stable hash by considering the symbol chars rather than
             // the symbol index.
             name.as_str().hash(&mut hasher);
@@ -173,7 +191,11 @@ impl DisambiguatedDefPathData {
                 }
             }
             DefPathDataName::Anon { namespace } => {
-                write!(writer, "{{{}#{}}}", namespace, self.disambiguator)
+                if let DefPathData::AnonAssocTy(method) = self.data {
+                    write!(writer, "{}::{{{}#{}}}", method, namespace, self.disambiguator)
+                } else {
+                    write!(writer, "{{{}#{}}}", namespace, self.disambiguator)
+                }
             }
         }
     }
@@ -287,10 +309,15 @@ pub enum DefPathData {
     /// An existential `impl Trait` type node.
     /// Argument position `impl Trait` have a `TypeNs` with their pretty-printed name.
     OpaqueTy,
-    /// An anonymous associated type from an RPITIT.
-    AnonAssocTy,
+    /// Used for remapped captured lifetimes in an existential `impl Trait` type node.
+    OpaqueLifetime(Symbol),
+    /// An anonymous associated type from an RPITIT. The symbol refers to the name of the method
+    /// that defined the type.
+    AnonAssocTy(Symbol),
     /// A synthetic body for a coroutine's by-move body.
     SyntheticCoroutineBody,
+    /// Additional static data referred to by a static.
+    NestedStatic,
 }
 
 impl Definitions {
@@ -342,11 +369,20 @@ impl Definitions {
         let root = LocalDefId { local_def_index: table.allocate(key, def_path_hash) };
         assert_eq!(root.local_def_index, CRATE_DEF_INDEX);
 
-        Definitions { table, next_disambiguator: Default::default() }
+        Definitions { table }
     }
 
-    /// Adds a definition with a parent definition.
-    pub fn create_def(&mut self, parent: LocalDefId, data: DefPathData) -> LocalDefId {
+    /// Creates a definition with a parent definition.
+    /// If there are multiple definitions with the same DefPathData and the same parent, use
+    /// `disambiguator` to differentiate them. Distinct `DisambiguatorState` instances are not
+    /// guaranteed to generate unique disambiguators and should instead ensure that the `parent`
+    /// and `data` pair is distinct from other instances.
+    pub fn create_def(
+        &mut self,
+        parent: LocalDefId,
+        data: DefPathData,
+        disambiguator: &mut DisambiguatorState,
+    ) -> LocalDefId {
         // We can't use `Debug` implementation for `LocalDefId` here, since it tries to acquire a
         // reference to `Definitions` and we're already holding a mutable reference.
         debug!(
@@ -354,12 +390,12 @@ impl Definitions {
             self.def_path(parent).to_string_no_crate_verbose(),
         );
 
-        // The root node must be created with `create_root_def()`.
+        // The root node must be created in `new()`.
         assert!(data != DefPathData::CrateRoot);
 
         // Find the next free disambiguator for this key.
         let disambiguator = {
-            let next_disamb = self.next_disambiguator.entry((parent, data)).or_insert(0);
+            let next_disamb = disambiguator.next.entry((parent, data)).or_insert(0);
             let disambiguator = *next_disamb;
             *next_disamb = next_disamb.checked_add(1).expect("disambiguator overflow");
             disambiguator
@@ -411,7 +447,29 @@ impl DefPathData {
     pub fn get_opt_name(&self) -> Option<Symbol> {
         use self::DefPathData::*;
         match *self {
-            TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name),
+            TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name)
+            | OpaqueLifetime(name) => Some(name),
+
+            Impl
+            | ForeignMod
+            | CrateRoot
+            | Use
+            | GlobalAsm
+            | Closure
+            | Ctor
+            | AnonConst
+            | OpaqueTy
+            | AnonAssocTy(..)
+            | SyntheticCoroutineBody
+            | NestedStatic => None,
+        }
+    }
+
+    fn hashed_symbol(&self) -> Option<Symbol> {
+        use self::DefPathData::*;
+        match *self {
+            TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) | AnonAssocTy(name)
+            | OpaqueLifetime(name) => Some(name),
 
             Impl
             | ForeignMod
@@ -422,17 +480,16 @@ impl DefPathData {
             | Ctor
             | AnonConst
             | OpaqueTy
-            | AnonAssocTy
-            | SyntheticCoroutineBody => None,
+            | SyntheticCoroutineBody
+            | NestedStatic => None,
         }
     }
 
     pub fn name(&self) -> DefPathDataName {
         use self::DefPathData::*;
         match *self {
-            TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => {
-                DefPathDataName::Named(name)
-            }
+            TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name)
+            | OpaqueLifetime(name) => DefPathDataName::Named(name),
             // Note that this does not show up in user print-outs.
             CrateRoot => DefPathDataName::Anon { namespace: kw::Crate },
             Impl => DefPathDataName::Anon { namespace: kw::Impl },
@@ -443,8 +500,9 @@ impl DefPathData {
             Ctor => DefPathDataName::Anon { namespace: sym::constructor },
             AnonConst => DefPathDataName::Anon { namespace: sym::constant },
             OpaqueTy => DefPathDataName::Anon { namespace: sym::opaque },
-            AnonAssocTy => DefPathDataName::Anon { namespace: sym::anon_assoc },
+            AnonAssocTy(..) => DefPathDataName::Anon { namespace: sym::anon_assoc },
             SyntheticCoroutineBody => DefPathDataName::Anon { namespace: sym::synthetic },
+            NestedStatic => DefPathDataName::Anon { namespace: sym::nested },
         }
     }
 }
diff --git a/compiler/rustc_hir/src/hir/tests.rs b/compiler/rustc_hir/src/hir/tests.rs
index 18f8c523f9d..8684adee29c 100644
--- a/compiler/rustc_hir/src/hir/tests.rs
+++ b/compiler/rustc_hir/src/hir/tests.rs
@@ -50,21 +50,14 @@ fn trait_object_roundtrips() {
 }
 
 fn trait_object_roundtrips_impl(syntax: TraitObjectSyntax) {
-    let unambig = TyKind::TraitObject::<'_, ()>(
-        &[],
-        TaggedRef::new(
-            &const {
-                Lifetime {
-                    hir_id: HirId::INVALID,
-                    ident: Ident::new(sym::name, DUMMY_SP),
-                    kind: LifetimeKind::Static,
-                    source: LifetimeSource::Other,
-                    syntax: LifetimeSyntax::Hidden,
-                }
-            },
-            syntax,
-        ),
-    );
+    let lt = Lifetime {
+        hir_id: HirId::INVALID,
+        ident: Ident::new(sym::name, DUMMY_SP),
+        kind: LifetimeKind::Static,
+        source: LifetimeSource::Other,
+        syntax: LifetimeSyntax::Hidden,
+    };
+    let unambig = TyKind::TraitObject::<'_, ()>(&[], TaggedRef::new(&lt, syntax));
     let unambig_to_ambig = unsafe { std::mem::transmute::<_, TyKind<'_, AmbigArg>>(unambig) };
 
     match unambig_to_ambig {
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index bbf36fef1dd..fb67f2fd223 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -5,7 +5,7 @@ use std::iter;
 use hir::def_id::{DefId, DefIdMap, LocalDefId};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_errors::codes::*;
-use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err};
+use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan, pluralize, struct_span_code_err};
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::VisitorExt;
 use rustc_hir::{self as hir, AmbigArg, GenericParamKind, ImplItemKind, intravisit};
@@ -14,10 +14,10 @@ use rustc_infer::traits::util;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::{
     self, BottomUpFolder, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeFolder,
-    TypeSuperFoldable, TypeVisitableExt, TypingMode, Upcast,
+    TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Upcast,
 };
 use rustc_middle::{bug, span_bug};
-use rustc_span::Span;
+use rustc_span::{DUMMY_SP, Span};
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
 use rustc_trait_selection::infer::InferCtxtExt;
 use rustc_trait_selection::regions::InferCtxtRegionExt;
@@ -1137,65 +1137,319 @@ fn check_region_bounds_on_impl_item<'tcx>(
     // but found 0" it's confusing, because it looks like there
     // are zero. Since I don't quite know how to phrase things at
     // the moment, give a kind of vague error message.
-    if trait_params != impl_params {
-        let span = tcx
-            .hir_get_generics(impl_m.def_id.expect_local())
-            .expect("expected impl item to have generics or else we can't compare them")
-            .span;
-
-        let mut generics_span = None;
-        let mut bounds_span = vec![];
-        let mut where_span = None;
-        if let Some(trait_node) = tcx.hir_get_if_local(trait_m.def_id)
-            && let Some(trait_generics) = trait_node.generics()
-        {
-            generics_span = Some(trait_generics.span);
-            // FIXME: we could potentially look at the impl's bounds to not point at bounds that
-            // *are* present in the impl.
-            for p in trait_generics.predicates {
-                if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind {
-                    for b in pred.bounds {
+    if trait_params == impl_params {
+        return Ok(());
+    }
+
+    if !delay && let Some(guar) = check_region_late_boundedness(tcx, impl_m, trait_m) {
+        return Err(guar);
+    }
+
+    let span = tcx
+        .hir_get_generics(impl_m.def_id.expect_local())
+        .expect("expected impl item to have generics or else we can't compare them")
+        .span;
+
+    let mut generics_span = None;
+    let mut bounds_span = vec![];
+    let mut where_span = None;
+
+    if let Some(trait_node) = tcx.hir_get_if_local(trait_m.def_id)
+        && let Some(trait_generics) = trait_node.generics()
+    {
+        generics_span = Some(trait_generics.span);
+        // FIXME: we could potentially look at the impl's bounds to not point at bounds that
+        // *are* present in the impl.
+        for p in trait_generics.predicates {
+            match p.kind {
+                hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
+                    bounds,
+                    ..
+                })
+                | hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
+                    bounds,
+                    ..
+                }) => {
+                    for b in *bounds {
                         if let hir::GenericBound::Outlives(lt) = b {
                             bounds_span.push(lt.ident.span);
                         }
                     }
                 }
+                _ => {}
             }
-            if let Some(impl_node) = tcx.hir_get_if_local(impl_m.def_id)
-                && let Some(impl_generics) = impl_node.generics()
-            {
-                let mut impl_bounds = 0;
-                for p in impl_generics.predicates {
-                    if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind {
-                        for b in pred.bounds {
+        }
+        if let Some(impl_node) = tcx.hir_get_if_local(impl_m.def_id)
+            && let Some(impl_generics) = impl_node.generics()
+        {
+            let mut impl_bounds = 0;
+            for p in impl_generics.predicates {
+                match p.kind {
+                    hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
+                        bounds,
+                        ..
+                    })
+                    | hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
+                        bounds,
+                        ..
+                    }) => {
+                        for b in *bounds {
                             if let hir::GenericBound::Outlives(_) = b {
                                 impl_bounds += 1;
                             }
                         }
                     }
+                    _ => {}
+                }
+            }
+            if impl_bounds == bounds_span.len() {
+                bounds_span = vec![];
+            } else if impl_generics.has_where_clause_predicates {
+                where_span = Some(impl_generics.where_clause_span);
+            }
+        }
+    }
+
+    let reported = tcx
+        .dcx()
+        .create_err(LifetimesOrBoundsMismatchOnTrait {
+            span,
+            item_kind: impl_m.descr(),
+            ident: impl_m.ident(tcx),
+            generics_span,
+            bounds_span,
+            where_span,
+        })
+        .emit_unless(delay);
+
+    Err(reported)
+}
+
+#[allow(unused)]
+enum LateEarlyMismatch<'tcx> {
+    EarlyInImpl(DefId, DefId, ty::Region<'tcx>),
+    LateInImpl(DefId, DefId, ty::Region<'tcx>),
+}
+
+fn check_region_late_boundedness<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    impl_m: ty::AssocItem,
+    trait_m: ty::AssocItem,
+) -> Option<ErrorGuaranteed> {
+    if !impl_m.is_fn() {
+        return None;
+    }
+
+    let (infcx, param_env) = tcx
+        .infer_ctxt()
+        .build_with_typing_env(ty::TypingEnv::non_body_analysis(tcx, impl_m.def_id));
+
+    let impl_m_args = infcx.fresh_args_for_item(DUMMY_SP, impl_m.def_id);
+    let impl_m_sig = tcx.fn_sig(impl_m.def_id).instantiate(tcx, impl_m_args);
+    let impl_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, impl_m_sig);
+
+    let trait_m_args = infcx.fresh_args_for_item(DUMMY_SP, trait_m.def_id);
+    let trait_m_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_m_args);
+    let trait_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_m_sig);
+
+    let ocx = ObligationCtxt::new(&infcx);
+
+    // Equate the signatures so that we can infer whether a late-bound param was present where
+    // an early-bound param was expected, since we replace the late-bound lifetimes with
+    // `ReLateParam`, and early-bound lifetimes with infer vars, so the early-bound args will
+    // resolve to `ReLateParam` if there is a mismatch.
+    let Ok(()) = ocx.eq(
+        &ObligationCause::dummy(),
+        param_env,
+        ty::Binder::dummy(trait_m_sig),
+        ty::Binder::dummy(impl_m_sig),
+    ) else {
+        return None;
+    };
+
+    let errors = ocx.select_where_possible();
+    if !errors.is_empty() {
+        return None;
+    }
+
+    let mut mismatched = vec![];
+
+    let impl_generics = tcx.generics_of(impl_m.def_id);
+    for (id_arg, arg) in
+        std::iter::zip(ty::GenericArgs::identity_for_item(tcx, impl_m.def_id), impl_m_args)
+    {
+        if let ty::GenericArgKind::Lifetime(r) = arg.unpack()
+            && let ty::ReVar(vid) = r.kind()
+            && let r = infcx
+                .inner
+                .borrow_mut()
+                .unwrap_region_constraints()
+                .opportunistic_resolve_var(tcx, vid)
+            && let ty::ReLateParam(ty::LateParamRegion {
+                kind: ty::LateParamRegionKind::Named(trait_param_def_id, _),
+                ..
+            }) = r.kind()
+            && let ty::ReEarlyParam(ebr) = id_arg.expect_region().kind()
+        {
+            mismatched.push(LateEarlyMismatch::EarlyInImpl(
+                impl_generics.region_param(ebr, tcx).def_id,
+                trait_param_def_id,
+                id_arg.expect_region(),
+            ));
+        }
+    }
+
+    let trait_generics = tcx.generics_of(trait_m.def_id);
+    for (id_arg, arg) in
+        std::iter::zip(ty::GenericArgs::identity_for_item(tcx, trait_m.def_id), trait_m_args)
+    {
+        if let ty::GenericArgKind::Lifetime(r) = arg.unpack()
+            && let ty::ReVar(vid) = r.kind()
+            && let r = infcx
+                .inner
+                .borrow_mut()
+                .unwrap_region_constraints()
+                .opportunistic_resolve_var(tcx, vid)
+            && let ty::ReLateParam(ty::LateParamRegion {
+                kind: ty::LateParamRegionKind::Named(impl_param_def_id, _),
+                ..
+            }) = r.kind()
+            && let ty::ReEarlyParam(ebr) = id_arg.expect_region().kind()
+        {
+            mismatched.push(LateEarlyMismatch::LateInImpl(
+                impl_param_def_id,
+                trait_generics.region_param(ebr, tcx).def_id,
+                id_arg.expect_region(),
+            ));
+        }
+    }
+
+    if mismatched.is_empty() {
+        return None;
+    }
+
+    let spans: Vec<_> = mismatched
+        .iter()
+        .map(|param| {
+            let (LateEarlyMismatch::EarlyInImpl(impl_param_def_id, ..)
+            | LateEarlyMismatch::LateInImpl(impl_param_def_id, ..)) = param;
+            tcx.def_span(impl_param_def_id)
+        })
+        .collect();
+
+    let mut diag = tcx
+        .dcx()
+        .struct_span_err(spans, "lifetime parameters do not match the trait definition")
+        .with_note("lifetime parameters differ in whether they are early- or late-bound")
+        .with_code(E0195);
+    for mismatch in mismatched {
+        match mismatch {
+            LateEarlyMismatch::EarlyInImpl(
+                impl_param_def_id,
+                trait_param_def_id,
+                early_bound_region,
+            ) => {
+                let mut multispan = MultiSpan::from_spans(vec![
+                    tcx.def_span(impl_param_def_id),
+                    tcx.def_span(trait_param_def_id),
+                ]);
+                multispan
+                    .push_span_label(tcx.def_span(tcx.parent(impl_m.def_id)), "in this impl...");
+                multispan
+                    .push_span_label(tcx.def_span(tcx.parent(trait_m.def_id)), "in this trait...");
+                multispan.push_span_label(
+                    tcx.def_span(impl_param_def_id),
+                    format!("`{}` is early-bound", tcx.item_name(impl_param_def_id)),
+                );
+                multispan.push_span_label(
+                    tcx.def_span(trait_param_def_id),
+                    format!("`{}` is late-bound", tcx.item_name(trait_param_def_id)),
+                );
+                if let Some(span) =
+                    find_region_in_predicates(tcx, impl_m.def_id, early_bound_region)
+                {
+                    multispan.push_span_label(
+                        span,
+                        format!(
+                            "this lifetime bound makes `{}` early-bound",
+                            tcx.item_name(impl_param_def_id)
+                        ),
+                    );
                 }
-                if impl_bounds == bounds_span.len() {
-                    bounds_span = vec![];
-                } else if impl_generics.has_where_clause_predicates {
-                    where_span = Some(impl_generics.where_clause_span);
+                diag.span_note(
+                    multispan,
+                    format!(
+                        "`{}` differs between the trait and impl",
+                        tcx.item_name(impl_param_def_id)
+                    ),
+                );
+            }
+            LateEarlyMismatch::LateInImpl(
+                impl_param_def_id,
+                trait_param_def_id,
+                early_bound_region,
+            ) => {
+                let mut multispan = MultiSpan::from_spans(vec![
+                    tcx.def_span(impl_param_def_id),
+                    tcx.def_span(trait_param_def_id),
+                ]);
+                multispan
+                    .push_span_label(tcx.def_span(tcx.parent(impl_m.def_id)), "in this impl...");
+                multispan
+                    .push_span_label(tcx.def_span(tcx.parent(trait_m.def_id)), "in this trait...");
+                multispan.push_span_label(
+                    tcx.def_span(impl_param_def_id),
+                    format!("`{}` is late-bound", tcx.item_name(impl_param_def_id)),
+                );
+                multispan.push_span_label(
+                    tcx.def_span(trait_param_def_id),
+                    format!("`{}` is early-bound", tcx.item_name(trait_param_def_id)),
+                );
+                if let Some(span) =
+                    find_region_in_predicates(tcx, trait_m.def_id, early_bound_region)
+                {
+                    multispan.push_span_label(
+                        span,
+                        format!(
+                            "this lifetime bound makes `{}` early-bound",
+                            tcx.item_name(trait_param_def_id)
+                        ),
+                    );
                 }
+                diag.span_note(
+                    multispan,
+                    format!(
+                        "`{}` differs between the trait and impl",
+                        tcx.item_name(impl_param_def_id)
+                    ),
+                );
             }
         }
-        let reported = tcx
-            .dcx()
-            .create_err(LifetimesOrBoundsMismatchOnTrait {
-                span,
-                item_kind: impl_m.descr(),
-                ident: impl_m.ident(tcx),
-                generics_span,
-                bounds_span,
-                where_span,
-            })
-            .emit_unless(delay);
-        return Err(reported);
     }
 
-    Ok(())
+    Some(diag.emit())
+}
+
+fn find_region_in_predicates<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    def_id: DefId,
+    early_bound_region: ty::Region<'tcx>,
+) -> Option<Span> {
+    for (pred, span) in tcx.explicit_predicates_of(def_id).instantiate_identity(tcx) {
+        if pred.visit_with(&mut FindRegion(early_bound_region)).is_break() {
+            return Some(span);
+        }
+    }
+
+    struct FindRegion<'tcx>(ty::Region<'tcx>);
+    impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for FindRegion<'tcx> {
+        type Result = ControlFlow<()>;
+        fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result {
+            if r == self.0 { ControlFlow::Break(()) } else { ControlFlow::Continue(()) }
+        }
+    }
+
+    None
 }
 
 #[instrument(level = "debug", skip(infcx))]
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index fa36fe79716..2ec14b2f018 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -76,6 +76,36 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
         )
     }
 
+    /// Convenience function to *deeply* normalize during wfcheck. In the old solver,
+    /// this just dispatches to [`WfCheckingCtxt::normalize`], but in the new solver
+    /// this calls `deeply_normalize` and reports errors if they are encountered.
+    ///
+    /// This function should be called in favor of `normalize` in cases where we will
+    /// then check the well-formedness of the type, since we only use the normalized
+    /// signature types for implied bounds when checking regions.
+    // FIXME(-Znext-solver): This should be removed when we compute implied outlives
+    // bounds using the unnormalized signature of the function we're checking.
+    fn deeply_normalize<T>(&self, span: Span, loc: Option<WellFormedLoc>, value: T) -> T
+    where
+        T: TypeFoldable<TyCtxt<'tcx>>,
+    {
+        if self.infcx.next_trait_solver() {
+            match self.ocx.deeply_normalize(
+                &ObligationCause::new(span, self.body_def_id, ObligationCauseCode::WellFormed(loc)),
+                self.param_env,
+                value.clone(),
+            ) {
+                Ok(value) => value,
+                Err(errors) => {
+                    self.infcx.err_ctxt().report_fulfillment_errors(errors);
+                    value
+                }
+            }
+        } else {
+            self.normalize(span, loc, value)
+        }
+    }
+
     fn register_wf_obligation(&self, span: Span, loc: Option<WellFormedLoc>, term: ty::Term<'tcx>) {
         let cause = traits::ObligationCause::new(
             span,
@@ -297,7 +327,8 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
         {
             let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| {
                 let ty = tcx.type_of(def_id).instantiate_identity();
-                let item_ty = wfcx.normalize(hir_ty.span, Some(WellFormedLoc::Ty(def_id)), ty);
+                let item_ty =
+                    wfcx.deeply_normalize(hir_ty.span, Some(WellFormedLoc::Ty(def_id)), ty);
                 wfcx.register_wf_obligation(
                     hir_ty.span,
                     Some(WellFormedLoc::Ty(def_id)),
@@ -1073,7 +1104,7 @@ fn check_associated_item(
         match item.kind {
             ty::AssocKind::Const { .. } => {
                 let ty = tcx.type_of(item.def_id).instantiate_identity();
-                let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
+                let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
                 wfcx.register_wf_obligation(span, loc, ty.into());
                 check_sized_if_body(
                     wfcx,
@@ -1102,7 +1133,7 @@ fn check_associated_item(
                 }
                 if item.defaultness(tcx).has_value() {
                     let ty = tcx.type_of(item.def_id).instantiate_identity();
-                    let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
+                    let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
                     wfcx.register_wf_obligation(span, loc, ty.into());
                 }
                 Ok(())
@@ -1149,7 +1180,7 @@ fn check_type_defn<'tcx>(
                 let field_id = field.did.expect_local();
                 let hir::FieldDef { ty: hir_ty, .. } =
                     tcx.hir_node_by_def_id(field_id).expect_field();
-                let ty = wfcx.normalize(
+                let ty = wfcx.deeply_normalize(
                     hir_ty.span,
                     None,
                     tcx.type_of(field.did).instantiate_identity(),
@@ -1310,7 +1341,7 @@ fn check_item_type(
 
     enter_wf_checking_ctxt(tcx, ty_span, item_id, |wfcx| {
         let ty = tcx.type_of(item_id).instantiate_identity();
-        let item_ty = wfcx.normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty);
+        let item_ty = wfcx.deeply_normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty);
 
         let forbid_unsized = match unsized_handling {
             UnsizedHandling::Forbid => true,
@@ -1375,7 +1406,7 @@ fn check_impl<'tcx>(
                 // other `Foo` impls are incoherent.
                 tcx.ensure_ok().coherent_trait(trait_ref.def_id)?;
                 let trait_span = hir_trait_ref.path.span;
-                let trait_ref = wfcx.normalize(
+                let trait_ref = wfcx.deeply_normalize(
                     trait_span,
                     Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
                     trait_ref,
@@ -1435,7 +1466,7 @@ fn check_impl<'tcx>(
             }
             None => {
                 let self_ty = tcx.type_of(item.owner_id).instantiate_identity();
-                let self_ty = wfcx.normalize(
+                let self_ty = wfcx.deeply_normalize(
                     item.span,
                     Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
                     self_ty,
@@ -1640,7 +1671,7 @@ fn check_fn_or_method<'tcx>(
 
     sig.inputs_and_output =
         tcx.mk_type_list_from_iter(sig.inputs_and_output.iter().enumerate().map(|(idx, ty)| {
-            wfcx.normalize(
+            wfcx.deeply_normalize(
                 arg_span(idx),
                 Some(WellFormedLoc::Param {
                     function: def_id,
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 59ab36d98fd..709446d09cd 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -14,6 +14,7 @@ use rustc_ast::visit::walk_list;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def::{DefKind, Res};
+use rustc_hir::definitions::{DefPathData, DisambiguatorState};
 use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt};
 use rustc_hir::{
     self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, LifetimeKind, Node,
@@ -63,6 +64,7 @@ impl ResolvedArg {
 struct BoundVarContext<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     rbv: &'a mut ResolveBoundVars,
+    disambiguator: &'a mut DisambiguatorState,
     scope: ScopeRef<'a>,
 }
 
@@ -245,8 +247,12 @@ pub(crate) fn provide(providers: &mut Providers) {
 #[instrument(level = "debug", skip(tcx))]
 fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBoundVars {
     let mut rbv = ResolveBoundVars::default();
-    let mut visitor =
-        BoundVarContext { tcx, rbv: &mut rbv, scope: &Scope::Root { opt_parent_item: None } };
+    let mut visitor = BoundVarContext {
+        tcx,
+        rbv: &mut rbv,
+        scope: &Scope::Root { opt_parent_item: None },
+        disambiguator: &mut DisambiguatorState::new(),
+    };
     match tcx.hir_owner_node(local_def_id) {
         hir::OwnerNode::Item(item) => visitor.visit_item(item),
         hir::OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item),
@@ -515,9 +521,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
 
         let capture_all_in_scope_lifetimes = opaque_captures_all_in_scope_lifetimes(opaque);
         if capture_all_in_scope_lifetimes {
+            let tcx = self.tcx;
             let lifetime_ident = |def_id: LocalDefId| {
-                let name = self.tcx.item_name(def_id.to_def_id());
-                let span = self.tcx.def_span(def_id);
+                let name = tcx.item_name(def_id.to_def_id());
+                let span = tcx.def_span(def_id);
                 Ident::new(name, span)
             };
 
@@ -1091,8 +1098,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
     where
         F: for<'b> FnOnce(&mut BoundVarContext<'b, 'tcx>),
     {
-        let BoundVarContext { tcx, rbv, .. } = self;
-        let mut this = BoundVarContext { tcx: *tcx, rbv, scope: &wrap_scope };
+        let BoundVarContext { tcx, rbv, disambiguator, .. } = self;
+        let mut this = BoundVarContext { tcx: *tcx, rbv, disambiguator, scope: &wrap_scope };
         let span = debug_span!("scope", scope = ?this.scope.debug_truncated());
         {
             let _enter = span.enter();
@@ -1446,7 +1453,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
 
     #[instrument(level = "trace", skip(self, opaque_capture_scopes), ret)]
     fn remap_opaque_captures(
-        &self,
+        &mut self,
         opaque_capture_scopes: &Vec<(LocalDefId, &RefCell<FxIndexMap<ResolvedArg, LocalDefId>>)>,
         mut lifetime: ResolvedArg,
         ident: Ident,
@@ -1462,8 +1469,17 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
         for &(opaque_def_id, captures) in opaque_capture_scopes.iter().rev() {
             let mut captures = captures.borrow_mut();
             let remapped = *captures.entry(lifetime).or_insert_with(|| {
-                let feed =
-                    self.tcx.create_def(opaque_def_id, Some(ident.name), DefKind::LifetimeParam);
+                // `opaque_def_id` is unique to the `BoundVarContext` pass which is executed once
+                // per `resolve_bound_vars` query. This is the only location that creates
+                // `OpaqueLifetime` paths. `<opaque_def_id>::OpaqueLifetime(..)` is thus unique
+                // to this query and duplicates within the query are handled by `self.disambiguator`.
+                let feed = self.tcx.create_def(
+                    opaque_def_id,
+                    None,
+                    DefKind::LifetimeParam,
+                    Some(DefPathData::OpaqueLifetime(ident.name)),
+                    &mut self.disambiguator,
+                );
                 feed.def_span(ident.span);
                 feed.def_ident_span(Some(ident.span));
                 feed.def_id()
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index bf91eb1b8fd..4419d5dc7d6 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -9,8 +9,8 @@ use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::{AmbigArg, HirId};
 use rustc_middle::bug;
 use rustc_middle::ty::{
-    self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
-    TypeVisitor, Upcast,
+    self as ty, IsSuggestable, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable,
+    TypeVisitableExt, TypeVisitor, Upcast,
 };
 use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
 use rustc_trait_selection::traits;
@@ -996,7 +996,7 @@ struct GenericParamAndBoundVarCollector<'a, 'tcx> {
 impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GenericParamAndBoundVarCollector<'_, 'tcx> {
     type Result = ControlFlow<ErrorGuaranteed>;
 
-    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
+    fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
         &mut self,
         binder: &ty::Binder<'tcx, T>,
     ) -> Self::Result {
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
index 88f74589204..f6e5149bd2b 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
@@ -172,7 +172,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
         let principal_trait = regular_traits.into_iter().next();
 
-        let mut needed_associated_types = vec![];
+        // A stable ordering of associated types from the principal trait and all its
+        // supertraits. We use this to ensure that different substitutions of a trait
+        // don't result in `dyn Trait` types with different projections lists, which
+        // can be unsound: <https://github.com/rust-lang/rust/pull/136458>.
+        // We achieve a stable ordering by walking over the unsubstituted principal
+        // trait ref.
+        let mut ordered_associated_types = vec![];
+
         if let Some((principal_trait, ref spans)) = principal_trait {
             let principal_trait = principal_trait.map_bound(|trait_pred| {
                 assert_eq!(trait_pred.polarity, ty::PredicatePolarity::Positive);
@@ -197,16 +204,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         // FIXME(negative_bounds): Handle this correctly...
                         let trait_ref =
                             tcx.anonymize_bound_vars(bound_predicate.rebind(pred.trait_ref));
-                        needed_associated_types.extend(
+                        ordered_associated_types.extend(
                             tcx.associated_items(pred.trait_ref.def_id)
                                 .in_definition_order()
                                 // We only care about associated types.
                                 .filter(|item| item.is_type())
                                 // No RPITITs -- they're not dyn-compatible for now.
                                 .filter(|item| !item.is_impl_trait_in_trait())
-                                // If the associated type has a `where Self: Sized` bound,
-                                // we do not need to constrain the associated type.
-                                .filter(|item| !tcx.generics_require_sized_self(item.def_id))
                                 .map(|item| (item.def_id, trait_ref)),
                         );
                     }
@@ -278,14 +282,26 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             }
         }
 
+        // We compute the list of projection bounds taking the ordered associated types,
+        // and check if there was an entry in the collected `projection_bounds`. Those
+        // are computed by first taking the user-written associated types, then elaborating
+        // the principal trait ref, and only using those if there was no user-written.
+        // See note below about how we handle missing associated types with `Self: Sized`,
+        // which are not required to be provided, but are still used if they are provided.
         let mut missing_assoc_types = FxIndexSet::default();
-        let projection_bounds: Vec<_> = needed_associated_types
+        let projection_bounds: Vec<_> = ordered_associated_types
             .into_iter()
             .filter_map(|key| {
                 if let Some(assoc) = projection_bounds.get(&key) {
                     Some(*assoc)
                 } else {
-                    missing_assoc_types.insert(key);
+                    // If the associated type has a `where Self: Sized` bound, then
+                    // we do not need to provide the associated type. This results in
+                    // a `dyn Trait` type that has a different number of projection
+                    // bounds, which may lead to type mismatches.
+                    if !tcx.generics_require_sized_self(key.0) {
+                        missing_assoc_types.insert(key);
+                    }
                     None
                 }
             })
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index fcb7382549f..5e79e932015 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -1770,7 +1770,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         span: Span,
         opt_self_ty: Option<Ty<'tcx>>,
         item_def_id: DefId,
-        trait_segment: &hir::PathSegment<'tcx>,
+        trait_segment: Option<&hir::PathSegment<'tcx>>,
         item_segment: &hir::PathSegment<'tcx>,
     ) -> Ty<'tcx> {
         match self.lower_qpath_shared(
@@ -1795,7 +1795,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         span: Span,
         opt_self_ty: Option<Ty<'tcx>>,
         item_def_id: DefId,
-        trait_segment: &hir::PathSegment<'tcx>,
+        trait_segment: Option<&hir::PathSegment<'tcx>>,
         item_segment: &hir::PathSegment<'tcx>,
     ) -> Const<'tcx> {
         match self.lower_qpath_shared(
@@ -1820,7 +1820,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         span: Span,
         opt_self_ty: Option<Ty<'tcx>>,
         item_def_id: DefId,
-        trait_segment: &hir::PathSegment<'tcx>,
+        trait_segment: Option<&hir::PathSegment<'tcx>>,
         item_segment: &hir::PathSegment<'tcx>,
         assoc_tag: ty::AssocTag,
     ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed> {
@@ -1840,7 +1840,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         debug!(?self_ty);
 
         let trait_ref =
-            self.lower_mono_trait_ref(span, trait_def_id, self_ty, trait_segment, false);
+            self.lower_mono_trait_ref(span, trait_def_id, self_ty, trait_segment.unwrap(), false);
         debug!(?trait_ref);
 
         let item_args =
@@ -2196,16 +2196,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 }
             }
             Res::Def(DefKind::AssocTy, def_id) => {
-                debug_assert!(path.segments.len() >= 2);
-                let _ = self.prohibit_generic_args(
-                    path.segments[..path.segments.len() - 2].iter(),
-                    GenericsArgsErrExtend::None,
-                );
+                let trait_segment = if let [modules @ .., trait_, _item] = path.segments {
+                    let _ = self.prohibit_generic_args(modules.iter(), GenericsArgsErrExtend::None);
+                    Some(trait_)
+                } else {
+                    None
+                };
                 self.lower_qpath_ty(
                     span,
                     opt_self_ty,
                     def_id,
-                    &path.segments[path.segments.len() - 2],
+                    trait_segment,
                     path.segments.last().unwrap(),
                 )
             }
@@ -2413,16 +2414,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args))
             }
             Res::Def(DefKind::AssocConst, did) => {
-                debug_assert!(path.segments.len() >= 2);
-                let _ = self.prohibit_generic_args(
-                    path.segments[..path.segments.len() - 2].iter(),
-                    GenericsArgsErrExtend::None,
-                );
+                let trait_segment = if let [modules @ .., trait_, _item] = path.segments {
+                    let _ = self.prohibit_generic_args(modules.iter(), GenericsArgsErrExtend::None);
+                    Some(trait_)
+                } else {
+                    None
+                };
                 self.lower_qpath_const(
                     span,
                     opt_self_ty,
                     did,
-                    &path.segments[path.segments.len() - 2],
+                    trait_segment,
                     path.segments.last().unwrap(),
                 )
             }
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 309b8f2c761..91dde13be55 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -216,7 +216,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
                 check::maybe_check_static_with_link_section(tcx, item_def_id);
             }
             DefKind::Const if tcx.generics_of(item_def_id).is_empty() => {
-                let instance = ty::Instance::new(item_def_id.into(), ty::GenericArgs::empty());
+                let instance = ty::Instance::new_raw(item_def_id.into(), ty::GenericArgs::empty());
                 let cid = GlobalId { instance, promoted: None };
                 let typing_env = ty::TypingEnv::fully_monomorphized();
                 tcx.ensure_ok().eval_to_const_value_raw(typing_env.as_query_input(cid));
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 15e997aebcb..09bf84ab64f 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -110,6 +110,7 @@ impl<'a> State<'a> {
                 }
                 self.print_attr_item(&unparsed, unparsed.span);
                 self.word("]");
+                self.hardbreak()
             }
             hir::Attribute::Parsed(AttributeKind::DocComment { style, kind, comment, .. }) => {
                 self.word(rustc_ast_pretty::pprust::state::doc_comment_to_string(
@@ -183,7 +184,7 @@ impl<'a> State<'a> {
             Node::Ty(a) => self.print_type(a),
             Node::AssocItemConstraint(a) => self.print_assoc_item_constraint(a),
             Node::TraitRef(a) => self.print_trait_ref(a),
-            Node::OpaqueTy(o) => self.print_opaque_ty(o),
+            Node::OpaqueTy(_) => panic!("cannot print Node::OpaqueTy"),
             Node::Pat(a) => self.print_pat(a),
             Node::TyPat(a) => self.print_ty_pat(a),
             Node::PatField(a) => self.print_patfield(a),
@@ -654,10 +655,11 @@ impl<'a> State<'a> {
                 self.bclose(item.span, cb);
             }
             hir::ItemKind::GlobalAsm { asm, .. } => {
-                // FIXME(nnethercote): `ib` is unclosed
-                let (cb, _ib) = self.head("global_asm!");
+                let (cb, ib) = self.head("global_asm!");
                 self.print_inline_asm(asm);
-                self.end(cb)
+                self.word(";");
+                self.end(cb);
+                self.end(ib);
             }
             hir::ItemKind::TyAlias(ident, ty, generics) => {
                 let (cb, ib) = self.head("type");
@@ -764,14 +766,6 @@ impl<'a> State<'a> {
         self.print_path(t.path, false);
     }
 
-    fn print_opaque_ty(&mut self, o: &hir::OpaqueTy<'_>) {
-        // FIXME(nnethercote): `cb` and `ib` are unclosed
-        let (_cb, _ib) = self.head("opaque");
-        self.word("{");
-        self.print_bounds("impl", o.bounds);
-        self.word("}");
-    }
-
     fn print_formal_generic_params(&mut self, generic_params: &[hir::GenericParam<'_>]) {
         if !generic_params.is_empty() {
             self.word("for");
@@ -1509,7 +1503,7 @@ impl<'a> State<'a> {
             }
             hir::ExprKind::DropTemps(init) => {
                 // Print `{`:
-                let cb = self.cbox(INDENT_UNIT);
+                let cb = self.cbox(0);
                 let ib = self.ibox(0);
                 self.bopen(ib);
 
@@ -1532,16 +1526,18 @@ impl<'a> State<'a> {
                 self.print_if(test, blk, elseopt);
             }
             hir::ExprKind::Loop(blk, opt_label, _, _) => {
+                let cb = self.cbox(0);
+                let ib = self.ibox(0);
                 if let Some(label) = opt_label {
                     self.print_ident(label.ident);
                     self.word_space(":");
                 }
-                let (cb, ib) = self.head("loop");
+                self.word_nbsp("loop");
                 self.print_block(blk, cb, ib);
             }
             hir::ExprKind::Match(expr, arms, _) => {
-                let cb = self.cbox(INDENT_UNIT);
-                let ib = self.ibox(INDENT_UNIT);
+                let cb = self.cbox(0);
+                let ib = self.ibox(0);
                 self.word_nbsp("match");
                 self.print_expr_as_cond(expr);
                 self.space();
@@ -1572,15 +1568,6 @@ impl<'a> State<'a> {
 
                 // This is a bare expression.
                 self.ann.nested(self, Nested::Body(body));
-                // FIXME(nnethercote): this is bogus
-                let fake_ib = BoxMarker;
-                self.end(fake_ib);
-
-                // A box will be closed by `print_expr`, but we didn't want an overall
-                // wrapper so we closed the corresponding opening. so create an
-                // empty box to satisfy the close.
-                // FIXME(nnethercote): this is bogus, and `print_expr` is missing
-                let _ib = self.ibox(0);
             }
             hir::ExprKind::Block(blk, opt_label) => {
                 if let Some(label) = opt_label {
diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs
index 38319862334..61dd8c57307 100644
--- a/compiler/rustc_hir_typeck/src/_match.rs
+++ b/compiler/rustc_hir_typeck/src/_match.rs
@@ -11,7 +11,7 @@ use rustc_trait_selection::traits::{
 use tracing::{debug, instrument};
 
 use crate::coercion::{AsCoercionSite, CoerceMany};
-use crate::{Diverges, Expectation, FnCtxt, Needs};
+use crate::{Diverges, Expectation, FnCtxt, GatherLocalsVisitor, Needs};
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     #[instrument(skip(self), level = "debug", ret)]
@@ -43,6 +43,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // #55810: Type check patterns first so we get types for all bindings.
         let scrut_span = scrut.span.find_ancestor_inside(expr.span).unwrap_or(scrut.span);
         for arm in arms {
+            GatherLocalsVisitor::gather_from_arm(self, arm);
+
             self.check_pat_top(arm.pat, scrutinee_ty, Some(scrut_span), Some(scrut), None);
         }
 
@@ -601,7 +603,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // FIXME(-Znext-solver): Remove this branch once `replace_opaque_types_with_infer` is gone.
             ty::Infer(ty::TyVar(_)) => self
                 .inner
-                .borrow()
+                .borrow_mut()
+                .opaque_types()
                 .iter_opaque_types()
                 .find(|(_, v)| v.ty == expected_ty)
                 .map(|(k, _)| (k.def_id, k.args))?,
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index caf36ba47bd..5bfc3e810d9 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -1051,20 +1051,19 @@ impl<'a, 'tcx> CastCheck<'tcx> {
     fn check_ref_cast(
         &self,
         fcx: &FnCtxt<'a, 'tcx>,
-        m_expr: ty::TypeAndMut<'tcx>,
-        m_cast: ty::TypeAndMut<'tcx>,
+        mut m_expr: ty::TypeAndMut<'tcx>,
+        mut m_cast: ty::TypeAndMut<'tcx>,
     ) -> Result<CastKind, CastError<'tcx>> {
         // array-ptr-cast: allow mut-to-mut, mut-to-const, const-to-const
+        m_expr.ty = fcx.try_structurally_resolve_type(self.expr_span, m_expr.ty);
+        m_cast.ty = fcx.try_structurally_resolve_type(self.cast_span, m_cast.ty);
+
         if m_expr.mutbl >= m_cast.mutbl
             && let ty::Array(ety, _) = m_expr.ty.kind()
             && fcx.can_eq(fcx.param_env, *ety, m_cast.ty)
         {
-            // Due to the limitations of LLVM global constants,
-            // region pointers end up pointing at copies of
-            // vector elements instead of the original values.
-            // To allow raw pointers to work correctly, we
-            // need to special-case obtaining a raw pointer
-            // from a region pointer to a vector.
+            // Due to historical reasons we allow directly casting references of
+            // arrays into raw pointers of their element type.
 
             // Coerce to a raw pointer so that we generate RawPtr in MIR.
             let array_ptr_type = Ty::new_ptr(fcx.tcx, m_expr.ty, m_expr.mutbl);
diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs
index 2189fdf0f34..99103f14d68 100644
--- a/compiler/rustc_hir_typeck/src/check.rs
+++ b/compiler/rustc_hir_typeck/src/check.rs
@@ -3,7 +3,6 @@ use std::cell::RefCell;
 use rustc_abi::ExternAbi;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
-use rustc_hir::intravisit::Visitor;
 use rustc_hir::lang_items::LangItem;
 use rustc_hir_analysis::check::check_function_signature;
 use rustc_infer::infer::RegionVariableOrigin;
@@ -50,7 +49,9 @@ pub(super) fn check_fn<'a, 'tcx>(
 
     let span = body.value.span;
 
-    GatherLocalsVisitor::new(fcx).visit_body(body);
+    for param in body.params {
+        GatherLocalsVisitor::gather_from_param(fcx, param);
+    }
 
     // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
     // (as it's created inside the body itself, not passed in from outside).
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index db2650ed357..2c28ffd1fe3 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -16,7 +16,6 @@ use rustc_errors::{
 };
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::DefId;
-use rustc_hir::intravisit::Visitor;
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{ExprKind, HirId, QPath};
 use rustc_hir_analysis::NoVariantNamed;
@@ -50,8 +49,8 @@ use crate::errors::{
     YieldExprOutsideOfCoroutine,
 };
 use crate::{
-    BreakableCtxt, CoroutineTypes, Diverges, FnCtxt, Needs, TupleArgumentsFlag, cast,
-    fatally_break_rust, report_unexpected_variant_res, type_error_struct,
+    BreakableCtxt, CoroutineTypes, Diverges, FnCtxt, GatherLocalsVisitor, Needs,
+    TupleArgumentsFlag, cast, fatally_break_rust, report_unexpected_variant_res, type_error_struct,
 };
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -1518,11 +1517,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let_expr: &'tcx hir::LetExpr<'tcx>,
         hir_id: HirId,
     ) -> Ty<'tcx> {
+        GatherLocalsVisitor::gather_from_let_expr(self, let_expr, hir_id);
+
         // for let statements, this is done in check_stmt
         let init = let_expr.init;
         self.warn_if_unreachable(init.hir_id, init.span, "block in `let` expression");
+
         // otherwise check exactly as a let statement
         self.check_decl((let_expr, hir_id).into());
+
         // but return a bool, for this is a boolean expression
         if let ast::Recovered::Yes(error_guaranteed) = let_expr.recovered {
             self.set_tainted_by_errors(error_guaranteed);
@@ -1827,7 +1830,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // Create a new function context.
         let def_id = block.def_id;
         let fcx = FnCtxt::new(self, self.param_env, def_id);
-        crate::GatherLocalsVisitor::new(&fcx).visit_body(body);
 
         let ty = fcx.check_expr_with_expectation(body.value, expected);
         fcx.require_type_is_sized(ty, body.value.span, ObligationCauseCode::SizedConstOrStatic);
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index 17e13ec0a37..3493d359028 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -158,7 +158,7 @@ pub trait TypeInformationCtxt<'tcx> {
 
     fn resolve_vars_if_possible<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T;
 
-    fn try_structurally_resolve_type(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>;
+    fn structurally_resolve_type(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>;
 
     fn report_bug(&self, span: Span, msg: impl ToString) -> Self::Error;
 
@@ -191,8 +191,8 @@ impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> {
         self.infcx.resolve_vars_if_possible(t)
     }
 
-    fn try_structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
-        (**self).try_structurally_resolve_type(sp, ty)
+    fn structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
+        (**self).structurally_resolve_type(sp, ty)
     }
 
     fn report_bug(&self, span: Span, msg: impl ToString) -> Self::Error {
@@ -236,7 +236,7 @@ impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) {
         self.0.maybe_typeck_results().expect("expected typeck results")
     }
 
-    fn try_structurally_resolve_type(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
+    fn structurally_resolve_type(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
         // FIXME: Maybe need to normalize here.
         ty
     }
@@ -776,7 +776,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
 
         // Select just those fields of the `with`
         // expression that will actually be used
-        match self.cx.try_structurally_resolve_type(with_expr.span, with_place.place.ty()).kind() {
+        match self.cx.structurally_resolve_type(with_expr.span, with_place.place.ty()).kind() {
             ty::Adt(adt, args) if adt.is_struct() => {
                 // Consume those fields of the with expression that are needed.
                 for (f_index, with_field) in adt.non_enum_variant().fields.iter_enumerated() {
@@ -1176,7 +1176,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
 /// two operations: a dereference to reach the array data and then an index to
 /// jump forward to the relevant item.
 impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx, Cx, D> {
-    fn resolve_type_vars_or_bug(
+    fn expect_and_resolve_type(
         &self,
         id: HirId,
         ty: Option<Ty<'tcx>>,
@@ -1185,12 +1185,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
             Some(ty) => {
                 let ty = self.cx.resolve_vars_if_possible(ty);
                 self.cx.error_reported_in_ty(ty)?;
-                if ty.is_ty_var() {
-                    debug!("resolve_type_vars_or_bug: infer var from {:?}", ty);
-                    Err(self.cx.report_bug(self.cx.tcx().hir_span(id), "encountered type variable"))
-                } else {
-                    Ok(ty)
-                }
+                Ok(ty)
             }
             None => {
                 // FIXME: We shouldn't be relying on the infcx being tainted.
@@ -1201,15 +1196,15 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
     }
 
     fn node_ty(&self, hir_id: HirId) -> Result<Ty<'tcx>, Cx::Error> {
-        self.resolve_type_vars_or_bug(hir_id, self.cx.typeck_results().node_type_opt(hir_id))
+        self.expect_and_resolve_type(hir_id, self.cx.typeck_results().node_type_opt(hir_id))
     }
 
     fn expr_ty(&self, expr: &hir::Expr<'_>) -> Result<Ty<'tcx>, Cx::Error> {
-        self.resolve_type_vars_or_bug(expr.hir_id, self.cx.typeck_results().expr_ty_opt(expr))
+        self.expect_and_resolve_type(expr.hir_id, self.cx.typeck_results().expr_ty_opt(expr))
     }
 
     fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Result<Ty<'tcx>, Cx::Error> {
-        self.resolve_type_vars_or_bug(
+        self.expect_and_resolve_type(
             expr.hir_id,
             self.cx.typeck_results().expr_ty_adjusted_opt(expr),
         )
@@ -1264,10 +1259,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
                     // a bind-by-ref means that the base_ty will be the type of the ident itself,
                     // but what we want here is the type of the underlying value being borrowed.
                     // So peel off one-level, turning the &T into T.
-                    match self
-                        .cx
-                        .try_structurally_resolve_type(pat.span, base_ty)
-                        .builtin_deref(false)
+                    match self.cx.structurally_resolve_type(pat.span, base_ty).builtin_deref(false)
                     {
                         Some(ty) => Ok(ty),
                         None => {
@@ -1513,10 +1505,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
             if node_ty != place_ty
                 && self
                     .cx
-                    .try_structurally_resolve_type(
-                        self.cx.tcx().hir_span(base_place.hir_id),
-                        place_ty,
-                    )
+                    .structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), place_ty)
                     .is_impl_trait()
             {
                 projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty });
@@ -1538,7 +1527,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
         let base_ty = self.expr_ty_adjusted(base)?;
 
         let ty::Ref(region, _, mutbl) =
-            *self.cx.try_structurally_resolve_type(base.span, base_ty).kind()
+            *self.cx.structurally_resolve_type(base.span, base_ty).kind()
         else {
             span_bug!(expr.span, "cat_overloaded_place: base is not a reference");
         };
@@ -1556,7 +1545,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
         let base_curr_ty = base_place.place.ty();
         let deref_ty = match self
             .cx
-            .try_structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), base_curr_ty)
+            .structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), base_curr_ty)
             .builtin_deref(true)
         {
             Some(ty) => ty,
@@ -1584,7 +1573,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
     ) -> Result<VariantIdx, Cx::Error> {
         let res = self.cx.typeck_results().qpath_res(qpath, pat_hir_id);
         let ty = self.cx.typeck_results().node_type(pat_hir_id);
-        let ty::Adt(adt_def, _) = self.cx.try_structurally_resolve_type(span, ty).kind() else {
+        let ty::Adt(adt_def, _) = self.cx.structurally_resolve_type(span, ty).kind() else {
             return Err(self
                 .cx
                 .report_bug(span, "struct or tuple struct pattern not applied to an ADT"));
@@ -1616,7 +1605,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
         span: Span,
     ) -> Result<usize, Cx::Error> {
         let ty = self.cx.typeck_results().node_type(pat_hir_id);
-        match self.cx.try_structurally_resolve_type(span, ty).kind() {
+        match self.cx.structurally_resolve_type(span, ty).kind() {
             ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()),
             _ => {
                 self.cx
@@ -1631,7 +1620,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
     /// Here `pat_hir_id` is the HirId of the pattern itself.
     fn total_fields_in_tuple(&self, pat_hir_id: HirId, span: Span) -> Result<usize, Cx::Error> {
         let ty = self.cx.typeck_results().node_type(pat_hir_id);
-        match self.cx.try_structurally_resolve_type(span, ty).kind() {
+        match self.cx.structurally_resolve_type(span, ty).kind() {
             ty::Tuple(args) => Ok(args.len()),
             _ => Err(self.cx.report_bug(span, "tuple pattern not applied to a tuple")),
         }
@@ -1820,7 +1809,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
             PatKind::Slice(before, ref slice, after) => {
                 let Some(element_ty) = self
                     .cx
-                    .try_structurally_resolve_type(pat.span, place_with_id.place.ty())
+                    .structurally_resolve_type(pat.span, place_with_id.place.ty())
                     .builtin_index()
                 else {
                     debug!("explicit index of non-indexable type {:?}", place_with_id);
@@ -1890,7 +1879,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
     }
 
     fn is_multivariant_adt(&self, ty: Ty<'tcx>, span: Span) -> bool {
-        if let ty::Adt(def, _) = self.cx.try_structurally_resolve_type(span, ty).kind() {
+        if let ty::Adt(def, _) = self.cx.structurally_resolve_type(span, ty).kind() {
             // Note that if a non-exhaustive SingleVariant is defined in another crate, we need
             // to assume that more cases will be added to the variant in the future. This mean
             // that we should handle non-exhaustive SingleVariant the same way we would handle
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index c804dc5e7fb..6cc7e82bbf7 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -37,8 +37,8 @@ use crate::method::probe::IsSuggestion;
 use crate::method::probe::Mode::MethodCall;
 use crate::method::probe::ProbeScope::TraitsInScope;
 use crate::{
-    BreakableCtxt, Diverges, Expectation, FnCtxt, LoweredTy, Needs, TupleArgumentsFlag, errors,
-    struct_span_code_err,
+    BreakableCtxt, Diverges, Expectation, FnCtxt, GatherLocalsVisitor, LoweredTy, Needs,
+    TupleArgumentsFlag, errors, struct_span_code_err,
 };
 
 rustc_index::newtype_index! {
@@ -1765,6 +1765,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// Type check a `let` statement.
     fn check_decl_local(&self, local: &'tcx hir::LetStmt<'tcx>) {
+        GatherLocalsVisitor::gather_from_local(self, local);
+
         let ty = self.check_decl(local.into());
         self.write_ty(local.hir_id, ty);
         if local.pat.is_never_pattern() {
diff --git a/compiler/rustc_hir_typeck/src/gather_locals.rs b/compiler/rustc_hir_typeck/src/gather_locals.rs
index 5d87e800096..a8bbc89dbde 100644
--- a/compiler/rustc_hir_typeck/src/gather_locals.rs
+++ b/compiler/rustc_hir_typeck/src/gather_locals.rs
@@ -55,6 +55,14 @@ impl<'a> From<(&'a hir::LetExpr<'a>, HirId)> for Declaration<'a> {
     }
 }
 
+/// The `GatherLocalsVisitor` is responsible for initializing local variable types
+/// in the [`ty::TypeckResults`] for all subpatterns in statements and expressions
+/// like `let`, `match`, and params of function bodies. It also adds `Sized` bounds
+/// for these types (with exceptions for unsized feature gates like `unsized_fn_params`).
+///
+/// Failure to visit locals will cause an ICE in writeback when the local's type is
+/// resolved. Visiting locals twice will ICE in the `GatherLocalsVisitor`, since it
+/// will overwrite the type previously stored in the local.
 pub(super) struct GatherLocalsVisitor<'a, 'tcx> {
     fcx: &'a FnCtxt<'a, 'tcx>,
     // parameters are special cases of patterns, but we want to handle them as
@@ -63,9 +71,37 @@ pub(super) struct GatherLocalsVisitor<'a, 'tcx> {
     outermost_fn_param_pat: Option<(Span, HirId)>,
 }
 
+// N.B. additional `gather_*` functions should be careful to only walk the pattern
+// for new expressions, since visiting sub-expressions or nested bodies may initialize
+// locals which are not conceptually owned by the gathered statement or expression.
 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
-    pub(super) fn new(fcx: &'a FnCtxt<'a, 'tcx>) -> Self {
-        Self { fcx, outermost_fn_param_pat: None }
+    pub(crate) fn gather_from_local(fcx: &'a FnCtxt<'a, 'tcx>, local: &'tcx hir::LetStmt<'tcx>) {
+        let mut visitor = GatherLocalsVisitor { fcx, outermost_fn_param_pat: None };
+        visitor.declare(local.into());
+        visitor.visit_pat(local.pat);
+    }
+
+    pub(crate) fn gather_from_let_expr(
+        fcx: &'a FnCtxt<'a, 'tcx>,
+        let_expr: &'tcx hir::LetExpr<'tcx>,
+        expr_hir_id: hir::HirId,
+    ) {
+        let mut visitor = GatherLocalsVisitor { fcx, outermost_fn_param_pat: None };
+        visitor.declare((let_expr, expr_hir_id).into());
+        visitor.visit_pat(let_expr.pat);
+    }
+
+    pub(crate) fn gather_from_param(fcx: &'a FnCtxt<'a, 'tcx>, param: &'tcx hir::Param<'tcx>) {
+        let mut visitor = GatherLocalsVisitor {
+            fcx,
+            outermost_fn_param_pat: Some((param.ty_span, param.hir_id)),
+        };
+        visitor.visit_pat(param.pat);
+    }
+
+    pub(crate) fn gather_from_arm(fcx: &'a FnCtxt<'a, 'tcx>, local: &'tcx hir::Arm<'tcx>) {
+        let mut visitor = GatherLocalsVisitor { fcx, outermost_fn_param_pat: None };
+        visitor.visit_pat(local.pat);
     }
 
     fn assign(&mut self, span: Span, nid: HirId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
@@ -73,12 +109,12 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
             None => {
                 // Infer the variable's type.
                 let var_ty = self.fcx.next_ty_var(span);
-                self.fcx.locals.borrow_mut().insert(nid, var_ty);
+                assert_eq!(self.fcx.locals.borrow_mut().insert(nid, var_ty), None);
                 var_ty
             }
             Some(typ) => {
                 // Take type that the user specified.
-                self.fcx.locals.borrow_mut().insert(nid, typ);
+                assert_eq!(self.fcx.locals.borrow_mut().insert(nid, typ), None);
                 typ
             }
         }
@@ -133,13 +169,6 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
         intravisit::walk_expr(self, expr)
     }
 
-    fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
-        let old_outermost_fn_param_pat =
-            self.outermost_fn_param_pat.replace((param.ty_span, param.hir_id));
-        intravisit::walk_param(self, param);
-        self.outermost_fn_param_pat = old_outermost_fn_param_pat;
-    }
-
     // Add pattern bindings.
     fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
         if let PatKind::Binding(_, _, ident, _) = p.kind {
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index d861a4f81b0..60187abd558 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -32,6 +32,7 @@ mod gather_locals;
 mod intrinsicck;
 mod method;
 mod op;
+mod opaque_types;
 mod pat;
 mod place_op;
 mod rvalue_scopes;
@@ -46,7 +47,6 @@ use rustc_errors::codes::*;
 use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::intravisit::Visitor;
 use rustc_hir::{HirId, HirIdMap, Node};
 use rustc_hir_analysis::check::check_abi;
 use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
@@ -191,9 +191,6 @@ fn typeck_with_inspect<'tcx>(
         let wf_code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(def_id)));
         fcx.register_wf_obligation(expected_type.into(), body.value.span, wf_code);
 
-        // Gather locals in statics (because of block expressions).
-        GatherLocalsVisitor::new(&fcx).visit_body(body);
-
         fcx.check_expr_coercible_to_type(body.value, expected_type, None);
 
         fcx.write_ty(id, expected_type);
@@ -249,9 +246,7 @@ fn typeck_with_inspect<'tcx>(
 
     let typeck_results = fcx.resolve_type_vars_in_body(body);
 
-    // We clone the defined opaque types during writeback in the new solver
-    // because we have to use them during normalization.
-    let _ = fcx.infcx.take_opaque_types();
+    fcx.detect_opaque_types_added_during_writeback();
 
     // Consistency check our TypeckResults instance can hold all ItemLocalIds
     // it will need to hold.
diff --git a/compiler/rustc_hir_typeck/src/opaque_types.rs b/compiler/rustc_hir_typeck/src/opaque_types.rs
new file mode 100644
index 00000000000..e0224f8c6e1
--- /dev/null
+++ b/compiler/rustc_hir_typeck/src/opaque_types.rs
@@ -0,0 +1,26 @@
+use super::FnCtxt;
+impl<'tcx> FnCtxt<'_, 'tcx> {
+    /// We may in theory add further uses of an opaque after cloning the opaque
+    /// types storage during writeback when computing the defining uses.
+    ///
+    /// Silently ignoring them is dangerous and could result in ICE or even in
+    /// unsoundness, so we make sure we catch such cases here. There's currently
+    /// no known code where this actually happens, even with the new solver which
+    /// does normalize types in writeback after cloning the opaque type storage.
+    ///
+    /// FIXME(@lcnr): I believe this should be possible in theory and would like
+    /// an actual test here. After playing around with this for an hour, I wasn't
+    /// able to do anything which didn't already try to normalize the opaque before
+    /// then, either allowing compilation to succeed or causing an ambiguity error.
+    pub(super) fn detect_opaque_types_added_during_writeback(&self) {
+        let num_entries = self.checked_opaque_types_storage_entries.take().unwrap();
+        for (key, hidden_type) in
+            self.inner.borrow_mut().opaque_types().opaque_types_added_since(num_entries)
+        {
+            let opaque_type_string = self.tcx.def_path_str(key.def_id);
+            let msg = format!("unexpected cyclic definition of `{opaque_type_string}`");
+            self.dcx().span_delayed_bug(hidden_type.span, msg);
+        }
+        let _ = self.take_opaque_types();
+    }
+}
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 7520782930a..17d48184dd9 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -177,16 +177,20 @@ enum PeelKind {
     /// Only peel reference types. This is used for explicit `deref!(_)` patterns, which dereference
     /// any number of `&`/`&mut` references, plus a single smart pointer.
     ExplicitDerefPat,
-    /// Implicitly peel any number of references, and if `deref_patterns` is enabled, smart pointer
-    /// ADTs. In order to peel only as much as necessary for the pattern to match, the `until_adt`
-    /// field contains the ADT def that the pattern is a constructor for, if applicable, so that we
-    /// don't peel it. See [`ResolvedPat`] for more information.
-    Implicit { until_adt: Option<DefId> },
+    /// Implicitly peel references, and if `deref_patterns` is enabled, smart pointer ADTs.
+    Implicit {
+        /// The ADT the pattern is a constructor for, if applicable, so that we don't peel it. See
+        /// [`ResolvedPat`] for more information.
+        until_adt: Option<DefId>,
+        /// The number of references at the head of the pattern's type, so we can leave that many
+        /// untouched. This is `1` for string literals, and `0` for most patterns.
+        pat_ref_layers: usize,
+    },
 }
 
 impl AdjustMode {
     const fn peel_until_adt(opt_adt_def: Option<DefId>) -> AdjustMode {
-        AdjustMode::Peel { kind: PeelKind::Implicit { until_adt: opt_adt_def } }
+        AdjustMode::Peel { kind: PeelKind::Implicit { until_adt: opt_adt_def, pat_ref_layers: 0 } }
     }
     const fn peel_all() -> AdjustMode {
         AdjustMode::peel_until_adt(None)
@@ -488,9 +492,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         match pat.kind {
             // Peel off a `&` or `&mut` from the scrutinee type. See the examples in
             // `tests/ui/rfcs/rfc-2005-default-binding-mode`.
-            _ if let AdjustMode::Peel { .. } = adjust_mode
+            _ if let AdjustMode::Peel { kind: peel_kind } = adjust_mode
                 && pat.default_binding_modes
-                && let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() =>
+                && let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind()
+                && self.should_peel_ref(peel_kind, expected) =>
             {
                 debug!("inspecting {:?}", expected);
 
@@ -531,24 +536,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // If `deref_patterns` is enabled, peel a smart pointer from the scrutinee type. See the
             // examples in `tests/ui/pattern/deref_patterns/`.
             _ if self.tcx.features().deref_patterns()
-                && let AdjustMode::Peel { kind: PeelKind::Implicit { until_adt } } = adjust_mode
+                && let AdjustMode::Peel { kind: peel_kind } = adjust_mode
                 && pat.default_binding_modes
-                // For simplicity, only apply overloaded derefs if `expected` is a known ADT.
-                // FIXME(deref_patterns): we'll get better diagnostics for users trying to
-                // implicitly deref generics if we allow them here, but primitives, tuples, and
-                // inference vars definitely should be stopped. Figure out what makes most sense.
-                && let ty::Adt(scrutinee_adt, _) = *expected.kind()
-                // Don't peel if the pattern type already matches the scrutinee. E.g., stop here if
-                // matching on a `Cow<'a, T>` scrutinee with a `Cow::Owned(_)` pattern.
-                && until_adt != Some(scrutinee_adt.did())
-                // At this point, the pattern isn't able to match `expected` without peeling. Check
-                // that it implements `Deref` before assuming it's a smart pointer, to get a normal
-                // type error instead of a missing impl error if not. This only checks for `Deref`,
-                // not `DerefPure`: we require that too, but we want a trait error if it's missing.
-                && let Some(deref_trait) = self.tcx.lang_items().deref_trait()
-                && self
-                    .type_implements_trait(deref_trait, [expected], self.param_env)
-                    .may_apply() =>
+                && self.should_peel_smart_pointer(peel_kind, expected) =>
             {
                 debug!("scrutinee ty {expected:?} is a smart pointer, inserting overloaded deref");
                 // The scrutinee is a smart pointer; implicitly dereference it. This adds a
@@ -660,14 +650,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         match &pat.kind {
             // Type checking these product-like types successfully always require
             // that the expected type be of those types and not reference types.
-            PatKind::Tuple(..)
-            | PatKind::Range(..)
-            | PatKind::Slice(..) => AdjustMode::peel_all(),
+            PatKind::Tuple(..) | PatKind::Range(..) | PatKind::Slice(..) => AdjustMode::peel_all(),
             // When checking an explicit deref pattern, only peel reference types.
             // FIXME(deref_patterns): If box patterns and deref patterns need to coexist, box
             // patterns may want `PeelKind::Implicit`, stopping on encountering a box.
-            | PatKind::Box(_)
-            | PatKind::Deref(_) => AdjustMode::Peel { kind: PeelKind::ExplicitDerefPat },
+            PatKind::Box(_) | PatKind::Deref(_) => {
+                AdjustMode::Peel { kind: PeelKind::ExplicitDerefPat }
+            }
             // A never pattern behaves somewhat like a literal or unit variant.
             PatKind::Never => AdjustMode::peel_all(),
             // For patterns with paths, how we peel the scrutinee depends on the path's resolution.
@@ -680,23 +669,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             // String and byte-string literals result in types `&str` and `&[u8]` respectively.
             // All other literals result in non-reference types.
-            // As a result, we allow `if let 0 = &&0 {}` but not `if let "foo" = &&"foo" {}`.
-            //
-            // Call `resolve_vars_if_possible` here for inline const blocks.
-            PatKind::Expr(lt) => match self.resolve_vars_if_possible(self.check_pat_expr_unadjusted(lt)).kind() {
-                ty::Ref(..) => AdjustMode::Pass,
-                _ => {
-                    // Path patterns have already been handled, and inline const blocks currently
-                    // aren't possible to write, so any handling for them would be untested.
-                    if cfg!(debug_assertions)
-                        && self.tcx.features().deref_patterns()
-                        && !matches!(lt.kind, PatExprKind::Lit { .. })
+            // As a result, we allow `if let 0 = &&0 {}` but not `if let "foo" = &&"foo" {}` unless
+            // `deref_patterns` is enabled.
+            PatKind::Expr(lt) => {
+                // Path patterns have already been handled, and inline const blocks currently
+                // aren't possible to write, so any handling for them would be untested.
+                if cfg!(debug_assertions)
+                    && self.tcx.features().deref_patterns()
+                    && !matches!(lt.kind, PatExprKind::Lit { .. })
+                {
+                    span_bug!(
+                        lt.span,
+                        "FIXME(deref_patterns): adjust mode unimplemented for {:?}",
+                        lt.kind
+                    );
+                }
+                // Call `resolve_vars_if_possible` here for inline const blocks.
+                let lit_ty = self.resolve_vars_if_possible(self.check_pat_expr_unadjusted(lt));
+                // If `deref_patterns` is enabled, allow `if let "foo" = &&"foo" {}`.
+                if self.tcx.features().deref_patterns() {
+                    let mut peeled_ty = lit_ty;
+                    let mut pat_ref_layers = 0;
+                    while let ty::Ref(_, inner_ty, mutbl) =
+                        *self.try_structurally_resolve_type(pat.span, peeled_ty).kind()
                     {
-                        span_bug!(lt.span, "FIXME(deref_patterns): adjust mode unimplemented for {:?}", lt.kind);
+                        // We rely on references at the head of constants being immutable.
+                        debug_assert!(mutbl.is_not());
+                        pat_ref_layers += 1;
+                        peeled_ty = inner_ty;
                     }
-                    AdjustMode::peel_all()
+                    AdjustMode::Peel {
+                        kind: PeelKind::Implicit { until_adt: None, pat_ref_layers },
+                    }
+                } else {
+                    if lit_ty.is_ref() { AdjustMode::Pass } else { AdjustMode::peel_all() }
                 }
-            },
+            }
 
             // Ref patterns are complicated, we handle them in `check_pat_ref`.
             PatKind::Ref(..)
@@ -720,6 +728,67 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
+    /// Assuming `expected` is a reference type, determine whether to peel it before matching.
+    fn should_peel_ref(&self, peel_kind: PeelKind, mut expected: Ty<'tcx>) -> bool {
+        debug_assert!(expected.is_ref());
+        let pat_ref_layers = match peel_kind {
+            PeelKind::ExplicitDerefPat => 0,
+            PeelKind::Implicit { pat_ref_layers, .. } => pat_ref_layers,
+        };
+
+        // Most patterns don't have reference types, so we'll want to peel all references from the
+        // scrutinee before matching. To optimize for the common case, return early.
+        if pat_ref_layers == 0 {
+            return true;
+        }
+        debug_assert!(
+            self.tcx.features().deref_patterns(),
+            "Peeling for patterns with reference types is gated by `deref_patterns`."
+        );
+
+        // If the pattern has as many or more layers of reference as the expected type, we can match
+        // without peeling more, unless we find a smart pointer or `&mut` that we also need to peel.
+        // We don't treat `&` and `&mut` as interchangeable, but by peeling `&mut`s before matching,
+        // we can still, e.g., match on a `&mut str` with a string literal pattern. This is because
+        // string literal patterns may be used where `str` is expected.
+        let mut expected_ref_layers = 0;
+        while let ty::Ref(_, inner_ty, mutbl) = *expected.kind() {
+            if mutbl.is_mut() {
+                // Mutable references can't be in the final value of constants, thus they can't be
+                // at the head of their types, thus we should always peel `&mut`.
+                return true;
+            }
+            expected_ref_layers += 1;
+            expected = inner_ty;
+        }
+        pat_ref_layers < expected_ref_layers || self.should_peel_smart_pointer(peel_kind, expected)
+    }
+
+    /// Determine whether `expected` is a smart pointer type that should be peeled before matching.
+    fn should_peel_smart_pointer(&self, peel_kind: PeelKind, expected: Ty<'tcx>) -> bool {
+        // Explicit `deref!(_)` patterns match against smart pointers; don't peel in that case.
+        if let PeelKind::Implicit { until_adt, .. } = peel_kind
+            // For simplicity, only apply overloaded derefs if `expected` is a known ADT.
+            // FIXME(deref_patterns): we'll get better diagnostics for users trying to
+            // implicitly deref generics if we allow them here, but primitives, tuples, and
+            // inference vars definitely should be stopped. Figure out what makes most sense.
+            && let ty::Adt(scrutinee_adt, _) = *expected.kind()
+            // Don't peel if the pattern type already matches the scrutinee. E.g., stop here if
+            // matching on a `Cow<'a, T>` scrutinee with a `Cow::Owned(_)` pattern.
+            && until_adt != Some(scrutinee_adt.did())
+            // At this point, the pattern isn't able to match `expected` without peeling. Check
+            // that it implements `Deref` before assuming it's a smart pointer, to get a normal
+            // type error instead of a missing impl error if not. This only checks for `Deref`,
+            // not `DerefPure`: we require that too, but we want a trait error if it's missing.
+            && let Some(deref_trait) = self.tcx.lang_items().deref_trait()
+            && self.type_implements_trait(deref_trait, [expected], self.param_env).may_apply()
+        {
+            true
+        } else {
+            false
+        }
+    }
+
     fn check_pat_expr_unadjusted(&self, lt: &'tcx hir::PatExpr<'tcx>) -> Ty<'tcx> {
         let ty = match &lt.kind {
             rustc_hir::PatExprKind::Lit { lit, negated } => {
@@ -866,6 +935,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // be peeled to `str` while ty here is still `&str`, if we don't
                 // err early here, a rather confusing unification error will be
                 // emitted instead).
+                let ty = self.try_structurally_resolve_type(expr.span, ty);
                 let fail =
                     !(ty.is_numeric() || ty.is_char() || ty.is_ty_var() || ty.references_error());
                 Some((fail, ty, expr.span))
diff --git a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
index 56859eef45f..26be5fc6d19 100644
--- a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
+++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
@@ -1,10 +1,10 @@
-use std::cell::RefCell;
+use std::cell::{Cell, RefCell};
 use std::ops::Deref;
 
 use rustc_data_structures::unord::{UnordMap, UnordSet};
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::{self as hir, HirId, HirIdMap, LangItem};
-use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
+use rustc_infer::infer::{InferCtxt, InferOk, OpaqueTypeStorageEntries, TyCtxtInferExt};
 use rustc_middle::span_bug;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypingMode};
 use rustc_span::Span;
@@ -37,6 +37,11 @@ pub(crate) struct TypeckRootCtxt<'tcx> {
 
     pub(super) fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx, FulfillmentError<'tcx>>>>,
 
+    // Used to detect opaque types uses added after we've already checked them.
+    //
+    // See [FnCtxt::detect_opaque_types_added_during_writeback] for more details.
+    pub(super) checked_opaque_types_storage_entries: Cell<Option<OpaqueTypeStorageEntries>>,
+
     /// Some additional `Sized` obligations badly affect type inference.
     /// These obligations are added in a later stage of typeck.
     /// Removing these may also cause additional complications, see #101066.
@@ -85,12 +90,14 @@ impl<'tcx> TypeckRootCtxt<'tcx> {
         let infcx =
             tcx.infer_ctxt().ignoring_regions().build(TypingMode::typeck_for_body(tcx, def_id));
         let typeck_results = RefCell::new(ty::TypeckResults::new(hir_owner));
+        let fulfillment_cx = RefCell::new(<dyn TraitEngine<'_, _>>::new(&infcx));
 
         TypeckRootCtxt {
-            typeck_results,
-            fulfillment_cx: RefCell::new(<dyn TraitEngine<'_, _>>::new(&infcx)),
             infcx,
+            typeck_results,
             locals: RefCell::new(Default::default()),
+            fulfillment_cx,
+            checked_opaque_types_storage_entries: Cell::new(None),
             deferred_sized_obligations: RefCell::new(Vec::new()),
             deferred_call_resolutions: RefCell::new(Default::default()),
             deferred_cast_checks: RefCell::new(Vec::new()),
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index 4a171a08ef7..9be041f75d7 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -535,13 +535,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         let tcx = self.tcx();
         // We clone the opaques instead of stealing them here as they are still used for
         // normalization in the next generation trait solver.
-        //
-        // FIXME(-Znext-solver): Opaque types defined after this would simply get dropped
-        // at the end of typeck. While this seems unlikely to happen in practice this
-        // should still get fixed. Either by preventing writeback from defining new opaque
-        // types or by using this function at the end of writeback and running it as a
-        // fixpoint.
         let opaque_types = self.fcx.infcx.clone_opaque_types();
+        let num_entries = self.fcx.inner.borrow_mut().opaque_types().num_entries();
+        let prev = self.fcx.checked_opaque_types_storage_entries.replace(Some(num_entries));
+        debug_assert_eq!(prev, None);
         for (opaque_type_key, hidden_type) in opaque_types {
             let hidden_type = self.resolve(hidden_type, &hidden_type.span);
             let opaque_type_key = self.resolve(opaque_type_key, &hidden_type.span);
@@ -555,15 +552,16 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                 }
             }
 
-            if let Err(guar) = check_opaque_type_parameter_valid(
+            if let Err(err) = check_opaque_type_parameter_valid(
                 &self.fcx,
                 opaque_type_key,
                 hidden_type.span,
                 DefiningScopeKind::HirTypeck,
             ) {
-                self.typeck_results
-                    .concrete_opaque_types
-                    .insert(opaque_type_key.def_id, ty::OpaqueHiddenType::new_error(tcx, guar));
+                self.typeck_results.concrete_opaque_types.insert(
+                    opaque_type_key.def_id,
+                    ty::OpaqueHiddenType::new_error(tcx, err.report(self.fcx)),
+                );
             }
 
             let hidden_type = hidden_type.remap_generic_params_to_declaration_params(
diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs
index 1b2056f541f..0e04a2a784e 100644
--- a/compiler/rustc_incremental/src/assert_dep_graph.rs
+++ b/compiler/rustc_incremental/src/assert_dep_graph.rs
@@ -38,7 +38,7 @@ use std::fs::{self, File};
 use std::io::Write;
 
 use rustc_data_structures::fx::FxIndexSet;
-use rustc_data_structures::graph::implementation::{Direction, INCOMING, NodeIndex, OUTGOING};
+use rustc_data_structures::graph::linked_graph::{Direction, INCOMING, NodeIndex, OUTGOING};
 use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_middle::dep_graph::{
diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs
index 94ce6d9fa81..58fea3278a8 100644
--- a/compiler/rustc_incremental/src/persist/save.rs
+++ b/compiler/rustc_incremental/src/persist/save.rs
@@ -44,10 +44,6 @@ pub(crate) fn save_dep_graph(tcx: TyCtxt<'_>) {
         sess.time("assert_dep_graph", || assert_dep_graph(tcx));
         sess.time("check_dirty_clean", || dirty_clean::check_dirty_clean_annotations(tcx));
 
-        if sess.opts.unstable_opts.incremental_info {
-            tcx.dep_graph.print_incremental_info()
-        }
-
         join(
             move || {
                 sess.time("incr_comp_persist_dep_graph", || {
@@ -172,12 +168,5 @@ pub(crate) fn build_dep_graph(
     // First encode the commandline arguments hash
     sess.opts.dep_tracking_hash(false).encode(&mut encoder);
 
-    Some(DepGraph::new(
-        sess,
-        prev_graph,
-        prev_work_products,
-        encoder,
-        sess.opts.unstable_opts.query_dep_graph,
-        sess.opts.unstable_opts.incremental_info,
-    ))
+    Some(DepGraph::new(sess, prev_graph, prev_work_products, encoder))
 }
diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index 5220071c500..1ae864c454f 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -132,7 +132,13 @@ impl<'tcx> InferCtxt<'tcx> {
 
         let certainty = if errors.is_empty() { Certainty::Proven } else { Certainty::Ambiguous };
 
-        let opaque_types = self.take_opaque_types_for_query_response();
+        let opaque_types = self
+            .inner
+            .borrow_mut()
+            .opaque_type_storage
+            .take_opaque_types()
+            .map(|(k, v)| (k, v.ty))
+            .collect();
 
         Ok(QueryResponse {
             var_values: inference_vars,
@@ -143,24 +149,6 @@ impl<'tcx> InferCtxt<'tcx> {
         })
     }
 
-    /// Used by the new solver as that one takes the opaque types at the end of a probe
-    /// to deal with multiple candidates without having to recompute them.
-    pub fn clone_opaque_types_for_query_response(
-        &self,
-    ) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
-        self.inner
-            .borrow()
-            .opaque_type_storage
-            .opaque_types
-            .iter()
-            .map(|(k, v)| (*k, v.ty))
-            .collect()
-    }
-
-    fn take_opaque_types_for_query_response(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
-        self.take_opaque_types().into_iter().map(|(k, v)| (k, v.ty)).collect()
-    }
-
     /// Given the (canonicalized) result to a canonical query,
     /// instantiates the result so it can be used, plugging in the
     /// values from the canonical query. (Note that the result may
diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs
index 75affa13977..359b9da11ce 100644
--- a/compiler/rustc_infer/src/infer/context.rs
+++ b/compiler/rustc_infer/src/infer/context.rs
@@ -6,7 +6,10 @@ use rustc_middle::ty::relate::combine::PredicateEmittingRelation;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
 
-use super::{BoundRegionConversionTime, InferCtxt, RegionVariableOrigin, SubregionOrigin};
+use super::{
+    BoundRegionConversionTime, InferCtxt, OpaqueTypeStorageEntries, RegionVariableOrigin,
+    SubregionOrigin,
+};
 
 impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
     type Interner = TyCtxt<'tcx>;
@@ -121,19 +124,19 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
         self.enter_forall(value, f)
     }
 
-    fn equate_ty_vids_raw(&self, a: rustc_type_ir::TyVid, b: rustc_type_ir::TyVid) {
+    fn equate_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid) {
         self.inner.borrow_mut().type_variables().equate(a, b);
     }
 
-    fn equate_int_vids_raw(&self, a: rustc_type_ir::IntVid, b: rustc_type_ir::IntVid) {
+    fn equate_int_vids_raw(&self, a: ty::IntVid, b: ty::IntVid) {
         self.inner.borrow_mut().int_unification_table().union(a, b);
     }
 
-    fn equate_float_vids_raw(&self, a: rustc_type_ir::FloatVid, b: rustc_type_ir::FloatVid) {
+    fn equate_float_vids_raw(&self, a: ty::FloatVid, b: ty::FloatVid) {
         self.inner.borrow_mut().float_unification_table().union(a, b);
     }
 
-    fn equate_const_vids_raw(&self, a: rustc_type_ir::ConstVid, b: rustc_type_ir::ConstVid) {
+    fn equate_const_vids_raw(&self, a: ty::ConstVid, b: ty::ConstVid) {
         self.inner.borrow_mut().const_unification_table().union(a, b);
     }
 
@@ -141,8 +144,8 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
         &self,
         relation: &mut R,
         target_is_expected: bool,
-        target_vid: rustc_type_ir::TyVid,
-        instantiation_variance: rustc_type_ir::Variance,
+        target_vid: ty::TyVid,
+        instantiation_variance: ty::Variance,
         source_ty: Ty<'tcx>,
     ) -> RelateResult<'tcx, ()> {
         self.instantiate_ty_var(
@@ -154,19 +157,11 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
         )
     }
 
-    fn instantiate_int_var_raw(
-        &self,
-        vid: rustc_type_ir::IntVid,
-        value: rustc_type_ir::IntVarValue,
-    ) {
+    fn instantiate_int_var_raw(&self, vid: ty::IntVid, value: ty::IntVarValue) {
         self.inner.borrow_mut().int_unification_table().union_value(vid, value);
     }
 
-    fn instantiate_float_var_raw(
-        &self,
-        vid: rustc_type_ir::FloatVid,
-        value: rustc_type_ir::FloatVarValue,
-    ) {
+    fn instantiate_float_var_raw(&self, vid: ty::FloatVid, value: ty::FloatVarValue) {
         self.inner.borrow_mut().float_unification_table().union_value(vid, value);
     }
 
@@ -174,7 +169,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
         &self,
         relation: &mut R,
         target_is_expected: bool,
-        target_vid: rustc_type_ir::ConstVid,
+        target_vid: ty::ConstVid,
         source_ct: ty::Const<'tcx>,
     ) -> RelateResult<'tcx, ()> {
         self.instantiate_const_var(relation, target_is_expected, target_vid, source_ct)
@@ -221,4 +216,58 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
     fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>, span: Span) {
         self.register_region_obligation_with_cause(ty, r, &ObligationCause::dummy_with_span(span));
     }
+
+    type OpaqueTypeStorageEntries = OpaqueTypeStorageEntries;
+    fn opaque_types_storage_num_entries(&self) -> OpaqueTypeStorageEntries {
+        self.inner.borrow_mut().opaque_types().num_entries()
+    }
+    fn clone_opaque_types_lookup_table(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
+        self.inner.borrow_mut().opaque_types().iter_lookup_table().map(|(k, h)| (k, h.ty)).collect()
+    }
+    fn clone_duplicate_opaque_types(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
+        self.inner
+            .borrow_mut()
+            .opaque_types()
+            .iter_duplicate_entries()
+            .map(|(k, h)| (k, h.ty))
+            .collect()
+    }
+    fn clone_opaque_types_added_since(
+        &self,
+        prev_entries: OpaqueTypeStorageEntries,
+    ) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
+        self.inner
+            .borrow_mut()
+            .opaque_types()
+            .opaque_types_added_since(prev_entries)
+            .map(|(k, h)| (k, h.ty))
+            .collect()
+    }
+
+    fn register_hidden_type_in_storage(
+        &self,
+        opaque_type_key: ty::OpaqueTypeKey<'tcx>,
+        hidden_ty: Ty<'tcx>,
+        span: Span,
+    ) -> Option<Ty<'tcx>> {
+        self.register_hidden_type_in_storage(
+            opaque_type_key,
+            ty::OpaqueHiddenType { span, ty: hidden_ty },
+        )
+    }
+    fn add_duplicate_opaque_type(
+        &self,
+        opaque_type_key: ty::OpaqueTypeKey<'tcx>,
+        hidden_ty: Ty<'tcx>,
+        span: Span,
+    ) {
+        self.inner
+            .borrow_mut()
+            .opaque_types()
+            .add_duplicate(opaque_type_key, ty::OpaqueHiddenType { span, ty: hidden_ty })
+    }
+
+    fn reset_opaque_types(&self) {
+        let _ = self.take_opaque_types();
+    }
 }
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index e3522137d83..2185886901e 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -3,8 +3,8 @@
 use std::fmt;
 
 use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::graph::implementation::{
-    Direction, Graph, INCOMING, NodeIndex, OUTGOING,
+use rustc_data_structures::graph::linked_graph::{
+    Direction, INCOMING, LinkedGraph, NodeIndex, OUTGOING,
 };
 use rustc_data_structures::intern::Interned;
 use rustc_data_structures::unord::UnordSet;
@@ -118,7 +118,7 @@ struct RegionAndOrigin<'tcx> {
     origin: SubregionOrigin<'tcx>,
 }
 
-type RegionGraph<'tcx> = Graph<(), Constraint<'tcx>>;
+type RegionGraph<'tcx> = LinkedGraph<(), Constraint<'tcx>>;
 
 struct LexicalResolver<'cx, 'tcx> {
     region_rels: &'cx RegionRelations<'cx, 'tcx>,
@@ -668,7 +668,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
     fn construct_graph(&self) -> RegionGraph<'tcx> {
         let num_vars = self.num_vars();
 
-        let mut graph = Graph::new();
+        let mut graph = LinkedGraph::new();
 
         for _ in 0..num_vars {
             graph.add_node(());
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index d25542dadd5..b408d76010d 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -9,7 +9,7 @@ use free_regions::RegionRelations;
 pub use freshen::TypeFreshener;
 use lexical_region_resolve::LexicalRegionResolutions;
 pub use lexical_region_resolve::RegionResolutionError;
-use opaque_types::OpaqueTypeStorage;
+pub use opaque_types::{OpaqueTypeStorage, OpaqueTypeStorageEntries, OpaqueTypeTable};
 use region_constraints::{
     GenericKind, RegionConstraintCollector, RegionConstraintStorage, VarInfos, VerifyBound,
 };
@@ -31,9 +31,9 @@ use rustc_middle::traits::solve::Goal;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::{
     self, BoundVarReplacerDelegate, ConstVid, FloatVid, GenericArg, GenericArgKind, GenericArgs,
-    GenericArgsRef, GenericParamDefKind, InferConst, IntVid, PseudoCanonicalInput, Term, TermKind,
-    Ty, TyCtxt, TyVid, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable,
-    TypeVisitableExt, TypingEnv, TypingMode, fold_regions,
+    GenericArgsRef, GenericParamDefKind, InferConst, IntVid, OpaqueHiddenType, OpaqueTypeKey,
+    PseudoCanonicalInput, Term, TermKind, Ty, TyCtxt, TyVid, TypeFoldable, TypeFolder,
+    TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypingEnv, TypingMode, fold_regions,
 };
 use rustc_span::{Span, Symbol};
 use snapshot::undo_log::InferCtxtUndoLogs;
@@ -198,7 +198,7 @@ impl<'tcx> InferCtxtInner<'tcx> {
     }
 
     #[inline]
-    fn opaque_types(&mut self) -> opaque_types::OpaqueTypeTable<'_, 'tcx> {
+    pub fn opaque_types(&mut self) -> opaque_types::OpaqueTypeTable<'_, 'tcx> {
         self.opaque_type_storage.with_log(&mut self.undo_log)
     }
 
@@ -224,15 +224,6 @@ impl<'tcx> InferCtxtInner<'tcx> {
             .expect("region constraints already solved")
             .with_log(&mut self.undo_log)
     }
-
-    // Iterates through the opaque type definitions without taking them; this holds the
-    // `InferCtxtInner` lock, so make sure to not do anything with `InferCtxt` side-effects
-    // while looping through this.
-    pub fn iter_opaque_types(
-        &self,
-    ) -> impl Iterator<Item = (ty::OpaqueTypeKey<'tcx>, ty::OpaqueHiddenType<'tcx>)> {
-        self.opaque_type_storage.opaque_types.iter().map(|(&k, &v)| (k, v))
-    }
 }
 
 pub struct InferCtxt<'tcx> {
@@ -954,13 +945,13 @@ impl<'tcx> InferCtxt<'tcx> {
     }
 
     #[instrument(level = "debug", skip(self), ret)]
-    pub fn take_opaque_types(&self) -> opaque_types::OpaqueTypeMap<'tcx> {
-        std::mem::take(&mut self.inner.borrow_mut().opaque_type_storage.opaque_types)
+    pub fn take_opaque_types(&self) -> Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
+        self.inner.borrow_mut().opaque_type_storage.take_opaque_types().collect()
     }
 
     #[instrument(level = "debug", skip(self), ret)]
-    pub fn clone_opaque_types(&self) -> opaque_types::OpaqueTypeMap<'tcx> {
-        self.inner.borrow().opaque_type_storage.opaque_types.clone()
+    pub fn clone_opaque_types(&self) -> Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
+        self.inner.borrow_mut().opaque_type_storage.iter_opaque_types().collect()
     }
 
     #[inline(always)]
diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
index ce5d2e6e17a..220d5e9bda2 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
@@ -1,5 +1,4 @@
 use hir::def_id::{DefId, LocalDefId};
-use rustc_data_structures::fx::FxIndexMap;
 use rustc_hir as hir;
 use rustc_middle::bug;
 use rustc_middle::traits::ObligationCause;
@@ -19,8 +18,7 @@ use crate::traits::{self, Obligation, PredicateObligations};
 
 mod table;
 
-pub(crate) type OpaqueTypeMap<'tcx> = FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>;
-pub(crate) use table::{OpaqueTypeStorage, OpaqueTypeTable};
+pub use table::{OpaqueTypeStorage, OpaqueTypeStorageEntries, OpaqueTypeTable};
 
 impl<'tcx> InferCtxt<'tcx> {
     /// This is a backwards compatibility hack to prevent breaking changes from
diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs
index ba6cc0d783d..46752840e1b 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/table.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs
@@ -1,18 +1,27 @@
+use std::ops::Deref;
+
+use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::undo_log::UndoLogs;
 use rustc_middle::bug;
 use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty};
 use tracing::instrument;
 
-use super::OpaqueTypeMap;
 use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, UndoLog};
 
 #[derive(Default, Debug, Clone)]
-pub(crate) struct OpaqueTypeStorage<'tcx> {
-    /// Opaque types found in explicit return types and their
-    /// associated fresh inference variable. Writeback resolves these
-    /// variables to get the concrete type, which can be used to
-    /// 'de-opaque' OpaqueHiddenType, after typeck is done with all functions.
-    pub opaque_types: OpaqueTypeMap<'tcx>,
+pub struct OpaqueTypeStorage<'tcx> {
+    opaque_types: FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
+    duplicate_entries: Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)>,
+}
+
+/// The number of entries in the opaque type storage at a given point.
+///
+/// Used to check that we haven't added any new opaque types after checking
+/// the opaque types currently in the storage.
+#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
+pub struct OpaqueTypeStorageEntries {
+    opaque_types: usize,
+    duplicate_entries: usize,
 }
 
 impl<'tcx> OpaqueTypeStorage<'tcx> {
@@ -33,6 +42,70 @@ impl<'tcx> OpaqueTypeStorage<'tcx> {
         }
     }
 
+    pub(crate) fn pop_duplicate_entry(&mut self) {
+        let entry = self.duplicate_entries.pop();
+        assert!(entry.is_some());
+    }
+
+    pub(crate) fn is_empty(&self) -> bool {
+        let OpaqueTypeStorage { opaque_types, duplicate_entries } = self;
+        opaque_types.is_empty() && duplicate_entries.is_empty()
+    }
+
+    pub(crate) fn take_opaque_types(
+        &mut self,
+    ) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
+        let OpaqueTypeStorage { opaque_types, duplicate_entries } = self;
+        std::mem::take(opaque_types).into_iter().chain(std::mem::take(duplicate_entries))
+    }
+
+    pub fn num_entries(&self) -> OpaqueTypeStorageEntries {
+        OpaqueTypeStorageEntries {
+            opaque_types: self.opaque_types.len(),
+            duplicate_entries: self.duplicate_entries.len(),
+        }
+    }
+
+    pub fn opaque_types_added_since(
+        &self,
+        prev_entries: OpaqueTypeStorageEntries,
+    ) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
+        self.opaque_types
+            .iter()
+            .skip(prev_entries.opaque_types)
+            .map(|(k, v)| (*k, *v))
+            .chain(self.duplicate_entries.iter().skip(prev_entries.duplicate_entries).copied())
+    }
+
+    /// Only returns the opaque types from the lookup table. These are used
+    /// when normalizing opaque types and have a unique key.
+    ///
+    /// Outside of canonicalization one should generally use `iter_opaque_types`
+    /// to also consider duplicate entries.
+    pub fn iter_lookup_table(
+        &self,
+    ) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
+        self.opaque_types.iter().map(|(k, v)| (*k, *v))
+    }
+
+    /// Only returns the opaque types which are stored in `duplicate_entries`.
+    ///
+    /// These have to considered when checking all opaque type uses but are e.g.
+    /// irrelevant for canonical inputs as nested queries never meaningfully
+    /// accesses them.
+    pub fn iter_duplicate_entries(
+        &self,
+    ) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
+        self.duplicate_entries.iter().copied()
+    }
+
+    pub fn iter_opaque_types(
+        &self,
+    ) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
+        let OpaqueTypeStorage { opaque_types, duplicate_entries } = self;
+        opaque_types.iter().map(|(k, v)| (*k, *v)).chain(duplicate_entries.iter().copied())
+    }
+
     #[inline]
     pub(crate) fn with_log<'a>(
         &'a mut self,
@@ -44,21 +117,27 @@ impl<'tcx> OpaqueTypeStorage<'tcx> {
 
 impl<'tcx> Drop for OpaqueTypeStorage<'tcx> {
     fn drop(&mut self) {
-        if !self.opaque_types.is_empty() {
+        if !self.is_empty() {
             ty::tls::with(|tcx| tcx.dcx().delayed_bug(format!("{:?}", self.opaque_types)));
         }
     }
 }
 
-pub(crate) struct OpaqueTypeTable<'a, 'tcx> {
+pub struct OpaqueTypeTable<'a, 'tcx> {
     storage: &'a mut OpaqueTypeStorage<'tcx>,
 
     undo_log: &'a mut InferCtxtUndoLogs<'tcx>,
 }
+impl<'tcx> Deref for OpaqueTypeTable<'_, 'tcx> {
+    type Target = OpaqueTypeStorage<'tcx>;
+    fn deref(&self) -> &Self::Target {
+        self.storage
+    }
+}
 
 impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> {
     #[instrument(skip(self), level = "debug")]
-    pub(crate) fn register(
+    pub fn register(
         &mut self,
         key: OpaqueTypeKey<'tcx>,
         hidden_type: OpaqueHiddenType<'tcx>,
@@ -72,4 +151,9 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> {
         self.undo_log.push(UndoLog::OpaqueTypes(key, None));
         None
     }
+
+    pub fn add_duplicate(&mut self, key: OpaqueTypeKey<'tcx>, hidden_type: OpaqueHiddenType<'tcx>) {
+        self.storage.duplicate_entries.push((key, hidden_type));
+        self.undo_log.push(UndoLog::DuplicateOpaqueType);
+    }
 }
diff --git a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs
index c44d9723f29..2a4b9776f68 100644
--- a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs
+++ b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs
@@ -24,10 +24,6 @@ impl<'tcx, OP> TypeVisitor<TyCtxt<'tcx>> for FreeRegionsVisitor<'tcx, OP>
 where
     OP: FnMut(ty::Region<'tcx>),
 {
-    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
-        t.super_visit_with(self);
-    }
-
     fn visit_region(&mut self, r: ty::Region<'tcx>) {
         match r.kind() {
             // ignore bound regions, keep visiting
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index a89cef50c9b..8dde99c45cf 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -63,11 +63,11 @@ use rustc_data_structures::undo_log::UndoLogs;
 use rustc_middle::bug;
 use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::traits::query::NoSolution;
+use rustc_middle::ty::outlives::{Component, push_outlives_components};
 use rustc_middle::ty::{
     self, GenericArgKind, GenericArgsRef, PolyTypeOutlivesPredicate, Region, Ty, TyCtxt,
     TypeFoldable as _, TypeVisitableExt,
 };
-use rustc_type_ir::outlives::{Component, push_outlives_components};
 use smallvec::smallvec;
 use tracing::{debug, instrument};
 
diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs
index c14c288c6e4..69feecfe30a 100644
--- a/compiler/rustc_infer/src/infer/outlives/verify.rs
+++ b/compiler/rustc_infer/src/infer/outlives/verify.rs
@@ -1,7 +1,7 @@
 use std::assert_matches::assert_matches;
 
+use rustc_middle::ty::outlives::{Component, compute_alias_components_recursive};
 use rustc_middle::ty::{self, OutlivesPredicate, Ty, TyCtxt};
-use rustc_type_ir::outlives::{Component, compute_alias_components_recursive};
 use smallvec::smallvec;
 use tracing::{debug, instrument, trace};
 
diff --git a/compiler/rustc_infer/src/infer/projection.rs b/compiler/rustc_infer/src/infer/projection.rs
index 1bee9632110..2a4f9db8963 100644
--- a/compiler/rustc_infer/src/infer/projection.rs
+++ b/compiler/rustc_infer/src/infer/projection.rs
@@ -1,7 +1,8 @@
 use rustc_middle::traits::ObligationCause;
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::ty;
 
 use super::InferCtxt;
+use crate::infer::Term;
 use crate::traits::{Obligation, PredicateObligations};
 
 impl<'tcx> InferCtxt<'tcx> {
@@ -11,24 +12,32 @@ impl<'tcx> InferCtxt<'tcx> {
     /// of the given projection. This allows us to proceed with projections
     /// while they cannot be resolved yet due to missing information or
     /// simply due to the lack of access to the trait resolution machinery.
-    pub fn projection_ty_to_infer(
+    pub fn projection_term_to_infer(
         &self,
         param_env: ty::ParamEnv<'tcx>,
-        projection_ty: ty::AliasTy<'tcx>,
+        alias_term: ty::AliasTerm<'tcx>,
         cause: ObligationCause<'tcx>,
         recursion_depth: usize,
         obligations: &mut PredicateObligations<'tcx>,
-    ) -> Ty<'tcx> {
+    ) -> Term<'tcx> {
         debug_assert!(!self.next_trait_solver());
-        let ty_var = self.next_ty_var(self.tcx.def_span(projection_ty.def_id));
+
+        let span = self.tcx.def_span(alias_term.def_id);
+        let infer_var = if alias_term.kind(self.tcx).is_type() {
+            self.next_ty_var(span).into()
+        } else {
+            self.next_const_var(span).into()
+        };
+
         let projection =
             ty::PredicateKind::Clause(ty::ClauseKind::Projection(ty::ProjectionPredicate {
-                projection_term: projection_ty.into(),
-                term: ty_var.into(),
+                projection_term: alias_term,
+                term: infer_var,
             }));
         let obligation =
             Obligation::with_depth(self.tcx, cause, recursion_depth, param_env, projection);
         obligations.push(obligation);
-        ty_var
+
+        infer_var
     }
 }
diff --git a/compiler/rustc_infer/src/infer/relate/mod.rs b/compiler/rustc_infer/src/infer/relate/mod.rs
index e6d1003cab6..6d25dfeb859 100644
--- a/compiler/rustc_infer/src/infer/relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/relate/mod.rs
@@ -2,9 +2,8 @@
 //! (except for some relations used for diagnostics and heuristics in the compiler).
 //! As well as the implementation of `Relate` for interned things (`Ty`/`Const`/etc).
 
-pub use rustc_middle::ty::relate::RelateResult;
-pub use rustc_type_ir::relate::combine::PredicateEmittingRelation;
-pub use rustc_type_ir::relate::*;
+pub use rustc_middle::ty::relate::combine::PredicateEmittingRelation;
+pub use rustc_middle::ty::relate::{RelateResult, *};
 
 mod generalize;
 mod higher_ranked;
diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs
index 009271a8378..04ff776594e 100644
--- a/compiler/rustc_infer/src/infer/relate/type_relating.rs
+++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs
@@ -3,9 +3,8 @@ use rustc_middle::ty::relate::combine::{super_combine_consts, super_combine_tys}
 use rustc_middle::ty::relate::{
     Relate, RelateResult, TypeRelation, relate_args_invariantly, relate_args_with_variances,
 };
-use rustc_middle::ty::{self, Ty, TyCtxt, TyVar};
+use rustc_middle::ty::{self, DelayedSet, Ty, TyCtxt, TyVar};
 use rustc_span::Span;
-use rustc_type_ir::data_structures::DelayedSet;
 use tracing::{debug, instrument};
 
 use crate::infer::BoundRegionConversionTime::HigherRankedType;
diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs
index 245f1a4ac5e..4b0ace8c554 100644
--- a/compiler/rustc_infer/src/infer/resolve.rs
+++ b/compiler/rustc_infer/src/infer/resolve.rs
@@ -1,9 +1,8 @@
 use rustc_middle::bug;
 use rustc_middle::ty::{
-    self, Const, FallibleTypeFolder, InferConst, Ty, TyCtxt, TypeFoldable, TypeFolder,
+    self, Const, DelayedMap, FallibleTypeFolder, InferConst, Ty, TyCtxt, TypeFoldable, TypeFolder,
     TypeSuperFoldable, TypeVisitableExt,
 };
-use rustc_type_ir::data_structures::DelayedMap;
 
 use super::{FixupError, FixupResult, InferCtxt};
 
diff --git a/compiler/rustc_infer/src/infer/snapshot/fudge.rs b/compiler/rustc_infer/src/infer/snapshot/fudge.rs
index 39c8c40ea7d..e210479581b 100644
--- a/compiler/rustc_infer/src/infer/snapshot/fudge.rs
+++ b/compiler/rustc_infer/src/infer/snapshot/fudge.rs
@@ -3,9 +3,8 @@ use std::ops::Range;
 use rustc_data_structures::{snapshot_vec as sv, unify as ut};
 use rustc_middle::ty::{
     self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid, TypeFoldable, TypeFolder,
-    TypeSuperFoldable,
+    TypeSuperFoldable, TypeVisitableExt,
 };
-use rustc_type_ir::TypeVisitableExt;
 use tracing::instrument;
 use ut::UnifyKey;
 
diff --git a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs
index ba7d8f588e6..b7412d3d6a6 100644
--- a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs
+++ b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs
@@ -17,6 +17,7 @@ pub struct Snapshot<'tcx> {
 /// Records the "undo" data for a single operation that affects some form of inference variable.
 #[derive(Clone)]
 pub(crate) enum UndoLog<'tcx> {
+    DuplicateOpaqueType,
     OpaqueTypes(OpaqueTypeKey<'tcx>, Option<OpaqueHiddenType<'tcx>>),
     TypeVariables(sv::UndoLog<ut::Delegate<type_variable::TyVidEqKey<'tcx>>>),
     ConstUnificationTable(sv::UndoLog<ut::Delegate<ConstVidKey<'tcx>>>),
@@ -58,6 +59,7 @@ impl_from! {
 impl<'tcx> Rollback<UndoLog<'tcx>> for InferCtxtInner<'tcx> {
     fn reverse(&mut self, undo: UndoLog<'tcx>) {
         match undo {
+            UndoLog::DuplicateOpaqueType => self.opaque_type_storage.pop_duplicate_entry(),
             UndoLog::OpaqueTypes(key, idx) => self.opaque_type_storage.remove(key, idx),
             UndoLog::TypeVariables(undo) => self.type_variable_storage.reverse(undo),
             UndoLog::ConstUnificationTable(undo) => self.const_unification_storage.reverse(undo),
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index 66ed49fe326..6461fbe0d33 100644
--- a/compiler/rustc_infer/src/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
@@ -1,7 +1,7 @@
 use rustc_data_structures::fx::FxHashSet;
+pub use rustc_middle::ty::elaborate::*;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::{Ident, Span};
-pub use rustc_type_ir::elaborate::*;
 
 use crate::traits::{self, Obligation, ObligationCauseCode, PredicateObligation};
 
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 493b1d5eaa9..f4d11a7c0be 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -31,10 +31,11 @@ use rustc_resolve::Resolver;
 use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType};
 use rustc_session::cstore::Untracked;
 use rustc_session::output::{collect_crate_types, filename_for_input};
+use rustc_session::parse::feature_err;
 use rustc_session::search_paths::PathKind;
 use rustc_session::{Limit, Session};
 use rustc_span::{
-    ErrorGuaranteed, FileName, SourceFileHash, SourceFileHashAlgorithm, Span, Symbol, sym,
+    DUMMY_SP, ErrorGuaranteed, FileName, SourceFileHash, SourceFileHashAlgorithm, Span, Symbol, sym,
 };
 use rustc_target::spec::PanicStrategy;
 use rustc_trait_selection::traits;
@@ -237,6 +238,7 @@ fn configure_and_expand(
             sess,
             features,
             &krate,
+            tcx.is_sdylib_interface_build(),
             resolver.lint_buffer(),
         )
     });
@@ -253,6 +255,9 @@ fn configure_and_expand(
             sess.dcx().emit_err(errors::MixedProcMacroCrate);
         }
     }
+    if crate_types.contains(&CrateType::Sdylib) && !tcx.features().export_stable() {
+        feature_err(sess, sym::export_stable, DUMMY_SP, "`sdylib` crate type is unstable").emit();
+    }
 
     if is_proc_macro_crate && sess.panic_strategy() == PanicStrategy::Abort {
         sess.dcx().emit_warn(errors::ProcMacroCratePanicAbort);
@@ -742,6 +747,25 @@ pub fn write_dep_info(tcx: TyCtxt<'_>) {
     }
 }
 
+pub fn write_interface<'tcx>(tcx: TyCtxt<'tcx>) {
+    if !tcx.crate_types().contains(&rustc_session::config::CrateType::Sdylib) {
+        return;
+    }
+    let _timer = tcx.sess.timer("write_interface");
+    let (_, krate) = &*tcx.resolver_for_lowering().borrow();
+
+    let krate = rustc_ast_pretty::pprust::print_crate_as_interface(
+        krate,
+        tcx.sess.psess.edition,
+        &tcx.sess.psess.attr_id_generator,
+    );
+    let export_output = tcx.output_filenames(()).interface_path();
+    let mut file = fs::File::create_buffered(export_output).unwrap();
+    if let Err(err) = write!(file, "{}", krate) {
+        tcx.dcx().fatal(format!("error writing interface file: {}", err));
+    }
+}
+
 pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
     let providers = &mut Providers::default();
     providers.analysis = analysis;
@@ -930,6 +954,8 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
                 CStore::from_tcx(tcx).report_unused_deps(tcx);
             },
             {
+                tcx.ensure_ok().exportable_items(LOCAL_CRATE);
+                tcx.ensure_ok().stable_order_of_exportable_impls(LOCAL_CRATE);
                 tcx.par_hir_for_each_module(|module| {
                     tcx.ensure_ok().check_mod_loops(module);
                     tcx.ensure_ok().check_mod_attrs(module);
diff --git a/compiler/rustc_lexer/src/cursor.rs b/compiler/rustc_lexer/src/cursor.rs
index e0e3bd0e30b..526693d3de1 100644
--- a/compiler/rustc_lexer/src/cursor.rs
+++ b/compiler/rustc_lexer/src/cursor.rs
@@ -1,5 +1,10 @@
 use std::str::Chars;
 
+pub enum FrontmatterAllowed {
+    Yes,
+    No,
+}
+
 /// Peekable iterator over a char sequence.
 ///
 /// Next characters can be peeked via `first` method,
@@ -8,6 +13,7 @@ pub struct Cursor<'a> {
     len_remaining: usize,
     /// Iterator over chars. Slightly faster than a &str.
     chars: Chars<'a>,
+    pub(crate) frontmatter_allowed: FrontmatterAllowed,
     #[cfg(debug_assertions)]
     prev: char,
 }
@@ -15,10 +21,11 @@ pub struct Cursor<'a> {
 pub(crate) const EOF_CHAR: char = '\0';
 
 impl<'a> Cursor<'a> {
-    pub fn new(input: &'a str) -> Cursor<'a> {
+    pub fn new(input: &'a str, frontmatter_allowed: FrontmatterAllowed) -> Cursor<'a> {
         Cursor {
             len_remaining: input.len(),
             chars: input.chars(),
+            frontmatter_allowed,
             #[cfg(debug_assertions)]
             prev: EOF_CHAR,
         }
@@ -95,6 +102,11 @@ impl<'a> Cursor<'a> {
         Some(c)
     }
 
+    /// Moves to a substring by a number of bytes.
+    pub(crate) fn bump_bytes(&mut self, n: usize) {
+        self.chars = self.as_str()[n..].chars();
+    }
+
     /// Eats symbols while predicate returns true or until the end of file is reached.
     pub(crate) fn eat_while(&mut self, mut predicate: impl FnMut(char) -> bool) {
         // It was tried making optimized version of this for eg. line comments, but
diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs
index f9c71b2fa65..2374f388250 100644
--- a/compiler/rustc_lexer/src/lib.rs
+++ b/compiler/rustc_lexer/src/lib.rs
@@ -35,8 +35,8 @@ pub use unicode_xid::UNICODE_VERSION as UNICODE_XID_VERSION;
 
 use self::LiteralKind::*;
 use self::TokenKind::*;
-pub use crate::cursor::Cursor;
 use crate::cursor::EOF_CHAR;
+pub use crate::cursor::{Cursor, FrontmatterAllowed};
 
 /// Parsed token.
 /// It doesn't contain information about data that has been parsed,
@@ -57,17 +57,27 @@ impl Token {
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum TokenKind {
     /// A line comment, e.g. `// comment`.
-    LineComment { doc_style: Option<DocStyle> },
+    LineComment {
+        doc_style: Option<DocStyle>,
+    },
 
     /// A block comment, e.g. `/* block comment */`.
     ///
     /// Block comments can be recursive, so a sequence like `/* /* */`
     /// will not be considered terminated and will result in a parsing error.
-    BlockComment { doc_style: Option<DocStyle>, terminated: bool },
+    BlockComment {
+        doc_style: Option<DocStyle>,
+        terminated: bool,
+    },
 
     /// Any whitespace character sequence.
     Whitespace,
 
+    Frontmatter {
+        has_invalid_preceding_whitespace: bool,
+        invalid_infostring: bool,
+    },
+
     /// An identifier or keyword, e.g. `ident` or `continue`.
     Ident,
 
@@ -109,10 +119,15 @@ pub enum TokenKind {
     /// this type will need to check for and reject that case.
     ///
     /// See [LiteralKind] for more details.
-    Literal { kind: LiteralKind, suffix_start: u32 },
+    Literal {
+        kind: LiteralKind,
+        suffix_start: u32,
+    },
 
     /// A lifetime, e.g. `'a`.
-    Lifetime { starts_with_number: bool },
+    Lifetime {
+        starts_with_number: bool,
+    },
 
     /// `;`
     Semi,
@@ -280,7 +295,7 @@ pub fn strip_shebang(input: &str) -> Option<usize> {
 #[inline]
 pub fn validate_raw_str(input: &str, prefix_len: u32) -> Result<(), RawStrError> {
     debug_assert!(!input.is_empty());
-    let mut cursor = Cursor::new(input);
+    let mut cursor = Cursor::new(input, FrontmatterAllowed::No);
     // Move past the leading `r` or `br`.
     for _ in 0..prefix_len {
         cursor.bump().unwrap();
@@ -290,7 +305,7 @@ pub fn validate_raw_str(input: &str, prefix_len: u32) -> Result<(), RawStrError>
 
 /// Creates an iterator that produces tokens from the input string.
 pub fn tokenize(input: &str) -> impl Iterator<Item = Token> {
-    let mut cursor = Cursor::new(input);
+    let mut cursor = Cursor::new(input, FrontmatterAllowed::No);
     std::iter::from_fn(move || {
         let token = cursor.advance_token();
         if token.kind != TokenKind::Eof { Some(token) } else { None }
@@ -361,7 +376,34 @@ impl Cursor<'_> {
             Some(c) => c,
             None => return Token::new(TokenKind::Eof, 0),
         };
+
         let token_kind = match first_char {
+            c if matches!(self.frontmatter_allowed, FrontmatterAllowed::Yes)
+                && is_whitespace(c) =>
+            {
+                let mut last = first_char;
+                while is_whitespace(self.first()) {
+                    let Some(c) = self.bump() else {
+                        break;
+                    };
+                    last = c;
+                }
+                // invalid frontmatter opening as whitespace preceding it isn't newline.
+                // combine the whitespace and the frontmatter to a single token as we shall
+                // error later.
+                if last != '\n' && self.as_str().starts_with("---") {
+                    self.bump();
+                    self.frontmatter(true)
+                } else {
+                    Whitespace
+                }
+            }
+            '-' if matches!(self.frontmatter_allowed, FrontmatterAllowed::Yes)
+                && self.as_str().starts_with("--") =>
+            {
+                // happy path
+                self.frontmatter(false)
+            }
             // Slash, comment or block comment.
             '/' => match self.first() {
                 '/' => self.line_comment(),
@@ -464,11 +506,110 @@ impl Cursor<'_> {
             c if !c.is_ascii() && c.is_emoji_char() => self.invalid_ident(),
             _ => Unknown,
         };
+        if matches!(self.frontmatter_allowed, FrontmatterAllowed::Yes)
+            && !matches!(token_kind, Whitespace)
+        {
+            // stop allowing frontmatters after first non-whitespace token
+            self.frontmatter_allowed = FrontmatterAllowed::No;
+        }
         let res = Token::new(token_kind, self.pos_within_token());
         self.reset_pos_within_token();
         res
     }
 
+    /// Given that one `-` was eaten, eat the rest of the frontmatter.
+    fn frontmatter(&mut self, has_invalid_preceding_whitespace: bool) -> TokenKind {
+        debug_assert_eq!('-', self.prev());
+
+        let pos = self.pos_within_token();
+        self.eat_while(|c| c == '-');
+
+        // one `-` is eaten by the caller.
+        let length_opening = self.pos_within_token() - pos + 1;
+
+        // must be ensured by the caller
+        debug_assert!(length_opening >= 3);
+
+        // whitespace between the opening and the infostring.
+        self.eat_while(|ch| ch != '\n' && is_whitespace(ch));
+
+        // copied from `eat_identifier`, but allows `.` in infostring to allow something like
+        // `---Cargo.toml` as a valid opener
+        if is_id_start(self.first()) {
+            self.bump();
+            self.eat_while(|c| is_id_continue(c) || c == '.');
+        }
+
+        self.eat_while(|ch| ch != '\n' && is_whitespace(ch));
+        let invalid_infostring = self.first() != '\n';
+
+        let mut s = self.as_str();
+        let mut found = false;
+        while let Some(closing) = s.find(&"-".repeat(length_opening as usize)) {
+            let preceding_chars_start = s[..closing].rfind("\n").map_or(0, |i| i + 1);
+            if s[preceding_chars_start..closing].chars().all(is_whitespace) {
+                // candidate found
+                self.bump_bytes(closing);
+                // in case like
+                // ---cargo
+                // --- blahblah
+                // or
+                // ---cargo
+                // ----
+                // combine those stuff into this frontmatter token such that it gets detected later.
+                self.eat_until(b'\n');
+                found = true;
+                break;
+            } else {
+                s = &s[closing + length_opening as usize..];
+            }
+        }
+
+        if !found {
+            // recovery strategy: a closing statement might have precending whitespace/newline
+            // but not have enough dashes to properly close. In this case, we eat until there,
+            // and report a mismatch in the parser.
+            let mut rest = self.as_str();
+            // We can look for a shorter closing (starting with four dashes but closing with three)
+            // and other indications that Rust has started and the infostring has ended.
+            let mut potential_closing = rest
+                .find("\n---")
+                // n.b. only in the case where there are dashes, we move the index to the line where
+                // the dashes start as we eat to include that line. For other cases those are Rust code
+                // and not included in the frontmatter.
+                .map(|x| x + 1)
+                .or_else(|| rest.find("\nuse "))
+                .or_else(|| rest.find("\n//!"))
+                .or_else(|| rest.find("\n#!["));
+
+            if potential_closing.is_none() {
+                // a less fortunate recovery if all else fails which finds any dashes preceded by whitespace
+                // on a standalone line. Might be wrong.
+                while let Some(closing) = rest.find("---") {
+                    let preceding_chars_start = rest[..closing].rfind("\n").map_or(0, |i| i + 1);
+                    if rest[preceding_chars_start..closing].chars().all(is_whitespace) {
+                        // candidate found
+                        potential_closing = Some(closing);
+                        break;
+                    } else {
+                        rest = &rest[closing + 3..];
+                    }
+                }
+            }
+
+            if let Some(potential_closing) = potential_closing {
+                // bump to the potential closing, and eat everything on that line.
+                self.bump_bytes(potential_closing);
+                self.eat_until(b'\n');
+            } else {
+                // eat everything. this will get reported as an unclosed frontmatter.
+                self.eat_while(|_| true);
+            }
+        }
+
+        Frontmatter { has_invalid_preceding_whitespace, invalid_infostring }
+    }
+
     fn line_comment(&mut self) -> TokenKind {
         debug_assert!(self.prev() == '/' && self.first() == '/');
         self.bump();
diff --git a/compiler/rustc_lexer/src/tests.rs b/compiler/rustc_lexer/src/tests.rs
index 8203ae70b07..fc8d9b9d57b 100644
--- a/compiler/rustc_lexer/src/tests.rs
+++ b/compiler/rustc_lexer/src/tests.rs
@@ -4,7 +4,7 @@ use super::*;
 
 fn check_raw_str(s: &str, expected: Result<u8, RawStrError>) {
     let s = &format!("r{}", s);
-    let mut cursor = Cursor::new(s);
+    let mut cursor = Cursor::new(s, FrontmatterAllowed::No);
     cursor.bump();
     let res = cursor.raw_double_quoted_string(0);
     assert_eq!(res, expected);
diff --git a/compiler/rustc_lint/src/autorefs.rs b/compiler/rustc_lint/src/autorefs.rs
index ddab13190be..91d58d92466 100644
--- a/compiler/rustc_lint/src/autorefs.rs
+++ b/compiler/rustc_lint/src/autorefs.rs
@@ -15,9 +15,9 @@ declare_lint! {
     ///
     /// ```rust
     /// unsafe fn fun(ptr: *mut [u8]) -> *mut [u8] {
-    ///     &raw mut (*ptr)[..16]
-    ///     //             ^^^^^^ this calls `IndexMut::index_mut(&mut ..., ..16)`,
-    ///     //                    implicitly creating a reference
+    ///     unsafe { &raw mut (*ptr)[..16] }
+    ///     //                      ^^^^^^ this calls `IndexMut::index_mut(&mut ..., ..16)`,
+    ///     //                             implicitly creating a reference
     /// }
     /// ```
     ///
@@ -34,17 +34,17 @@ declare_lint! {
     ///
     /// ```rust
     /// unsafe fn fun(ptr: *mut [u8]) -> *mut [u8] {
-    ///     &raw mut (&mut *ptr)[..16]
+    ///     unsafe { &raw mut (&mut *ptr)[..16] }
     /// }
     /// ```
     ///
     /// Otherwise try to find an alternative way to achive your goals using only raw pointers:
     ///
     /// ```rust
-    /// use std::slice;
+    /// use std::ptr;
     ///
-    /// unsafe fn fun(ptr: *mut [u8]) -> *mut [u8] {
-    ///     slice::from_raw_parts_mut(ptr.cast(), 16)
+    /// fn fun(ptr: *mut [u8]) -> *mut [u8] {
+    ///     ptr::slice_from_raw_parts_mut(ptr.cast(), 16)
     /// }
     /// ```
     pub DANGEROUS_IMPLICIT_AUTOREFS,
diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs
index 757fc1f58bd..a56b753bda7 100644
--- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs
+++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs
@@ -49,6 +49,8 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         let Some((pat, arg)) = extract_for_loop(expr) else { return };
 
+        let arg_span = arg.span.source_callsite();
+
         let ty = cx.typeck_results().expr_ty(arg);
 
         let (adt, args, ref_mutability) = match ty.kind() {
@@ -78,27 +80,27 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {
             && let Ok(recv_snip) = cx.sess().source_map().span_to_snippet(recv.span)
         {
             ForLoopsOverFalliblesLoopSub::RemoveNext {
-                suggestion: recv.span.between(arg.span.shrink_to_hi()),
+                suggestion: recv.span.between(arg_span.shrink_to_hi()),
                 recv_snip,
             }
         } else {
             ForLoopsOverFalliblesLoopSub::UseWhileLet {
                 start_span: expr.span.with_hi(pat.span.lo()),
-                end_span: pat.span.between(arg.span),
+                end_span: pat.span.between(arg_span),
                 var,
             }
         };
         let question_mark = suggest_question_mark(cx, adt, args, expr.span)
-            .then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg.span.shrink_to_hi() });
+            .then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg_span.shrink_to_hi() });
         let suggestion = ForLoopsOverFalliblesSuggestion {
             var,
             start_span: expr.span.with_hi(pat.span.lo()),
-            end_span: pat.span.between(arg.span),
+            end_span: pat.span.between(arg_span),
         };
 
         cx.emit_span_lint(
             FOR_LOOPS_OVER_FALLIBLES,
-            arg.span,
+            arg_span,
             ForLoopsOverFalliblesDiag { article, ref_prefix, ty, sub, question_mark, suggestion },
         );
     }
diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs
index 0494c78a7a9..d0668794198 100644
--- a/compiler/rustc_lint/src/foreign_modules.rs
+++ b/compiler/rustc_lint/src/foreign_modules.rs
@@ -104,7 +104,7 @@ impl ClashingExternDeclarations {
     /// for the item, return its HirId without updating the set.
     fn insert(&mut self, tcx: TyCtxt<'_>, fi: hir::ForeignItemId) -> Option<hir::OwnerId> {
         let did = fi.owner_id.to_def_id();
-        let instance = Instance::new(did, ty::List::identity_for_item(tcx, did));
+        let instance = Instance::new_raw(did, ty::List::identity_for_item(tcx, did));
         let name = Symbol::intern(tcx.symbol_name(instance).name);
         if let Some(&existing_id) = self.seen_decls.get(&name) {
             // Avoid updating the map with the new entry when we do find a collision. We want to
diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
index 7f4789ad0d9..a8f45d043be 100644
--- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs
+++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
@@ -15,7 +15,8 @@ use rustc_middle::ty::relate::{
     Relate, RelateResult, TypeRelation, structurally_relate_consts, structurally_relate_tys,
 };
 use rustc_middle::ty::{
-    self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
+    self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
+    TypeVisitor,
 };
 use rustc_middle::{bug, span_bug};
 use rustc_session::lint::FutureIncompatibilityReason;
@@ -209,7 +210,7 @@ where
     VarFn: FnOnce() -> FxHashMap<DefId, ty::Variance>,
     OutlivesFn: FnOnce() -> OutlivesEnvironment<'tcx>,
 {
-    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
+    fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
         // When we get into a binder, we need to add its own bound vars to the scope.
         let mut added = vec![];
         for arg in t.bound_vars() {
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 03b8112938c..3cea24634fe 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -2352,37 +2352,11 @@ declare_lint! {
 }
 
 declare_lint! {
-    /// The `soft_unstable` lint detects unstable features that were
-    /// unintentionally allowed on stable.
-    ///
-    /// ### Example
-    ///
-    /// ```rust,compile_fail
-    /// #[cfg(test)]
-    /// extern crate test;
-    ///
-    /// #[bench]
-    /// fn name(b: &mut test::Bencher) {
-    ///     b.iter(|| 123)
-    /// }
-    /// ```
-    ///
-    /// {{produces}}
-    ///
-    /// ### Explanation
-    ///
-    /// The [`bench` attribute] was accidentally allowed to be specified on
-    /// the [stable release channel]. Turning this to a hard error would have
-    /// broken some projects. This lint allows those projects to continue to
-    /// build correctly when [`--cap-lints`] is used, but otherwise signal an
-    /// error that `#[bench]` should not be used on the stable channel. This
-    /// is a [future-incompatible] lint to transition this to a hard error in
-    /// the future. See [issue #64266] for more details.
+    /// The `soft_unstable` lint detects unstable features that were unintentionally allowed on
+    /// stable. This is a [future-incompatible] lint to transition this to a hard error in the
+    /// future. See [issue #64266] for more details.
     ///
     /// [issue #64266]: https://github.com/rust-lang/rust/issues/64266
-    /// [`bench` attribute]: https://doc.rust-lang.org/nightly/unstable-book/library-features/test.html
-    /// [stable release channel]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html
-    /// [`--cap-lints`]: https://doc.rust-lang.org/rustc/lints/levels.html#capping-lints
     /// [future-incompatible]: ../index.md#future-incompatible-lints
     pub SOFT_UNSTABLE,
     Deny,
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index ebe8eb57f2c..d4a05fbbbc5 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -512,8 +512,13 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
 #endif
   }
 
+#if LLVM_VERSION_GE(21, 0)
+  TargetMachine *TM = TheTarget->createTargetMachine(Trip, CPU, Feature,
+                                                     Options, RM, CM, OptLevel);
+#else
   TargetMachine *TM = TheTarget->createTargetMachine(
       Trip.getTriple(), CPU, Feature, Options, RM, CM, OptLevel);
+#endif
   return wrap(TM);
 }
 
diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs
index 49dd388f14c..1bb502ca3d0 100644
--- a/compiler/rustc_log/src/lib.rs
+++ b/compiler/rustc_log/src/lib.rs
@@ -37,6 +37,7 @@ use std::env::{self, VarError};
 use std::fmt::{self, Display};
 use std::io::{self, IsTerminal};
 
+use tracing::dispatcher::SetGlobalDefaultError;
 use tracing_core::{Event, Subscriber};
 use tracing_subscriber::filter::{Directive, EnvFilter, LevelFilter};
 use tracing_subscriber::fmt::FmtContext;
@@ -131,10 +132,10 @@ pub fn init_logger(cfg: LoggerConfig) -> Result<(), Error> {
                 .without_time()
                 .event_format(BacktraceFormatter { backtrace_target });
             let subscriber = subscriber.with(fmt_layer);
-            tracing::subscriber::set_global_default(subscriber).unwrap();
+            tracing::subscriber::set_global_default(subscriber)?;
         }
         Err(_) => {
-            tracing::subscriber::set_global_default(subscriber).unwrap();
+            tracing::subscriber::set_global_default(subscriber)?;
         }
     };
 
@@ -180,6 +181,7 @@ pub enum Error {
     InvalidColorValue(String),
     NonUnicodeColorValue,
     InvalidWraptree(String),
+    AlreadyInit(SetGlobalDefaultError),
 }
 
 impl std::error::Error for Error {}
@@ -199,6 +201,13 @@ impl Display for Error {
                 formatter,
                 "invalid log WRAPTREE value '{value}': expected a non-negative integer",
             ),
+            Error::AlreadyInit(tracing_error) => Display::fmt(tracing_error, formatter),
         }
     }
 }
+
+impl From<SetGlobalDefaultError> for Error {
+    fn from(tracing_error: SetGlobalDefaultError) -> Self {
+        Error::AlreadyInit(tracing_error)
+    }
+}
diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml
index b11f9260be7..26878c488b7 100644
--- a/compiler/rustc_metadata/Cargo.toml
+++ b/compiler/rustc_metadata/Cargo.toml
@@ -26,6 +26,7 @@ rustc_serialize = { path = "../rustc_serialize" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
+tempfile = "3.7.1"
 tracing = "0.1"
 # tidy-alphabetical-end
 
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 1c3222bbfeb..07fb2de8a3e 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -148,7 +148,7 @@ impl<'a> std::fmt::Debug for CrateDump<'a> {
             writeln!(fmt, "  hash: {}", data.hash())?;
             writeln!(fmt, "  reqd: {:?}", data.dep_kind())?;
             writeln!(fmt, "  priv: {:?}", data.is_private_dep())?;
-            let CrateSource { dylib, rlib, rmeta } = data.source();
+            let CrateSource { dylib, rlib, rmeta, sdylib_interface } = data.source();
             if let Some(dylib) = dylib {
                 writeln!(fmt, "  dylib: {}", dylib.0.display())?;
             }
@@ -158,6 +158,9 @@ impl<'a> std::fmt::Debug for CrateDump<'a> {
             if let Some(rmeta) = rmeta {
                 writeln!(fmt, "   rmeta: {}", rmeta.0.display())?;
             }
+            if let Some(sdylib_interface) = sdylib_interface {
+                writeln!(fmt, "   sdylib interface: {}", sdylib_interface.0.display())?;
+            }
         }
         Ok(())
     }
diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs
index be31aa629c8..fcae33c73c9 100644
--- a/compiler/rustc_metadata/src/dependency_format.rs
+++ b/compiler/rustc_metadata/src/dependency_format.rs
@@ -88,45 +88,42 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
         return IndexVec::new();
     }
 
-    let preferred_linkage = match ty {
-        // Generating a dylib without `-C prefer-dynamic` means that we're going
-        // to try to eagerly statically link all dependencies. This is normally
-        // done for end-product dylibs, not intermediate products.
-        //
-        // Treat cdylibs and staticlibs similarly. If `-C prefer-dynamic` is set,
-        // the caller may be code-size conscious, but without it, it makes sense
-        // to statically link a cdylib or staticlib. For staticlibs we use
-        // `-Z staticlib-prefer-dynamic` for now. This may be merged into
-        // `-C prefer-dynamic` in the future.
-        CrateType::Dylib | CrateType::Cdylib => {
-            if sess.opts.cg.prefer_dynamic {
-                Linkage::Dynamic
-            } else {
-                Linkage::Static
+    let preferred_linkage =
+        match ty {
+            // Generating a dylib without `-C prefer-dynamic` means that we're going
+            // to try to eagerly statically link all dependencies. This is normally
+            // done for end-product dylibs, not intermediate products.
+            //
+            // Treat cdylibs and staticlibs similarly. If `-C prefer-dynamic` is set,
+            // the caller may be code-size conscious, but without it, it makes sense
+            // to statically link a cdylib or staticlib. For staticlibs we use
+            // `-Z staticlib-prefer-dynamic` for now. This may be merged into
+            // `-C prefer-dynamic` in the future.
+            CrateType::Dylib | CrateType::Cdylib | CrateType::Sdylib => {
+                if sess.opts.cg.prefer_dynamic { Linkage::Dynamic } else { Linkage::Static }
             }
-        }
-        CrateType::Staticlib => {
-            if sess.opts.unstable_opts.staticlib_prefer_dynamic {
-                Linkage::Dynamic
-            } else {
-                Linkage::Static
+            CrateType::Staticlib => {
+                if sess.opts.unstable_opts.staticlib_prefer_dynamic {
+                    Linkage::Dynamic
+                } else {
+                    Linkage::Static
+                }
             }
-        }
 
-        // If the global prefer_dynamic switch is turned off, or the final
-        // executable will be statically linked, prefer static crate linkage.
-        CrateType::Executable if !sess.opts.cg.prefer_dynamic || sess.crt_static(Some(ty)) => {
-            Linkage::Static
-        }
-        CrateType::Executable => Linkage::Dynamic,
+            // If the global prefer_dynamic switch is turned off, or the final
+            // executable will be statically linked, prefer static crate linkage.
+            CrateType::Executable if !sess.opts.cg.prefer_dynamic || sess.crt_static(Some(ty)) => {
+                Linkage::Static
+            }
+            CrateType::Executable => Linkage::Dynamic,
 
-        // proc-macro crates are mostly cdylibs, but we also need metadata.
-        CrateType::ProcMacro => Linkage::Static,
+            // proc-macro crates are mostly cdylibs, but we also need metadata.
+            CrateType::ProcMacro => Linkage::Static,
 
-        // No linkage happens with rlibs, we just needed the metadata (which we
-        // got long ago), so don't bother with anything.
-        CrateType::Rlib => Linkage::NotLinked,
-    };
+            // No linkage happens with rlibs, we just needed the metadata (which we
+            // got long ago), so don't bother with anything.
+            CrateType::Rlib => Linkage::NotLinked,
+        };
 
     let mut unavailable_as_static = Vec::new();
 
@@ -165,7 +162,9 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
 
     let all_dylibs = || {
         tcx.crates(()).iter().filter(|&&cnum| {
-            !tcx.dep_kind(cnum).macros_only() && tcx.used_crate_source(cnum).dylib.is_some()
+            !tcx.dep_kind(cnum).macros_only()
+                && (tcx.used_crate_source(cnum).dylib.is_some()
+                    || tcx.used_crate_source(cnum).sdylib_interface.is_some())
         })
     };
 
@@ -273,7 +272,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
         match *kind {
             Linkage::NotLinked | Linkage::IncludedFromDylib => {}
             Linkage::Static if src.rlib.is_some() => continue,
-            Linkage::Dynamic if src.dylib.is_some() => continue,
+            Linkage::Dynamic if src.dylib.is_some() || src.sdylib_interface.is_some() => continue,
             kind => {
                 let kind = match kind {
                     Linkage::Static => "rlib",
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index f0a898d678c..10123cb9a9d 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -220,7 +220,7 @@ use std::{cmp, fmt};
 
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_data_structures::memmap::Mmap;
-use rustc_data_structures::owned_slice::slice_owned;
+use rustc_data_structures::owned_slice::{OwnedSlice, slice_owned};
 use rustc_data_structures::svh::Svh;
 use rustc_errors::{DiagArgValue, IntoDiagArg};
 use rustc_fs_util::try_canonicalize;
@@ -231,6 +231,7 @@ use rustc_session::search_paths::PathKind;
 use rustc_session::utils::CanonicalizedPath;
 use rustc_span::{Span, Symbol};
 use rustc_target::spec::{Target, TargetTuple};
+use tempfile::Builder as TempFileBuilder;
 use tracing::{debug, info};
 
 use crate::creader::{Library, MetadataLoader};
@@ -277,6 +278,7 @@ pub(crate) enum CrateFlavor {
     Rlib,
     Rmeta,
     Dylib,
+    SDylib,
 }
 
 impl fmt::Display for CrateFlavor {
@@ -285,6 +287,7 @@ impl fmt::Display for CrateFlavor {
             CrateFlavor::Rlib => "rlib",
             CrateFlavor::Rmeta => "rmeta",
             CrateFlavor::Dylib => "dylib",
+            CrateFlavor::SDylib => "sdylib",
         })
     }
 }
@@ -295,6 +298,7 @@ impl IntoDiagArg for CrateFlavor {
             CrateFlavor::Rlib => DiagArgValue::Str(Cow::Borrowed("rlib")),
             CrateFlavor::Rmeta => DiagArgValue::Str(Cow::Borrowed("rmeta")),
             CrateFlavor::Dylib => DiagArgValue::Str(Cow::Borrowed("dylib")),
+            CrateFlavor::SDylib => DiagArgValue::Str(Cow::Borrowed("sdylib")),
         }
     }
 }
@@ -379,14 +383,18 @@ impl<'a> CrateLocator<'a> {
             &format!("{}{}{}", self.target.dll_prefix, self.crate_name, extra_prefix);
         let staticlib_prefix =
             &format!("{}{}{}", self.target.staticlib_prefix, self.crate_name, extra_prefix);
+        let interface_prefix = rmeta_prefix;
 
         let rmeta_suffix = ".rmeta";
         let rlib_suffix = ".rlib";
         let dylib_suffix = &self.target.dll_suffix;
         let staticlib_suffix = &self.target.staticlib_suffix;
+        let interface_suffix = ".rs";
 
-        let mut candidates: FxIndexMap<_, (FxIndexMap<_, _>, FxIndexMap<_, _>, FxIndexMap<_, _>)> =
-            Default::default();
+        let mut candidates: FxIndexMap<
+            _,
+            (FxIndexMap<_, _>, FxIndexMap<_, _>, FxIndexMap<_, _>, FxIndexMap<_, _>),
+        > = Default::default();
 
         // First, find all possible candidate rlibs and dylibs purely based on
         // the name of the files themselves. We're trying to match against an
@@ -417,6 +425,7 @@ impl<'a> CrateLocator<'a> {
                 (rlib_prefix.as_str(), rlib_suffix, CrateFlavor::Rlib),
                 (rmeta_prefix.as_str(), rmeta_suffix, CrateFlavor::Rmeta),
                 (dylib_prefix, dylib_suffix, CrateFlavor::Dylib),
+                (interface_prefix, interface_suffix, CrateFlavor::SDylib),
             ] {
                 if prefix == staticlib_prefix && suffix == staticlib_suffix {
                     should_check_staticlibs = false;
@@ -425,7 +434,7 @@ impl<'a> CrateLocator<'a> {
                     for (hash, spf) in matches {
                         info!("lib candidate: {}", spf.path.display());
 
-                        let (rlibs, rmetas, dylibs) =
+                        let (rlibs, rmetas, dylibs, interfaces) =
                             candidates.entry(hash.to_string()).or_default();
                         {
                             // As a perforamnce optimisation we canonicalize the path and skip
@@ -446,6 +455,7 @@ impl<'a> CrateLocator<'a> {
                             CrateFlavor::Rlib => rlibs.insert(path, search_path.kind),
                             CrateFlavor::Rmeta => rmetas.insert(path, search_path.kind),
                             CrateFlavor::Dylib => dylibs.insert(path, search_path.kind),
+                            CrateFlavor::SDylib => interfaces.insert(path, search_path.kind),
                         };
                     }
                 }
@@ -472,8 +482,8 @@ impl<'a> CrateLocator<'a> {
         // libraries corresponds to the crate id and hash criteria that this
         // search is being performed for.
         let mut libraries = FxIndexMap::default();
-        for (_hash, (rlibs, rmetas, dylibs)) in candidates {
-            if let Some((svh, lib)) = self.extract_lib(rlibs, rmetas, dylibs)? {
+        for (_hash, (rlibs, rmetas, dylibs, interfaces)) in candidates {
+            if let Some((svh, lib)) = self.extract_lib(rlibs, rmetas, dylibs, interfaces)? {
                 libraries.insert(svh, lib);
             }
         }
@@ -508,6 +518,7 @@ impl<'a> CrateLocator<'a> {
         rlibs: FxIndexMap<PathBuf, PathKind>,
         rmetas: FxIndexMap<PathBuf, PathKind>,
         dylibs: FxIndexMap<PathBuf, PathKind>,
+        interfaces: FxIndexMap<PathBuf, PathKind>,
     ) -> Result<Option<(Svh, Library)>, CrateError> {
         let mut slot = None;
         // Order here matters, rmeta should come first.
@@ -515,12 +526,17 @@ impl<'a> CrateLocator<'a> {
         // Make sure there's at most one rlib and at most one dylib.
         //
         // See comment in `extract_one` below.
-        let source = CrateSource {
-            rmeta: self.extract_one(rmetas, CrateFlavor::Rmeta, &mut slot)?,
-            rlib: self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot)?,
-            dylib: self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot)?,
-        };
-        Ok(slot.map(|(svh, metadata, _)| (svh, Library { source, metadata })))
+        let rmeta = self.extract_one(rmetas, CrateFlavor::Rmeta, &mut slot)?;
+        let rlib = self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot)?;
+        let sdylib_interface = self.extract_one(interfaces, CrateFlavor::SDylib, &mut slot)?;
+        let dylib = self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot)?;
+
+        if sdylib_interface.is_some() && dylib.is_none() {
+            return Err(CrateError::FullMetadataNotFound(self.crate_name, CrateFlavor::SDylib));
+        }
+
+        let source = CrateSource { rmeta, rlib, dylib, sdylib_interface };
+        Ok(slot.map(|(svh, metadata, _, _)| (svh, Library { source, metadata })))
     }
 
     fn needs_crate_flavor(&self, flavor: CrateFlavor) -> bool {
@@ -550,7 +566,7 @@ impl<'a> CrateLocator<'a> {
         &mut self,
         m: FxIndexMap<PathBuf, PathKind>,
         flavor: CrateFlavor,
-        slot: &mut Option<(Svh, MetadataBlob, PathBuf)>,
+        slot: &mut Option<(Svh, MetadataBlob, PathBuf, CrateFlavor)>,
     ) -> Result<Option<(PathBuf, PathKind)>, CrateError> {
         // If we are producing an rlib, and we've already loaded metadata, then
         // we should not attempt to discover further crate sources (unless we're
@@ -586,6 +602,7 @@ impl<'a> CrateLocator<'a> {
                 &lib,
                 self.metadata_loader,
                 self.cfg_version,
+                Some(self.crate_name),
             ) {
                 Ok(blob) => {
                     if let Some(h) = self.crate_matches(&blob, &lib) {
@@ -610,6 +627,11 @@ impl<'a> CrateLocator<'a> {
                 }
                 Err(MetadataError::LoadFailure(err)) => {
                     info!("no metadata found: {}", err);
+                    // Metadata was loaded from interface file earlier.
+                    if let Some((.., CrateFlavor::SDylib)) = slot {
+                        ret = Some((lib, kind));
+                        continue;
+                    }
                     // The file was present and created by the same compiler version, but we
                     // couldn't load it for some reason. Give a hard error instead of silently
                     // ignoring it, but only if we would have given an error anyway.
@@ -679,7 +701,7 @@ impl<'a> CrateLocator<'a> {
                     return Err(CrateError::FullMetadataNotFound(self.crate_name, flavor));
                 }
             } else {
-                *slot = Some((hash, metadata, lib.clone()));
+                *slot = Some((hash, metadata, lib.clone(), flavor));
             }
             ret = Some((lib, kind));
         }
@@ -736,6 +758,7 @@ impl<'a> CrateLocator<'a> {
         let mut rlibs = FxIndexMap::default();
         let mut rmetas = FxIndexMap::default();
         let mut dylibs = FxIndexMap::default();
+        let mut sdylib_interfaces = FxIndexMap::default();
         for loc in &self.exact_paths {
             let loc_canon = loc.canonicalized();
             let loc_orig = loc.original();
@@ -763,6 +786,9 @@ impl<'a> CrateLocator<'a> {
                     rmetas.insert(loc_canon.clone(), PathKind::ExternFlag);
                     continue;
                 }
+                if file.ends_with(".rs") {
+                    sdylib_interfaces.insert(loc_canon.clone(), PathKind::ExternFlag);
+                }
             }
             let dll_prefix = self.target.dll_prefix.as_ref();
             let dll_suffix = self.target.dll_suffix.as_ref();
@@ -776,7 +802,8 @@ impl<'a> CrateLocator<'a> {
         }
 
         // Extract the dylib/rlib/rmeta triple.
-        self.extract_lib(rlibs, rmetas, dylibs).map(|opt| opt.map(|(_, lib)| lib))
+        self.extract_lib(rlibs, rmetas, dylibs, sdylib_interfaces)
+            .map(|opt| opt.map(|(_, lib)| lib))
     }
 
     pub(crate) fn into_error(self, dep_root: Option<CratePaths>) -> CrateError {
@@ -797,6 +824,7 @@ fn get_metadata_section<'p>(
     filename: &'p Path,
     loader: &dyn MetadataLoader,
     cfg_version: &'static str,
+    crate_name: Option<Symbol>,
 ) -> Result<MetadataBlob, MetadataError<'p>> {
     if !filename.exists() {
         return Err(MetadataError::NotPresent(filename));
@@ -805,6 +833,55 @@ fn get_metadata_section<'p>(
         CrateFlavor::Rlib => {
             loader.get_rlib_metadata(target, filename).map_err(MetadataError::LoadFailure)?
         }
+        CrateFlavor::SDylib => {
+            let compiler = std::env::current_exe().map_err(|_err| {
+                MetadataError::LoadFailure(
+                    "couldn't obtain current compiler binary when loading sdylib interface"
+                        .to_string(),
+                )
+            })?;
+
+            let tmp_path = match TempFileBuilder::new().prefix("rustc").tempdir() {
+                Ok(tmp_path) => tmp_path,
+                Err(error) => {
+                    return Err(MetadataError::LoadFailure(format!(
+                        "couldn't create a temp dir: {}",
+                        error
+                    )));
+                }
+            };
+
+            let crate_name = crate_name.unwrap();
+            debug!("compiling {}", filename.display());
+            // FIXME: This will need to be done either within the current compiler session or
+            // as a separate compiler session in the same process.
+            let res = std::process::Command::new(compiler)
+                .arg(&filename)
+                .arg("--emit=metadata")
+                .arg(format!("--crate-name={}", crate_name))
+                .arg(format!("--out-dir={}", tmp_path.path().display()))
+                .arg("-Zbuild-sdylib-interface")
+                .output()
+                .map_err(|err| {
+                    MetadataError::LoadFailure(format!("couldn't compile interface: {}", err))
+                })?;
+
+            if !res.status.success() {
+                return Err(MetadataError::LoadFailure(format!(
+                    "couldn't compile interface: {}",
+                    std::str::from_utf8(&res.stderr).unwrap_or_default()
+                )));
+            }
+
+            // Load interface metadata instead of crate metadata.
+            let interface_metadata_name = format!("lib{}.rmeta", crate_name);
+            let rmeta_file = tmp_path.path().join(interface_metadata_name);
+            debug!("loading interface metadata from {}", rmeta_file.display());
+            let rmeta = get_rmeta_metadata_section(&rmeta_file)?;
+            let _ = std::fs::remove_file(rmeta_file);
+
+            rmeta
+        }
         CrateFlavor::Dylib => {
             let buf =
                 loader.get_dylib_metadata(target, filename).map_err(MetadataError::LoadFailure)?;
@@ -834,24 +911,7 @@ fn get_metadata_section<'p>(
             // Header is okay -> inflate the actual metadata
             buf.slice(|buf| &buf[data_start..(data_start + metadata_len)])
         }
-        CrateFlavor::Rmeta => {
-            // mmap the file, because only a small fraction of it is read.
-            let file = std::fs::File::open(filename).map_err(|_| {
-                MetadataError::LoadFailure(format!(
-                    "failed to open rmeta metadata: '{}'",
-                    filename.display()
-                ))
-            })?;
-            let mmap = unsafe { Mmap::map(file) };
-            let mmap = mmap.map_err(|_| {
-                MetadataError::LoadFailure(format!(
-                    "failed to mmap rmeta metadata: '{}'",
-                    filename.display()
-                ))
-            })?;
-
-            slice_owned(mmap, Deref::deref)
-        }
+        CrateFlavor::Rmeta => get_rmeta_metadata_section(filename)?,
     };
     let Ok(blob) = MetadataBlob::new(raw_bytes) else {
         return Err(MetadataError::LoadFailure(format!(
@@ -877,6 +937,25 @@ fn get_metadata_section<'p>(
     }
 }
 
+fn get_rmeta_metadata_section<'a, 'p>(filename: &'p Path) -> Result<OwnedSlice, MetadataError<'a>> {
+    // mmap the file, because only a small fraction of it is read.
+    let file = std::fs::File::open(filename).map_err(|_| {
+        MetadataError::LoadFailure(format!(
+            "failed to open rmeta metadata: '{}'",
+            filename.display()
+        ))
+    })?;
+    let mmap = unsafe { Mmap::map(file) };
+    let mmap = mmap.map_err(|_| {
+        MetadataError::LoadFailure(format!(
+            "failed to mmap rmeta metadata: '{}'",
+            filename.display()
+        ))
+    })?;
+
+    Ok(slice_owned(mmap, Deref::deref))
+}
+
 /// A diagnostic function for dumping crate metadata to an output stream.
 pub fn list_file_metadata(
     target: &Target,
@@ -887,7 +966,7 @@ pub fn list_file_metadata(
     cfg_version: &'static str,
 ) -> IoResult<()> {
     let flavor = get_flavor_from_path(path);
-    match get_metadata_section(target, flavor, path, metadata_loader, cfg_version) {
+    match get_metadata_section(target, flavor, path, metadata_loader, cfg_version, None) {
         Ok(metadata) => metadata.list_crate_metadata(out, ls_kinds),
         Err(msg) => write!(out, "{msg}\n"),
     }
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 3c2245347f9..bd813cadedc 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1489,6 +1489,17 @@ impl<'a> CrateMetadataRef<'a> {
         tcx.arena.alloc_from_iter(self.root.lang_items_missing.decode(self))
     }
 
+    fn get_exportable_items(self) -> impl Iterator<Item = DefId> {
+        self.root.exportable_items.decode(self).map(move |index| self.local_def_id(index))
+    }
+
+    fn get_stable_order_of_exportable_impls(self) -> impl Iterator<Item = (DefId, usize)> {
+        self.root
+            .stable_order_of_exportable_impls
+            .decode(self)
+            .map(move |v| (self.local_def_id(v.0), v.1))
+    }
+
     fn exported_symbols<'tcx>(
         self,
         tcx: TyCtxt<'tcx>,
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index ecc2dcc5318..76bae39ef8c 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -406,6 +406,8 @@ provide! { tcx, def_id, other, cdata,
     used_crate_source => { Arc::clone(&cdata.source) }
     debugger_visualizers => { cdata.get_debugger_visualizers() }
 
+    exportable_items => { tcx.arena.alloc_from_iter(cdata.get_exportable_items()) }
+    stable_order_of_exportable_impls => { tcx.arena.alloc(cdata.get_stable_order_of_exportable_impls().collect()) }
     exported_symbols => {
         let syms = cdata.exported_symbols(tcx);
 
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 3ea61d1b40a..7ac72ef814a 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -551,8 +551,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
             match source_file.name {
                 FileName::Real(ref original_file_name) => {
-                    // FIXME: This should probably to conditionally remapped under
-                    // a RemapPathScopeComponents but which one?
                     let adapted_file_name = source_map
                         .path_mapping()
                         .to_embeddable_absolute_path(original_file_name.clone(), working_directory);
@@ -673,6 +671,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         let debugger_visualizers =
             stat!("debugger-visualizers", || self.encode_debugger_visualizers());
 
+        let exportable_items = stat!("exportable-items", || self.encode_exportable_items());
+
+        let stable_order_of_exportable_impls =
+            stat!("exportable-items", || self.encode_stable_order_of_exportable_impls());
+
         // Encode exported symbols info. This is prefetched in `encode_metadata`.
         let exported_symbols = stat!("exported-symbols", || {
             self.encode_exported_symbols(tcx.exported_symbols(LOCAL_CRATE))
@@ -740,6 +743,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 traits,
                 impls,
                 incoherent_impls,
+                exportable_items,
+                stable_order_of_exportable_impls,
                 exported_symbols,
                 interpret_alloc_index,
                 tables,
@@ -2149,6 +2154,20 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         self.lazy_array(&all_impls)
     }
 
+    fn encode_exportable_items(&mut self) -> LazyArray<DefIndex> {
+        empty_proc_macro!(self);
+        self.lazy_array(self.tcx.exportable_items(LOCAL_CRATE).iter().map(|def_id| def_id.index))
+    }
+
+    fn encode_stable_order_of_exportable_impls(&mut self) -> LazyArray<(DefIndex, usize)> {
+        empty_proc_macro!(self);
+        let stable_order_of_exportable_impls =
+            self.tcx.stable_order_of_exportable_impls(LOCAL_CRATE);
+        self.lazy_array(
+            stable_order_of_exportable_impls.iter().map(|(def_id, idx)| (def_id.index, *idx)),
+        )
+    }
+
     // Encodes all symbols exported from this crate into the metadata.
     //
     // This pass is seeded off the reachability list calculated in the
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 5aa81f41b7b..c86cf567283 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -280,6 +280,8 @@ pub(crate) struct CrateRoot {
     tables: LazyTables,
     debugger_visualizers: LazyArray<DebuggerVisualizerFile>,
 
+    exportable_items: LazyArray<DefIndex>,
+    stable_order_of_exportable_impls: LazyArray<(DefIndex, usize)>,
     exported_symbols: LazyArray<(ExportedSymbol<'static>, SymbolExportInfo)>,
 
     syntax_contexts: SyntaxContextTable,
diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs
index 2dcb0de92b7..a0f45974089 100644
--- a/compiler/rustc_middle/src/arena.rs
+++ b/compiler/rustc_middle/src/arena.rs
@@ -91,6 +91,8 @@ macro_rules! arena_types {
             [] autodiff_item: rustc_ast::expand::autodiff_attrs::AutoDiffItem,
             [] ordered_name_set: rustc_data_structures::fx::FxIndexSet<rustc_span::Symbol>,
             [] valtree: rustc_middle::ty::ValTreeKind<'tcx>,
+            [] stable_order_of_exportable_impls:
+                rustc_data_structures::fx::FxIndexMap<rustc_hir::def_id::DefId, usize>,
 
             // Note that this deliberately duplicates items in the `rustc_hir::arena`,
             // since we need to allocate this type on both the `rustc_hir` arena
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index 711036865bb..979608df79c 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -27,7 +27,6 @@
 // tidy-alphabetical-start
 #![allow(internal_features)]
 #![allow(rustc::diagnostic_outside_of_impl)]
-#![allow(rustc::potential_query_instability)]
 #![allow(rustc::untranslatable_diagnostic)]
 #![cfg_attr(bootstrap, feature(let_chains))]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
diff --git a/compiler/rustc_middle/src/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs
index 3c62017072e..64a1f2aff15 100644
--- a/compiler/rustc_middle/src/middle/exported_symbols.rs
+++ b/compiler/rustc_middle/src/middle/exported_symbols.rs
@@ -22,7 +22,7 @@ impl SymbolExportLevel {
 }
 
 /// Kind of exported symbols.
-#[derive(Eq, PartialEq, Debug, Copy, Clone, Encodable, Decodable, HashStable)]
+#[derive(Eq, PartialEq, Debug, Copy, Clone, Encodable, Decodable, HashStable, Hash)]
 pub enum SymbolExportKind {
     Text,
     Data,
@@ -56,7 +56,7 @@ impl<'tcx> ExportedSymbol<'tcx> {
         match *self {
             ExportedSymbol::NonGeneric(def_id) => tcx.symbol_name(ty::Instance::mono(tcx, def_id)),
             ExportedSymbol::Generic(def_id, args) => {
-                tcx.symbol_name(ty::Instance::new(def_id, args))
+                tcx.symbol_name(ty::Instance::new_raw(def_id, args))
             }
             ExportedSymbol::DropGlue(ty) => {
                 tcx.symbol_name(ty::Instance::resolve_drop_in_place(tcx, ty))
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index e5d1dda3aa0..4a5c42c721c 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -23,7 +23,7 @@ impl<'tcx> TyCtxt<'tcx> {
         // into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are
         // encountered.
         let args = GenericArgs::identity_for_item(self, def_id);
-        let instance = ty::Instance::new(def_id, args);
+        let instance = ty::Instance::new_raw(def_id, args);
         let cid = GlobalId { instance, promoted: None };
         let typing_env = ty::TypingEnv::post_analysis(self, def_id);
         self.const_eval_global_id(typing_env, cid, DUMMY_SP)
@@ -39,7 +39,7 @@ impl<'tcx> TyCtxt<'tcx> {
         // into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are
         // encountered.
         let args = GenericArgs::identity_for_item(self, def_id);
-        let instance = ty::Instance::new(def_id, args);
+        let instance = ty::Instance::new_raw(def_id, args);
         let cid = GlobalId { instance, promoted: None };
         let typing_env = ty::TypingEnv::post_analysis(self, def_id);
         let inputs = self.erase_regions(typing_env.as_query_input(cid));
@@ -209,7 +209,7 @@ impl<'tcx> TyCtxtEnsureOk<'tcx> {
         // into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are
         // encountered.
         let args = GenericArgs::identity_for_item(self.tcx, def_id);
-        let instance = ty::Instance::new(def_id, self.tcx.erase_regions(args));
+        let instance = ty::Instance::new_raw(def_id, self.tcx.erase_regions(args));
         let cid = GlobalId { instance, promoted: None };
         let typing_env = ty::TypingEnv::post_analysis(self.tcx, def_id);
         // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index 6b413a7383a..7243f87ee63 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -318,7 +318,7 @@ impl<'tcx> fmt::Display for MonoItem<'tcx> {
         match *self {
             MonoItem::Fn(instance) => write!(f, "fn {instance}"),
             MonoItem::Static(def_id) => {
-                write!(f, "static {}", Instance::new(def_id, GenericArgs::empty()))
+                write!(f, "static {}", Instance::new_raw(def_id, GenericArgs::empty()))
             }
             MonoItem::GlobalAsm(..) => write!(f, "global_asm"),
         }
diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs
index 8a1ead7d19d..0834fa8844c 100644
--- a/compiler/rustc_middle/src/mir/terminator.rs
+++ b/compiler/rustc_middle/src/mir/terminator.rs
@@ -437,8 +437,8 @@ impl<'tcx> Terminator<'tcx> {
     }
 
     #[inline]
-    pub fn successors_mut(&mut self) -> SuccessorsMut<'_> {
-        self.kind.successors_mut()
+    pub fn successors_mut<'a>(&'a mut self, f: impl FnMut(&'a mut BasicBlock)) {
+        self.kind.successors_mut(f)
     }
 
     #[inline]
@@ -486,7 +486,6 @@ pub use helper::*;
 mod helper {
     use super::*;
     pub type Successors<'a> = impl DoubleEndedIterator<Item = BasicBlock> + 'a;
-    pub type SuccessorsMut<'a> = impl DoubleEndedIterator<Item = &'a mut BasicBlock> + 'a;
 
     impl SwitchTargets {
         /// Like [`SwitchTargets::target_for_value`], but returning the same type as
@@ -560,69 +559,63 @@ mod helper {
         }
 
         #[inline]
-        #[define_opaque(SuccessorsMut)]
-        pub fn successors_mut(&mut self) -> SuccessorsMut<'_> {
+        pub fn successors_mut<'a>(&'a mut self, mut f: impl FnMut(&'a mut BasicBlock)) {
             use self::TerminatorKind::*;
-            match *self {
-                // 3-successors for async drop: target, unwind, dropline (parent coroutine drop)
-                Drop {
-                    target: ref mut t,
-                    unwind: UnwindAction::Cleanup(ref mut u),
-                    drop: Some(ref mut d),
-                    ..
-                } => slice::from_mut(t).into_iter().chain(Some(u).into_iter().chain(Some(d))),
-                // 2-successors
-                Call {
-                    target: Some(ref mut t), unwind: UnwindAction::Cleanup(ref mut u), ..
+            match self {
+                Drop { target, unwind, drop, .. } => {
+                    f(target);
+                    if let UnwindAction::Cleanup(u) = unwind {
+                        f(u)
+                    }
+                    if let Some(d) = drop {
+                        f(d)
+                    }
+                }
+                Call { target, unwind, .. } => {
+                    if let Some(target) = target {
+                        f(target);
+                    }
+                    if let UnwindAction::Cleanup(u) = unwind {
+                        f(u)
+                    }
                 }
-                | Yield { resume: ref mut t, drop: Some(ref mut u), .. }
-                | Drop {
-                    target: ref mut t,
-                    unwind: UnwindAction::Cleanup(ref mut u),
-                    drop: None,
-                    ..
+                Yield { resume, drop, .. } => {
+                    f(resume);
+                    if let Some(d) = drop {
+                        f(d)
+                    }
                 }
-                | Drop { target: ref mut t, unwind: _, drop: Some(ref mut u), .. }
-                | Assert { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. }
-                | FalseUnwind {
-                    real_target: ref mut t,
-                    unwind: UnwindAction::Cleanup(ref mut u),
-                } => slice::from_mut(t).into_iter().chain(Some(u).into_iter().chain(None)),
-                // single successor
-                Goto { target: ref mut t }
-                | Call { target: None, unwind: UnwindAction::Cleanup(ref mut t), .. }
-                | Call { target: Some(ref mut t), unwind: _, .. }
-                | Yield { resume: ref mut t, drop: None, .. }
-                | Drop { target: ref mut t, unwind: _, .. }
-                | Assert { target: ref mut t, unwind: _, .. }
-                | FalseUnwind { real_target: ref mut t, unwind: _ } => {
-                    slice::from_mut(t).into_iter().chain(None.into_iter().chain(None))
+                Assert { target, unwind, .. } | FalseUnwind { real_target: target, unwind } => {
+                    f(target);
+                    if let UnwindAction::Cleanup(u) = unwind {
+                        f(u)
+                    }
+                }
+                Goto { target } => {
+                    f(target);
                 }
-                // No successors
                 UnwindResume
                 | UnwindTerminate(_)
                 | CoroutineDrop
                 | Return
                 | Unreachable
-                | TailCall { .. }
-                | Call { target: None, unwind: _, .. } => {
-                    (&mut []).into_iter().chain(None.into_iter().chain(None))
-                }
-                // Multiple successors
-                InlineAsm { ref mut targets, unwind: UnwindAction::Cleanup(ref mut u), .. } => {
-                    targets.iter_mut().chain(Some(u).into_iter().chain(None))
-                }
-                InlineAsm { ref mut targets, unwind: _, .. } => {
-                    targets.iter_mut().chain(None.into_iter().chain(None))
+                | TailCall { .. } => {}
+                InlineAsm { targets, unwind, .. } => {
+                    for target in targets {
+                        f(target);
+                    }
+                    if let UnwindAction::Cleanup(u) = unwind {
+                        f(u)
+                    }
                 }
-                SwitchInt { ref mut targets, .. } => {
-                    targets.targets.iter_mut().chain(None.into_iter().chain(None))
+                SwitchInt { targets, .. } => {
+                    for target in &mut targets.targets {
+                        f(target);
+                    }
                 }
-                // FalseEdge
-                FalseEdge { ref mut real_target, ref mut imaginary_target } => {
-                    slice::from_mut(real_target)
-                        .into_iter()
-                        .chain(Some(imaginary_target).into_iter().chain(None))
+                FalseEdge { real_target, imaginary_target } => {
+                    f(real_target);
+                    f(imaginary_target);
                 }
             }
         }
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 88f4c4ae4d3..b2133fea08c 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -387,7 +387,7 @@ rustc_queries! {
         }
     }
 
-    query stalled_generators_within(
+    query nested_bodies_within(
         key: LocalDefId
     ) -> &'tcx ty::List<LocalDefId> {
         desc {
@@ -2205,7 +2205,7 @@ rustc_queries! {
     query maybe_unused_trait_imports(_: ()) -> &'tcx FxIndexSet<LocalDefId> {
         desc { "fetching potentially unused trait imports" }
     }
-    query names_imported_by_glob_use(def_id: LocalDefId) -> &'tcx UnordSet<Symbol> {
+    query names_imported_by_glob_use(def_id: LocalDefId) -> &'tcx FxIndexSet<Symbol> {
         desc { |tcx| "finding names imported by glob use for `{}`", tcx.def_path_str(def_id) }
     }
 
@@ -2239,6 +2239,16 @@ rustc_queries! {
         separate_provide_extern
     }
 
+    query stable_order_of_exportable_impls(_: CrateNum) -> &'tcx FxIndexMap<DefId, usize> {
+        desc { "fetching the stable impl's order" }
+        separate_provide_extern
+    }
+
+    query exportable_items(_: CrateNum) -> &'tcx [DefId] {
+        desc { "fetching all exportable items in a crate" }
+        separate_provide_extern
+    }
+
     /// The list of symbols exported from the given crate.
     ///
     /// - All names contained in `exported_symbols(cnum)` are guaranteed to
@@ -2471,7 +2481,7 @@ rustc_queries! {
     query resolve_instance_raw(
         key: ty::PseudoCanonicalInput<'tcx, (DefId, GenericArgsRef<'tcx>)>
     ) -> Result<Option<ty::Instance<'tcx>>, ErrorGuaranteed> {
-        desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) }
+        desc { "resolving instance `{}`", ty::Instance::new_raw(key.value.0, key.value.1) }
     }
 
     query reveal_opaque_types_in_bounds(key: ty::Clauses<'tcx>) -> ty::Clauses<'tcx> {
diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs
index 5431097cb1d..e1876f8f0f9 100644
--- a/compiler/rustc_middle/src/query/on_disk_cache.rs
+++ b/compiler/rustc_middle/src/query/on_disk_cache.rs
@@ -2,7 +2,7 @@ use std::collections::hash_map::Entry;
 use std::mem;
 use std::sync::Arc;
 
-use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
+use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
 use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::sync::{HashMapExt, Lock, RwLock};
 use rustc_data_structures::unhash::UnhashMap;
@@ -57,7 +57,7 @@ pub struct OnDiskCache {
 
     // Collects all `QuerySideEffect` created during the current compilation
     // session.
-    current_side_effects: Lock<FxHashMap<DepNodeIndex, QuerySideEffect>>,
+    current_side_effects: Lock<FxIndexMap<DepNodeIndex, QuerySideEffect>>,
 
     file_index_to_stable_id: FxHashMap<SourceFileIndex, EncodedSourceFileId>,
 
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 3ea285d3d8e..0759fa3da42 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -29,13 +29,12 @@ use rustc_data_structures::steal::Steal;
 use rustc_data_structures::sync::{
     self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
 };
-use rustc_data_structures::unord::UnordSet;
 use rustc_errors::{
     Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, MultiSpan,
 };
 use rustc_hir::def::{CtorKind, DefKind};
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
-use rustc_hir::definitions::Definitions;
+use rustc_hir::definitions::{DefPathData, Definitions, DisambiguatorState};
 use rustc_hir::intravisit::VisitorExt;
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{self as hir, Attribute, HirId, Node, TraitCandidate};
@@ -243,10 +242,18 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
                     ty::AliasTermKind::ProjectionTy
                 }
             }
+            DefKind::AssocConst => {
+                if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
+                {
+                    ty::AliasTermKind::InherentConst
+                } else {
+                    ty::AliasTermKind::ProjectionConst
+                }
+            }
             DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy,
             DefKind::TyAlias => ty::AliasTermKind::FreeTy,
-            DefKind::AssocConst => ty::AliasTermKind::ProjectionConst,
-            DefKind::AnonConst | DefKind::Const | DefKind::Ctor(_, CtorKind::Const) => {
+            DefKind::Const => ty::AliasTermKind::FreeConst,
+            DefKind::AnonConst | DefKind::Ctor(_, CtorKind::Const) => {
                 ty::AliasTermKind::UnevaluatedConst
             }
             kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
@@ -684,15 +691,17 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
         self.opaque_types_defined_by(defining_anchor)
     }
 
-    fn opaque_types_and_generators_defined_by(
+    fn opaque_types_and_coroutines_defined_by(
         self,
         defining_anchor: Self::LocalDefId,
     ) -> Self::LocalDefIds {
         if self.next_trait_solver_globally() {
+            let coroutines_defined_by = self
+                .nested_bodies_within(defining_anchor)
+                .iter()
+                .filter(|def_id| self.is_coroutine(def_id.to_def_id()));
             self.mk_local_def_ids_from_iter(
-                self.opaque_types_defined_by(defining_anchor)
-                    .iter()
-                    .chain(self.stalled_generators_within(defining_anchor)),
+                self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
             )
         } else {
             self.opaque_types_defined_by(defining_anchor)
@@ -1820,9 +1829,10 @@ impl<'tcx> TyCtxt<'tcx> {
         self.crate_types()
             .iter()
             .map(|ty| match *ty {
-                CrateType::Executable | CrateType::Staticlib | CrateType::Cdylib => {
-                    MetadataKind::None
-                }
+                CrateType::Executable
+                | CrateType::Staticlib
+                | CrateType::Cdylib
+                | CrateType::Sdylib => MetadataKind::None,
                 CrateType::Rlib => MetadataKind::Uncompressed,
                 CrateType::Dylib | CrateType::ProcMacro => MetadataKind::Compressed,
             })
@@ -1969,8 +1979,11 @@ impl<'tcx> TyCtxtAt<'tcx> {
         parent: LocalDefId,
         name: Option<Symbol>,
         def_kind: DefKind,
+        override_def_path_data: Option<DefPathData>,
+        disambiguator: &mut DisambiguatorState,
     ) -> TyCtxtFeed<'tcx, LocalDefId> {
-        let feed = self.tcx.create_def(parent, name, def_kind);
+        let feed =
+            self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
 
         feed.def_span(self.span);
         feed
@@ -1984,8 +1997,10 @@ impl<'tcx> TyCtxt<'tcx> {
         parent: LocalDefId,
         name: Option<Symbol>,
         def_kind: DefKind,
+        override_def_path_data: Option<DefPathData>,
+        disambiguator: &mut DisambiguatorState,
     ) -> TyCtxtFeed<'tcx, LocalDefId> {
-        let data = def_kind.def_path_data(name);
+        let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
         // The following call has the side effect of modifying the tables inside `definitions`.
         // These very tables are relied on by the incr. comp. engine to decode DepNodes and to
         // decode the on-disk cache.
@@ -1995,12 +2010,7 @@ impl<'tcx> TyCtxt<'tcx> {
         // - has been created by this call to `create_def`.
         // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
         // comp. engine itself.
-        //
-        // This call also writes to the value of the `source_span` query.
-        // This is fine because:
-        // - that query is `eval_always` so we won't miss its result changing;
-        // - this write will have happened before that query is called.
-        let def_id = self.untracked.definitions.write().create_def(parent, data);
+        let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
 
         // This function modifies `self.definitions` using a side-effect.
         // We need to ensure that these side effects are re-run by the incr. comp. engine.
@@ -2125,7 +2135,8 @@ impl<'tcx> TyCtxt<'tcx> {
                 CrateType::Executable
                 | CrateType::Staticlib
                 | CrateType::ProcMacro
-                | CrateType::Cdylib => false,
+                | CrateType::Cdylib
+                | CrateType::Sdylib => false,
 
                 // FIXME rust-lang/rust#64319, rust-lang/rust#64872:
                 // We want to block export of generics from dylibs,
@@ -2413,6 +2424,8 @@ macro_rules! sty_debug_print {
                 $(let mut $variant = total;)*
 
                 for shard in tcx.interners.type_.lock_shards() {
+                    // It seems that ordering doesn't affect anything here.
+                    #[allow(rustc::potential_query_instability)]
                     let types = shard.iter();
                     for &(InternedInSet(t), ()) in types {
                         let variant = match t.internee {
@@ -3307,6 +3320,10 @@ impl<'tcx> TyCtxt<'tcx> {
             && self.impl_trait_header(def_id).unwrap().constness == hir::Constness::Const
     }
 
+    pub fn is_sdylib_interface_build(self) -> bool {
+        self.sess.opts.unstable_opts.build_sdylib_interface
+    }
+
     pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
         match self.def_kind(def_id) {
             DefKind::Fn | DefKind::AssocFn => {}
@@ -3399,9 +3416,7 @@ pub fn provide(providers: &mut Providers) {
     providers.maybe_unused_trait_imports =
         |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
     providers.names_imported_by_glob_use = |tcx, id| {
-        tcx.arena.alloc(UnordSet::from(
-            tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default(),
-        ))
+        tcx.arena.alloc(tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default())
     };
 
     providers.extern_mod_stmt_cnum =
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index fbb57b8df6b..b122ada0925 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -3,7 +3,7 @@
 use std::fmt::Write;
 use std::ops::ControlFlow;
 
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::{
     Applicability, Diag, DiagArgValue, IntoDiagArg, into_diag_arg_using_display, listify, pluralize,
 };
@@ -287,7 +287,7 @@ pub fn suggest_constraining_type_params<'a>(
     param_names_and_constraints: impl Iterator<Item = (&'a str, &'a str, Option<DefId>)>,
     span_to_replace: Option<Span>,
 ) -> bool {
-    let mut grouped = FxHashMap::default();
+    let mut grouped = FxIndexMap::default();
     let mut unstable_suggestion = false;
     param_names_and_constraints.for_each(|(param_name, constraint, def_id)| {
         let stable = match def_id {
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index d660e7d0d60..0d99a1b5149 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -491,7 +491,15 @@ fn resolve_async_drop_poll<'tcx>(mut cor_ty: Ty<'tcx>) -> Instance<'tcx> {
 }
 
 impl<'tcx> Instance<'tcx> {
-    pub fn new(def_id: DefId, args: GenericArgsRef<'tcx>) -> Instance<'tcx> {
+    /// Creates a new [`InstanceKind::Item`] from the `def_id` and `args`.
+    ///
+    /// Note that this item corresponds to the body of `def_id` directly, which
+    /// likely does not make sense for trait items which need to be resolved to an
+    /// implementation, and which may not even have a body themselves. Usages of
+    /// this function should probably use [`Instance::expect_resolve`], or if run
+    /// in a polymorphic environment or within a lint (that may encounter ambiguity)
+    /// [`Instance::try_resolve`] instead.
+    pub fn new_raw(def_id: DefId, args: GenericArgsRef<'tcx>) -> Instance<'tcx> {
         assert!(
             !args.has_escaping_bound_vars(),
             "args of instance {def_id:?} has escaping bound vars: {args:?}"
@@ -510,7 +518,7 @@ impl<'tcx> Instance<'tcx> {
             }
         });
 
-        Instance::new(def_id, args)
+        Instance::new_raw(def_id, args)
     }
 
     #[inline]
@@ -603,7 +611,7 @@ impl<'tcx> Instance<'tcx> {
                 let type_length = type_length(args);
                 if !tcx.type_length_limit().value_within_limit(type_length) {
                     let (shrunk, written_to_path) =
-                        shrunk_instance_name(tcx, Instance::new(def_id, args));
+                        shrunk_instance_name(tcx, Instance::new_raw(def_id, args));
                     let mut path = PathBuf::new();
                     let was_written = if let Some(path2) = written_to_path {
                         path = path2;
@@ -773,7 +781,7 @@ impl<'tcx> Instance<'tcx> {
 
         match needs_fn_once_adapter_shim(actual_kind, requested_kind) {
             Ok(true) => Instance::fn_once_adapter_instance(tcx, def_id, args),
-            _ => Instance::new(def_id, args),
+            _ => Instance::new_raw(def_id, args),
         }
     }
 
@@ -899,7 +907,7 @@ impl<'tcx> Instance<'tcx> {
             // This is important for `Iterator`'s combinators, but also useful for
             // adding future default methods to `Future`, for instance.
             debug_assert!(tcx.defaultness(trait_item_id).has_value());
-            Some(Instance::new(trait_item_id, rcvr_args))
+            Some(Instance::new_raw(trait_item_id, rcvr_args))
         }
     }
 
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 2f4c03f0953..2d69a1c2b55 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -38,6 +38,7 @@ use rustc_errors::{Diag, ErrorGuaranteed};
 use rustc_hir::LangItem;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
+use rustc_hir::definitions::DisambiguatorState;
 use rustc_index::IndexVec;
 use rustc_index::bit_set::BitMatrix;
 use rustc_macros::{
@@ -50,9 +51,17 @@ use rustc_session::lint::LintBuffer;
 pub use rustc_session::lint::RegisteredTools;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::{DUMMY_SP, ExpnId, ExpnKind, Ident, Span, Symbol, kw, sym};
-pub use rustc_type_ir::data_structures::DelayedSet;
+pub use rustc_type_ir::data_structures::{DelayedMap, DelayedSet};
+#[allow(
+    hidden_glob_reexports,
+    rustc::usage_of_type_ir_inherent,
+    rustc::non_glob_import_of_type_ir_inherent
+)]
+use rustc_type_ir::inherent;
 pub use rustc_type_ir::relate::VarianceDiagInfo;
 pub use rustc_type_ir::*;
+#[allow(hidden_glob_reexports, unused_imports)]
+use rustc_type_ir::{InferCtxtLike, Interner};
 use tracing::{debug, instrument};
 pub use vtable::*;
 use {rustc_ast as ast, rustc_attr_data_structures as attr, rustc_hir as hir};
@@ -173,7 +182,7 @@ pub struct ResolverGlobalCtxt {
     pub extern_crate_map: UnordMap<LocalDefId, CrateNum>,
     pub maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
     pub module_children: LocalDefIdMap<Vec<ModChild>>,
-    pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
+    pub glob_map: FxIndexMap<LocalDefId, FxIndexSet<Symbol>>,
     pub main_def: Option<MainDefinition>,
     pub trait_impls: FxIndexMap<DefId, Vec<LocalDefId>>,
     /// A list of proc macro LocalDefIds, written out in the order in which
@@ -209,6 +218,8 @@ pub struct ResolverAstLowering {
 
     pub node_id_to_def_id: NodeMap<LocalDefId>,
 
+    pub disambiguator: DisambiguatorState,
+
     pub trait_map: NodeMap<Vec<hir::TraitCandidate>>,
     /// List functions and methods for which lifetime elision was successful.
     pub lifetime_elision_allowed: FxHashSet<ast::NodeId>,
@@ -298,7 +309,10 @@ impl Visibility {
                 } else if restricted_id == tcx.parent_module_from_def_id(def_id).to_local_def_id() {
                     "pub(self)".to_string()
                 } else {
-                    format!("pub({})", tcx.item_name(restricted_id.to_def_id()))
+                    format!(
+                        "pub(in crate{})",
+                        tcx.def_path(restricted_id.to_def_id()).to_string_no_crate_verbose()
+                    )
                 }
             }
             ty::Visibility::Public => "pub".to_string(),
@@ -1929,13 +1943,17 @@ impl<'tcx> TyCtxt<'tcx> {
             if arg_cor_ty.is_coroutine() {
                 let span = self.def_span(def_id);
                 let source_info = SourceInfo::outermost(span);
+                // Even minimal, empty coroutine has 3 states (RESERVED_VARIANTS),
+                // so variant_fields and variant_source_info should have 3 elements.
                 let variant_fields: IndexVec<VariantIdx, IndexVec<FieldIdx, CoroutineSavedLocal>> =
                     iter::repeat(IndexVec::new()).take(CoroutineArgs::RESERVED_VARIANTS).collect();
+                let variant_source_info: IndexVec<VariantIdx, SourceInfo> =
+                    iter::repeat(source_info).take(CoroutineArgs::RESERVED_VARIANTS).collect();
                 let proxy_layout = CoroutineLayout {
                     field_tys: [].into(),
                     field_names: [].into(),
                     variant_fields,
-                    variant_source_info: [source_info].into(),
+                    variant_source_info,
                     storage_conflicts: BitMatrix::new(0, 0),
                 };
                 return Some(self.arena.alloc(proxy_layout));
@@ -1978,6 +1996,10 @@ impl<'tcx> TyCtxt<'tcx> {
         None
     }
 
+    pub fn is_exportable(self, def_id: DefId) -> bool {
+        self.exportable_items(def_id.krate).contains(&def_id)
+    }
+
     /// Check if the given `DefId` is `#\[automatically_derived\]`, *and*
     /// whether it was produced by expanding a builtin derive macro.
     pub fn is_builtin_derived(self, def_id: DefId) -> bool {
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index ad8677f7c7d..0250c777faf 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -6,7 +6,7 @@ use std::ops::{Deref, DerefMut};
 use rustc_abi::{ExternAbi, Size};
 use rustc_apfloat::Float;
 use rustc_apfloat::ieee::{Double, Half, Quad, Single};
-use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
+use rustc_data_structures::fx::{FxIndexMap, IndexEntry};
 use rustc_data_structures::unord::UnordMap;
 use rustc_hir as hir;
 use rustc_hir::LangItem;
@@ -2934,7 +2934,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
 
     fn prepare_region_info<T>(&mut self, value: &ty::Binder<'tcx, T>)
     where
-        T: TypeVisitable<TyCtxt<'tcx>>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         struct RegionNameCollector<'tcx> {
             used_region_names: FxHashSet<Symbol>,
@@ -3195,7 +3195,7 @@ define_print! {
 
     ty::AliasTerm<'tcx> {
         match self.kind(cx.tcx()) {
-            ty::AliasTermKind::InherentTy => p!(pretty_print_inherent_projection(*self)),
+            ty::AliasTermKind::InherentTy | ty::AliasTermKind::InherentConst => p!(pretty_print_inherent_projection(*self)),
             ty::AliasTermKind::ProjectionTy => {
                 if !(cx.should_print_verbose() || with_reduced_queries())
                     && cx.tcx().is_impl_trait_in_trait(self.def_id)
@@ -3205,7 +3205,8 @@ define_print! {
                     p!(print_def_path(self.def_id, self.args));
                 }
             }
-            | ty::AliasTermKind::FreeTy
+            ty::AliasTermKind::FreeTy
+            | ty::AliasTermKind::FreeConst
             | ty::AliasTermKind::OpaqueTy
             | ty::AliasTermKind::UnevaluatedConst
             | ty::AliasTermKind::ProjectionConst => {
@@ -3496,8 +3497,8 @@ pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> DefIdMap<Symbol> {
 
     // Once constructed, unique namespace+symbol pairs will have a `Some(_)` entry, while
     // non-unique pairs will have a `None` entry.
-    let unique_symbols_rev: &mut FxHashMap<(Namespace, Symbol), Option<DefId>> =
-        &mut FxHashMap::default();
+    let unique_symbols_rev: &mut FxIndexMap<(Namespace, Symbol), Option<DefId>> =
+        &mut FxIndexMap::default();
 
     for symbol_set in tcx.resolutions(()).glob_map.values() {
         for symbol in symbol_set {
@@ -3507,27 +3508,23 @@ pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> DefIdMap<Symbol> {
         }
     }
 
-    for_each_def(tcx, |ident, ns, def_id| {
-        use std::collections::hash_map::Entry::{Occupied, Vacant};
-
-        match unique_symbols_rev.entry((ns, ident.name)) {
-            Occupied(mut v) => match v.get() {
-                None => {}
-                Some(existing) => {
-                    if *existing != def_id {
-                        v.insert(None);
-                    }
+    for_each_def(tcx, |ident, ns, def_id| match unique_symbols_rev.entry((ns, ident.name)) {
+        IndexEntry::Occupied(mut v) => match v.get() {
+            None => {}
+            Some(existing) => {
+                if *existing != def_id {
+                    v.insert(None);
                 }
-            },
-            Vacant(v) => {
-                v.insert(Some(def_id));
             }
+        },
+        IndexEntry::Vacant(v) => {
+            v.insert(Some(def_id));
         }
     });
 
     // Put the symbol from all the unique namespace+symbol pairs into `map`.
     let mut map: DefIdMap<Symbol> = Default::default();
-    for ((_, symbol), opt_def_id) in unique_symbols_rev.drain() {
+    for ((_, symbol), opt_def_id) in unique_symbols_rev.drain(..) {
         use std::collections::hash_map::Entry::{Occupied, Vacant};
 
         if let Some(def_id) = opt_def_id {
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 2165cf186bd..c31ce1bc630 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -723,7 +723,10 @@ impl<'tcx> Ty<'tcx> {
         repr: DynKind,
     ) -> Ty<'tcx> {
         if cfg!(debug_assertions) {
-            let projection_count = obj.projection_bounds().count();
+            let projection_count = obj
+                .projection_bounds()
+                .filter(|item| !tcx.generics_require_sized_self(item.item_def_id()))
+                .count();
             let expected_count: usize = obj
                 .principal_def_id()
                 .into_iter()
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index f5158edffcf..6fe5927c29f 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -966,7 +966,9 @@ impl<'tcx> TyCtxt<'tcx> {
             }
             ty::AliasTermKind::OpaqueTy => Some(self.variances_of(def_id)),
             ty::AliasTermKind::InherentTy
+            | ty::AliasTermKind::InherentConst
             | ty::AliasTermKind::FreeTy
+            | ty::AliasTermKind::FreeConst
             | ty::AliasTermKind::UnevaluatedConst
             | ty::AliasTermKind::ProjectionConst => None,
         }
diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs
index 3853a804a92..f8042174599 100644
--- a/compiler/rustc_middle/src/ty/visit.rs
+++ b/compiler/rustc_middle/src/ty/visit.rs
@@ -66,7 +66,7 @@ impl<'tcx> TyCtxt<'tcx> {
         {
             type Result = ControlFlow<()>;
 
-            fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
+            fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
                 &mut self,
                 t: &Binder<'tcx, T>,
             ) -> Self::Result {
@@ -168,7 +168,7 @@ impl LateBoundRegionsCollector {
 }
 
 impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for LateBoundRegionsCollector {
-    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) {
+    fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) {
         self.current_index.shift_in(1);
         t.super_visit_with(self);
         self.current_index.shift_out(1);
diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs
index 59a52ae67cb..9cf051a8760 100644
--- a/compiler/rustc_mir_build/src/builder/mod.rs
+++ b/compiler/rustc_mir_build/src/builder/mod.rs
@@ -998,7 +998,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             self.source_scope = source_scope;
         }
 
-        if self.tcx.intrinsic(self.def_id).is_some_and(|i| i.must_be_overridden) {
+        if self.tcx.intrinsic(self.def_id).is_some_and(|i| i.must_be_overridden)
+            || self.tcx.is_sdylib_interface_build()
+        {
             let source_info = self.source_info(rustc_span::DUMMY_SP);
             self.cfg.terminate(block, source_info, TerminatorKind::Unreachable);
             self.cfg.start_new_block().unit()
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 8e69ff568b9..fcd106d78e2 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -553,8 +553,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         let res = self.typeck_results.qpath_res(qpath, id);
 
         let (def_id, user_ty) = match res {
-            Res::Def(DefKind::Const, def_id) => (def_id, None),
-            Res::Def(DefKind::AssocConst, def_id) => {
+            Res::Def(DefKind::Const, def_id) | Res::Def(DefKind::AssocConst, def_id) => {
                 (def_id, self.typeck_results.user_provided_types().get(id))
             }
 
@@ -568,6 +567,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
 
         // Lower the named constant to a THIR pattern.
         let args = self.typeck_results.node_args(id);
+        // FIXME(mgca): we will need to special case IACs here to have type system compatible
+        // generic args, instead of how we represent them in body expressions.
         let c = ty::Const::new_unevaluated(self.tcx, ty::UnevaluatedConst { def: def_id, args });
         let mut pattern = self.const_to_pat(c, ty, id, span);
 
diff --git a/compiler/rustc_mir_dataflow/src/framework/cursor.rs b/compiler/rustc_mir_dataflow/src/framework/cursor.rs
index d5005768b80..3f6e7a06619 100644
--- a/compiler/rustc_mir_dataflow/src/framework/cursor.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/cursor.rs
@@ -1,5 +1,6 @@
 //! Random access inspection of the results of a dataflow analysis.
 
+use std::borrow::Cow;
 use std::cmp::Ordering;
 use std::ops::{Deref, DerefMut};
 
@@ -9,38 +10,30 @@ use rustc_middle::mir::{self, BasicBlock, Location};
 
 use super::{Analysis, Direction, Effect, EffectIndex, Results};
 
-/// Some `ResultsCursor`s want to own a `Results`, and some want to borrow a `Results`, either
-/// mutable or immutably. This type allows all of the above. It's similar to `Cow`.
-pub enum ResultsHandle<'a, 'tcx, A>
-where
-    A: Analysis<'tcx>,
-{
-    BorrowedMut(&'a mut Results<'tcx, A>),
-    Owned(Results<'tcx, A>),
+/// Some `ResultsCursor`s want to own an `Analysis`, and some want to borrow an `Analysis`, either
+/// mutable or immutably. This type allows all of the above. It's similar to `Cow`, but `Cow`
+/// doesn't allow mutable borrowing.
+enum CowMut<'a, T> {
+    BorrowedMut(&'a mut T),
+    Owned(T),
 }
 
-impl<'tcx, A> Deref for ResultsHandle<'_, 'tcx, A>
-where
-    A: Analysis<'tcx>,
-{
-    type Target = Results<'tcx, A>;
+impl<T> Deref for CowMut<'_, T> {
+    type Target = T;
 
-    fn deref(&self) -> &Results<'tcx, A> {
+    fn deref(&self) -> &T {
         match self {
-            ResultsHandle::BorrowedMut(borrowed) => borrowed,
-            ResultsHandle::Owned(owned) => owned,
+            CowMut::BorrowedMut(borrowed) => borrowed,
+            CowMut::Owned(owned) => owned,
         }
     }
 }
 
-impl<'tcx, A> DerefMut for ResultsHandle<'_, 'tcx, A>
-where
-    A: Analysis<'tcx>,
-{
-    fn deref_mut(&mut self) -> &mut Results<'tcx, A> {
+impl<T> DerefMut for CowMut<'_, T> {
+    fn deref_mut(&mut self) -> &mut T {
         match self {
-            ResultsHandle::BorrowedMut(borrowed) => borrowed,
-            ResultsHandle::Owned(owned) => owned,
+            CowMut::BorrowedMut(borrowed) => borrowed,
+            CowMut::Owned(owned) => owned,
         }
     }
 }
@@ -60,7 +53,8 @@ where
     A: Analysis<'tcx>,
 {
     body: &'mir mir::Body<'tcx>,
-    results: ResultsHandle<'mir, 'tcx, A>,
+    analysis: CowMut<'mir, A>,
+    results: Cow<'mir, Results<A::Domain>>,
     state: A::Domain,
 
     pos: CursorPosition,
@@ -88,11 +82,15 @@ where
         self.body
     }
 
-    /// Returns a new cursor that can inspect `results`.
-    pub fn new(body: &'mir mir::Body<'tcx>, results: ResultsHandle<'mir, 'tcx, A>) -> Self {
-        let bottom_value = results.analysis.bottom_value(body);
+    fn new(
+        body: &'mir mir::Body<'tcx>,
+        analysis: CowMut<'mir, A>,
+        results: Cow<'mir, Results<A::Domain>>,
+    ) -> Self {
+        let bottom_value = analysis.bottom_value(body);
         ResultsCursor {
             body,
+            analysis,
             results,
 
             // Initialize to the `bottom_value` and set `state_needs_reset` to tell the cursor that
@@ -107,6 +105,24 @@ where
         }
     }
 
+    /// Returns a new cursor that takes ownership of and inspects analysis results.
+    pub fn new_owning(
+        body: &'mir mir::Body<'tcx>,
+        analysis: A,
+        results: Results<A::Domain>,
+    ) -> Self {
+        Self::new(body, CowMut::Owned(analysis), Cow::Owned(results))
+    }
+
+    /// Returns a new cursor that borrows and inspects analysis results.
+    pub fn new_borrowing(
+        body: &'mir mir::Body<'tcx>,
+        analysis: &'mir mut A,
+        results: &'mir Results<A::Domain>,
+    ) -> Self {
+        Self::new(body, CowMut::BorrowedMut(analysis), Cow::Borrowed(results))
+    }
+
     /// Allows inspection of unreachable basic blocks even with `debug_assertions` enabled.
     #[cfg(test)]
     pub(crate) fn allow_unreachable(&mut self) {
@@ -116,7 +132,7 @@ where
 
     /// Returns the `Analysis` used to generate the underlying `Results`.
     pub fn analysis(&self) -> &A {
-        &self.results.analysis
+        &self.analysis
     }
 
     /// Resets the cursor to hold the entry set for the given basic block.
@@ -128,7 +144,7 @@ where
         #[cfg(debug_assertions)]
         assert!(self.reachable_blocks.contains(block));
 
-        self.state.clone_from(self.results.entry_set_for_block(block));
+        self.state.clone_from(&self.results[block]);
         self.pos = CursorPosition::block_entry(block);
         self.state_needs_reset = false;
     }
@@ -220,7 +236,7 @@ where
         let target_effect_index = effect.at_index(target.statement_index);
 
         A::Direction::apply_effects_in_range(
-            &mut self.results.analysis,
+            &mut *self.analysis,
             &mut self.state,
             target.block,
             block_data,
@@ -236,7 +252,7 @@ where
     /// This can be used, e.g., to apply the call return effect directly to the cursor without
     /// creating an extra copy of the dataflow state.
     pub fn apply_custom_effect(&mut self, f: impl FnOnce(&mut A, &mut A::Domain)) {
-        f(&mut self.results.analysis, &mut self.state);
+        f(&mut self.analysis, &mut self.state);
         self.state_needs_reset = true;
     }
 }
diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs
index b8c26dad59f..e955e38ad10 100644
--- a/compiler/rustc_mir_dataflow/src/framework/direction.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs
@@ -5,7 +5,7 @@ use rustc_middle::mir::{
 };
 
 use super::visitor::ResultsVisitor;
-use super::{Analysis, Effect, EffectIndex, Results};
+use super::{Analysis, Effect, EffectIndex};
 
 pub trait Direction {
     const IS_FORWARD: bool;
@@ -36,13 +36,13 @@ pub trait Direction {
         A: Analysis<'tcx>;
 
     /// Called by `ResultsVisitor` to recompute the analysis domain values for
-    /// all locations in a basic block (starting from the entry value stored
-    /// in `Results`) and to visit them with `vis`.
+    /// all locations in a basic block (starting from `entry_state` and to
+    /// visit them with `vis`.
     fn visit_results_in_block<'mir, 'tcx, A>(
         state: &mut A::Domain,
         block: BasicBlock,
         block_data: &'mir mir::BasicBlockData<'tcx>,
-        results: &mut Results<'tcx, A>,
+        analysis: &mut A,
         vis: &mut impl ResultsVisitor<'tcx, A>,
     ) where
         A: Analysis<'tcx>;
@@ -211,28 +211,26 @@ impl Direction for Backward {
         state: &mut A::Domain,
         block: BasicBlock,
         block_data: &'mir mir::BasicBlockData<'tcx>,
-        results: &mut Results<'tcx, A>,
+        analysis: &mut A,
         vis: &mut impl ResultsVisitor<'tcx, A>,
     ) where
         A: Analysis<'tcx>,
     {
-        state.clone_from(results.entry_set_for_block(block));
-
         vis.visit_block_end(state);
 
         let loc = Location { block, statement_index: block_data.statements.len() };
         let term = block_data.terminator();
-        results.analysis.apply_early_terminator_effect(state, term, loc);
-        vis.visit_after_early_terminator_effect(results, state, term, loc);
-        results.analysis.apply_primary_terminator_effect(state, term, loc);
-        vis.visit_after_primary_terminator_effect(results, state, term, loc);
+        analysis.apply_early_terminator_effect(state, term, loc);
+        vis.visit_after_early_terminator_effect(analysis, state, term, loc);
+        analysis.apply_primary_terminator_effect(state, term, loc);
+        vis.visit_after_primary_terminator_effect(analysis, state, term, loc);
 
         for (statement_index, stmt) in block_data.statements.iter().enumerate().rev() {
             let loc = Location { block, statement_index };
-            results.analysis.apply_early_statement_effect(state, stmt, loc);
-            vis.visit_after_early_statement_effect(results, state, stmt, loc);
-            results.analysis.apply_primary_statement_effect(state, stmt, loc);
-            vis.visit_after_primary_statement_effect(results, state, stmt, loc);
+            analysis.apply_early_statement_effect(state, stmt, loc);
+            vis.visit_after_early_statement_effect(analysis, state, stmt, loc);
+            analysis.apply_primary_statement_effect(state, stmt, loc);
+            vis.visit_after_primary_statement_effect(analysis, state, stmt, loc);
         }
 
         vis.visit_block_start(state);
@@ -393,29 +391,27 @@ impl Direction for Forward {
         state: &mut A::Domain,
         block: BasicBlock,
         block_data: &'mir mir::BasicBlockData<'tcx>,
-        results: &mut Results<'tcx, A>,
+        analysis: &mut A,
         vis: &mut impl ResultsVisitor<'tcx, A>,
     ) where
         A: Analysis<'tcx>,
     {
-        state.clone_from(results.entry_set_for_block(block));
-
         vis.visit_block_start(state);
 
         for (statement_index, stmt) in block_data.statements.iter().enumerate() {
             let loc = Location { block, statement_index };
-            results.analysis.apply_early_statement_effect(state, stmt, loc);
-            vis.visit_after_early_statement_effect(results, state, stmt, loc);
-            results.analysis.apply_primary_statement_effect(state, stmt, loc);
-            vis.visit_after_primary_statement_effect(results, state, stmt, loc);
+            analysis.apply_early_statement_effect(state, stmt, loc);
+            vis.visit_after_early_statement_effect(analysis, state, stmt, loc);
+            analysis.apply_primary_statement_effect(state, stmt, loc);
+            vis.visit_after_primary_statement_effect(analysis, state, stmt, loc);
         }
 
         let loc = Location { block, statement_index: block_data.statements.len() };
         let term = block_data.terminator();
-        results.analysis.apply_early_terminator_effect(state, term, loc);
-        vis.visit_after_early_terminator_effect(results, state, term, loc);
-        results.analysis.apply_primary_terminator_effect(state, term, loc);
-        vis.visit_after_primary_terminator_effect(results, state, term, loc);
+        analysis.apply_early_terminator_effect(state, term, loc);
+        vis.visit_after_early_terminator_effect(analysis, state, term, loc);
+        analysis.apply_primary_terminator_effect(state, term, loc);
+        vis.visit_after_primary_terminator_effect(analysis, state, term, loc);
 
         vis.visit_block_end(state);
     }
diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
index b5e9a0b8932..a7d5422a3d7 100644
--- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
@@ -21,7 +21,9 @@ use tracing::debug;
 use {rustc_ast as ast, rustc_graphviz as dot};
 
 use super::fmt::{DebugDiffWithAdapter, DebugWithAdapter, DebugWithContext};
-use super::{Analysis, CallReturnPlaces, Direction, Results, ResultsCursor, ResultsVisitor};
+use super::{
+    Analysis, CallReturnPlaces, Direction, Results, ResultsCursor, ResultsVisitor, visit_results,
+};
 use crate::errors::{
     DuplicateValuesFor, PathMustEndInFilename, RequiresAnArgument, UnknownFormatter,
 };
@@ -32,7 +34,8 @@ use crate::errors::{
 pub(super) fn write_graphviz_results<'tcx, A>(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
-    results: &mut Results<'tcx, A>,
+    analysis: &mut A,
+    results: &Results<A::Domain>,
     pass_name: Option<&'static str>,
 ) -> std::io::Result<()>
 where
@@ -77,7 +80,7 @@ where
 
     let mut buf = Vec::new();
 
-    let graphviz = Formatter::new(body, results, style);
+    let graphviz = Formatter::new(body, analysis, results, style);
     let mut render_opts =
         vec![dot::RenderOption::Fontname(tcx.sess.opts.unstable_opts.graphviz_font.clone())];
     if tcx.sess.opts.unstable_opts.graphviz_dark_mode {
@@ -203,10 +206,11 @@ where
 {
     body: &'mir Body<'tcx>,
     // The `RefCell` is used because `<Formatter as Labeller>::node_label`
-    // takes `&self`, but it needs to modify the results. This is also the
+    // takes `&self`, but it needs to modify the analysis. This is also the
     // reason for the `Formatter`/`BlockFormatter` split; `BlockFormatter` has
     // the operations that involve the mutation, i.e. within the `borrow_mut`.
-    results: RefCell<&'mir mut Results<'tcx, A>>,
+    analysis: RefCell<&'mir mut A>,
+    results: &'mir Results<A::Domain>,
     style: OutputStyle,
     reachable: DenseBitSet<BasicBlock>,
 }
@@ -217,11 +221,12 @@ where
 {
     fn new(
         body: &'mir Body<'tcx>,
-        results: &'mir mut Results<'tcx, A>,
+        analysis: &'mir mut A,
+        results: &'mir Results<A::Domain>,
         style: OutputStyle,
     ) -> Self {
         let reachable = traversal::reachable_as_bitset(body);
-        Formatter { body, results: results.into(), style, reachable }
+        Formatter { body, analysis: analysis.into(), results, style, reachable }
     }
 }
 
@@ -259,12 +264,12 @@ where
     }
 
     fn node_label(&self, block: &Self::Node) -> dot::LabelText<'_> {
-        let mut results = self.results.borrow_mut();
+        let analysis = &mut **self.analysis.borrow_mut();
 
-        let diffs = StateDiffCollector::run(self.body, *block, *results, self.style);
+        let diffs = StateDiffCollector::run(self.body, *block, analysis, self.results, self.style);
 
         let mut fmt = BlockFormatter {
-            cursor: results.as_results_cursor(self.body),
+            cursor: ResultsCursor::new_borrowing(self.body, analysis, self.results),
             style: self.style,
             bg: Background::Light,
         };
@@ -692,7 +697,8 @@ impl<D> StateDiffCollector<D> {
     fn run<'tcx, A>(
         body: &Body<'tcx>,
         block: BasicBlock,
-        results: &mut Results<'tcx, A>,
+        analysis: &mut A,
+        results: &Results<A::Domain>,
         style: OutputStyle,
     ) -> Self
     where
@@ -700,12 +706,12 @@ impl<D> StateDiffCollector<D> {
         D: DebugWithContext<A>,
     {
         let mut collector = StateDiffCollector {
-            prev_state: results.analysis.bottom_value(body),
+            prev_state: analysis.bottom_value(body),
             after: vec![],
             before: (style == OutputStyle::BeforeAndAfter).then_some(vec![]),
         };
 
-        results.visit_with(body, std::iter::once(block), &mut collector);
+        visit_results(body, std::iter::once(block), analysis, results, &mut collector);
         collector
     }
 }
@@ -729,49 +735,49 @@ where
 
     fn visit_after_early_statement_effect(
         &mut self,
-        results: &mut Results<'tcx, A>,
+        analysis: &mut A,
         state: &A::Domain,
         _statement: &mir::Statement<'tcx>,
         _location: Location,
     ) {
         if let Some(before) = self.before.as_mut() {
-            before.push(diff_pretty(state, &self.prev_state, &results.analysis));
+            before.push(diff_pretty(state, &self.prev_state, analysis));
             self.prev_state.clone_from(state)
         }
     }
 
     fn visit_after_primary_statement_effect(
         &mut self,
-        results: &mut Results<'tcx, A>,
+        analysis: &mut A,
         state: &A::Domain,
         _statement: &mir::Statement<'tcx>,
         _location: Location,
     ) {
-        self.after.push(diff_pretty(state, &self.prev_state, &results.analysis));
+        self.after.push(diff_pretty(state, &self.prev_state, analysis));
         self.prev_state.clone_from(state)
     }
 
     fn visit_after_early_terminator_effect(
         &mut self,
-        results: &mut Results<'tcx, A>,
+        analysis: &mut A,
         state: &A::Domain,
         _terminator: &mir::Terminator<'tcx>,
         _location: Location,
     ) {
         if let Some(before) = self.before.as_mut() {
-            before.push(diff_pretty(state, &self.prev_state, &results.analysis));
+            before.push(diff_pretty(state, &self.prev_state, analysis));
             self.prev_state.clone_from(state)
         }
     }
 
     fn visit_after_primary_terminator_effect(
         &mut self,
-        results: &mut Results<'tcx, A>,
+        analysis: &mut A,
         state: &A::Domain,
         _terminator: &mir::Terminator<'tcx>,
         _location: Location,
     ) {
-        self.after.push(diff_pretty(state, &self.prev_state, &results.analysis));
+        self.after.push(diff_pretty(state, &self.prev_state, analysis));
         self.prev_state.clone_from(state)
     }
 }
diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs
index 09f6cdb5c4a..9cadec100b5 100644
--- a/compiler/rustc_mir_dataflow/src/framework/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs
@@ -58,8 +58,9 @@ mod visitor;
 pub use self::cursor::ResultsCursor;
 pub use self::direction::{Backward, Direction, Forward};
 pub use self::lattice::{JoinSemiLattice, MaybeReachable};
-pub use self::results::{EntryStates, Results};
-pub use self::visitor::{ResultsVisitor, visit_results};
+pub(crate) use self::results::AnalysisAndResults;
+pub use self::results::Results;
+pub use self::visitor::{ResultsVisitor, visit_reachable_results, visit_results};
 
 /// Analysis domains are all bitsets of various kinds. This trait holds
 /// operations needed by all of them.
@@ -247,17 +248,15 @@ pub trait Analysis<'tcx> {
         tcx: TyCtxt<'tcx>,
         body: &'mir mir::Body<'tcx>,
         pass_name: Option<&'static str>,
-    ) -> Results<'tcx, Self>
+    ) -> AnalysisAndResults<'tcx, Self>
     where
         Self: Sized,
         Self::Domain: DebugWithContext<Self>,
     {
-        let mut entry_states =
-            IndexVec::from_fn_n(|_| self.bottom_value(body), body.basic_blocks.len());
-        self.initialize_start_block(body, &mut entry_states[mir::START_BLOCK]);
+        let mut results = IndexVec::from_fn_n(|_| self.bottom_value(body), body.basic_blocks.len());
+        self.initialize_start_block(body, &mut results[mir::START_BLOCK]);
 
-        if Self::Direction::IS_BACKWARD && entry_states[mir::START_BLOCK] != self.bottom_value(body)
-        {
+        if Self::Direction::IS_BACKWARD && results[mir::START_BLOCK] != self.bottom_value(body) {
             bug!("`initialize_start_block` is not yet supported for backward dataflow analyses");
         }
 
@@ -280,10 +279,9 @@ pub trait Analysis<'tcx> {
         // every iteration.
         let mut state = self.bottom_value(body);
         while let Some(bb) = dirty_queue.pop() {
-            // Set the state to the entry state of the block.
-            // This is equivalent to `state = entry_states[bb].clone()`,
-            // but it saves an allocation, thus improving compile times.
-            state.clone_from(&entry_states[bb]);
+            // Set the state to the entry state of the block. This is equivalent to `state =
+            // results[bb].clone()`, but it saves an allocation, thus improving compile times.
+            state.clone_from(&results[bb]);
 
             Self::Direction::apply_effects_in_block(
                 &mut self,
@@ -292,7 +290,7 @@ pub trait Analysis<'tcx> {
                 bb,
                 &body[bb],
                 |target: BasicBlock, state: &Self::Domain| {
-                    let set_changed = entry_states[target].join(state);
+                    let set_changed = results[target].join(state);
                     if set_changed {
                         dirty_queue.insert(target);
                     }
@@ -300,16 +298,14 @@ pub trait Analysis<'tcx> {
             );
         }
 
-        let mut results = Results { analysis: self, entry_states };
-
         if tcx.sess.opts.unstable_opts.dump_mir_dataflow {
-            let res = write_graphviz_results(tcx, body, &mut results, pass_name);
+            let res = write_graphviz_results(tcx, body, &mut self, &results, pass_name);
             if let Err(e) = res {
                 error!("Failed to write graphviz dataflow results: {}", e);
             }
         }
 
-        results
+        AnalysisAndResults { analysis: self, results }
     }
 }
 
diff --git a/compiler/rustc_mir_dataflow/src/framework/results.rs b/compiler/rustc_mir_dataflow/src/framework/results.rs
index 93dfc06a878..7b7e981d3a5 100644
--- a/compiler/rustc_mir_dataflow/src/framework/results.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/results.rs
@@ -1,63 +1,30 @@
 //! Dataflow analysis results.
 
 use rustc_index::IndexVec;
-use rustc_middle::mir::{BasicBlock, Body, traversal};
+use rustc_middle::mir::{BasicBlock, Body};
 
-use super::{Analysis, ResultsCursor, ResultsVisitor, visit_results};
-use crate::framework::cursor::ResultsHandle;
+use super::{Analysis, ResultsCursor};
 
-pub type EntryStates<'tcx, A> = IndexVec<BasicBlock, <A as Analysis<'tcx>>::Domain>;
+/// The results of a dataflow analysis that has converged to fixpoint. It only holds the domain
+/// values at the entry of each basic block. Domain values in other parts of the block are
+/// recomputed on the fly by visitors (i.e. `ResultsCursor`, or `ResultsVisitor` impls).
+pub type Results<D> = IndexVec<BasicBlock, D>;
 
-/// A dataflow analysis that has converged to fixpoint. It only holds the domain values at the
-/// entry of each basic block. Domain values in other parts of the block are recomputed on the fly
-/// by visitors (i.e. `ResultsCursor`, or `ResultsVisitor` impls).
-#[derive(Clone)]
-pub struct Results<'tcx, A>
+/// Utility type used in a few places where it's convenient to bundle an analysis with its results.
+pub struct AnalysisAndResults<'tcx, A>
 where
     A: Analysis<'tcx>,
 {
     pub analysis: A,
-    pub entry_states: EntryStates<'tcx, A>,
+    pub results: Results<A::Domain>,
 }
 
-impl<'tcx, A> Results<'tcx, A>
+impl<'tcx, A> AnalysisAndResults<'tcx, A>
 where
     A: Analysis<'tcx>,
 {
-    /// Creates a `ResultsCursor` that mutably borrows the `Results`, which is appropriate when the
-    /// `Results` is also used outside the cursor.
-    pub fn as_results_cursor<'mir>(
-        &'mir mut self,
-        body: &'mir Body<'tcx>,
-    ) -> ResultsCursor<'mir, 'tcx, A> {
-        ResultsCursor::new(body, ResultsHandle::BorrowedMut(self))
-    }
-
-    /// Creates a `ResultsCursor` that takes ownership of the `Results`.
+    /// Creates a `ResultsCursor` that takes ownership of `self`.
     pub fn into_results_cursor<'mir>(self, body: &'mir Body<'tcx>) -> ResultsCursor<'mir, 'tcx, A> {
-        ResultsCursor::new(body, ResultsHandle::Owned(self))
-    }
-
-    /// Gets the dataflow state for the given block.
-    pub fn entry_set_for_block(&self, block: BasicBlock) -> &A::Domain {
-        &self.entry_states[block]
-    }
-
-    pub fn visit_with<'mir>(
-        &mut self,
-        body: &'mir Body<'tcx>,
-        blocks: impl IntoIterator<Item = BasicBlock>,
-        vis: &mut impl ResultsVisitor<'tcx, A>,
-    ) {
-        visit_results(body, blocks, self, vis)
-    }
-
-    pub fn visit_reachable_with<'mir>(
-        &mut self,
-        body: &'mir Body<'tcx>,
-        vis: &mut impl ResultsVisitor<'tcx, A>,
-    ) {
-        let blocks = traversal::reachable(body);
-        visit_results(body, blocks.map(|(bb, _)| bb), self, vis)
+        ResultsCursor::new_owning(body, self.analysis, self.results)
     }
 }
diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs
index ae0f1179e6f..8602bb55765 100644
--- a/compiler/rustc_mir_dataflow/src/framework/tests.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs
@@ -79,7 +79,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> {
 ///
 /// The `102` in the block's entry set is derived from the basic block index and ensures that the
 /// expected state is unique across all basic blocks. Remember, it is generated by
-/// `mock_entry_states`, not from actually running `MockAnalysis` to fixpoint.
+/// `mock_results`, not from actually running `MockAnalysis` to fixpoint.
 struct MockAnalysis<'tcx, D> {
     body: &'tcx mir::Body<'tcx>,
     dir: PhantomData<D>,
@@ -96,7 +96,7 @@ impl<D: Direction> MockAnalysis<'_, D> {
         ret
     }
 
-    fn mock_entry_states(&self) -> IndexVec<BasicBlock, DenseBitSet<usize>> {
+    fn mock_results(&self) -> IndexVec<BasicBlock, DenseBitSet<usize>> {
         let empty = self.bottom_value(self.body);
         let mut ret = IndexVec::from_elem(empty, &self.body.basic_blocks);
 
@@ -255,7 +255,7 @@ fn test_cursor<D: Direction>(analysis: MockAnalysis<'_, D>) {
     let body = analysis.body;
 
     let mut cursor =
-        Results { entry_states: analysis.mock_entry_states(), analysis }.into_results_cursor(body);
+        AnalysisAndResults { results: analysis.mock_results(), analysis }.into_results_cursor(body);
 
     cursor.allow_unreachable();
 
diff --git a/compiler/rustc_mir_dataflow/src/framework/visitor.rs b/compiler/rustc_mir_dataflow/src/framework/visitor.rs
index c9fdf46c4f5..fbb9e410872 100644
--- a/compiler/rustc_mir_dataflow/src/framework/visitor.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/visitor.rs
@@ -1,4 +1,4 @@
-use rustc_middle::mir::{self, BasicBlock, Location};
+use rustc_middle::mir::{self, BasicBlock, Location, traversal};
 
 use super::{Analysis, Direction, Results};
 
@@ -7,12 +7,13 @@ use super::{Analysis, Direction, Results};
 pub fn visit_results<'mir, 'tcx, A>(
     body: &'mir mir::Body<'tcx>,
     blocks: impl IntoIterator<Item = BasicBlock>,
-    results: &mut Results<'tcx, A>,
+    analysis: &mut A,
+    results: &Results<A::Domain>,
     vis: &mut impl ResultsVisitor<'tcx, A>,
 ) where
     A: Analysis<'tcx>,
 {
-    let mut state = results.analysis.bottom_value(body);
+    let mut state = analysis.bottom_value(body);
 
     #[cfg(debug_assertions)]
     let reachable_blocks = mir::traversal::reachable_as_bitset(body);
@@ -22,10 +23,24 @@ pub fn visit_results<'mir, 'tcx, A>(
         assert!(reachable_blocks.contains(block));
 
         let block_data = &body[block];
-        A::Direction::visit_results_in_block(&mut state, block, block_data, results, vis);
+        state.clone_from(&results[block]);
+        A::Direction::visit_results_in_block(&mut state, block, block_data, analysis, vis);
     }
 }
 
+/// Like `visit_results`, but only for reachable blocks.
+pub fn visit_reachable_results<'mir, 'tcx, A>(
+    body: &'mir mir::Body<'tcx>,
+    analysis: &mut A,
+    results: &Results<A::Domain>,
+    vis: &mut impl ResultsVisitor<'tcx, A>,
+) where
+    A: Analysis<'tcx>,
+{
+    let blocks = traversal::reachable(body).map(|(bb, _)| bb);
+    visit_results(body, blocks, analysis, results, vis)
+}
+
 /// A visitor over the results of an `Analysis`. Use this when you want to inspect domain values in
 /// many or all locations; use `ResultsCursor` if you want to inspect domain values only in certain
 /// locations.
@@ -38,7 +53,7 @@ where
     /// Called after the "early" effect of the given statement is applied to `state`.
     fn visit_after_early_statement_effect(
         &mut self,
-        _results: &mut Results<'tcx, A>,
+        _analysis: &mut A,
         _state: &A::Domain,
         _statement: &mir::Statement<'tcx>,
         _location: Location,
@@ -48,7 +63,7 @@ where
     /// Called after the "primary" effect of the given statement is applied to `state`.
     fn visit_after_primary_statement_effect(
         &mut self,
-        _results: &mut Results<'tcx, A>,
+        _analysis: &mut A,
         _state: &A::Domain,
         _statement: &mir::Statement<'tcx>,
         _location: Location,
@@ -58,7 +73,7 @@ where
     /// Called after the "early" effect of the given terminator is applied to `state`.
     fn visit_after_early_terminator_effect(
         &mut self,
-        _results: &mut Results<'tcx, A>,
+        _analysis: &mut A,
         _state: &A::Domain,
         _terminator: &mir::Terminator<'tcx>,
         _location: Location,
@@ -70,7 +85,7 @@ where
     /// The `call_return_effect` (if one exists) will *not* be applied to `state`.
     fn visit_after_primary_terminator_effect(
         &mut self,
-        _results: &mut Results<'tcx, A>,
+        _analysis: &mut A,
         _state: &A::Domain,
         _terminator: &mir::Terminator<'tcx>,
         _location: Location,
diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs
index 38f82b12746..658fbf505e4 100644
--- a/compiler/rustc_mir_dataflow/src/lib.rs
+++ b/compiler/rustc_mir_dataflow/src/lib.rs
@@ -18,8 +18,8 @@ pub use self::drop_flag_effects::{
     move_path_children_matching, on_all_children_bits, on_lookup_result_bits,
 };
 pub use self::framework::{
-    Analysis, Backward, Direction, EntryStates, Forward, GenKill, JoinSemiLattice, MaybeReachable,
-    Results, ResultsCursor, ResultsVisitor, fmt, graphviz, lattice, visit_results,
+    Analysis, Backward, Direction, Forward, GenKill, JoinSemiLattice, MaybeReachable, Results,
+    ResultsCursor, ResultsVisitor, fmt, graphviz, lattice, visit_reachable_results, visit_results,
 };
 use self::move_paths::MoveData;
 
diff --git a/compiler/rustc_mir_dataflow/src/points.rs b/compiler/rustc_mir_dataflow/src/points.rs
index 21590ff1bba..70d1a34b5fb 100644
--- a/compiler/rustc_mir_dataflow/src/points.rs
+++ b/compiler/rustc_mir_dataflow/src/points.rs
@@ -98,7 +98,8 @@ rustc_index::newtype_index! {
 pub fn save_as_intervals<'tcx, N, A>(
     elements: &DenseLocationMap,
     body: &mir::Body<'tcx>,
-    mut results: Results<'tcx, A>,
+    mut analysis: A,
+    results: Results<A::Domain>,
 ) -> SparseIntervalMatrix<N, PointIndex>
 where
     N: Idx,
@@ -109,7 +110,8 @@ where
     visit_results(
         body,
         body.basic_blocks.reverse_postorder().iter().copied(),
-        &mut results,
+        &mut analysis,
+        &results,
         &mut visitor,
     );
     visitor.values
@@ -127,7 +129,7 @@ where
 {
     fn visit_after_primary_statement_effect<'mir>(
         &mut self,
-        _results: &mut Results<'tcx, A>,
+        _analysis: &mut A,
         state: &A::Domain,
         _statement: &'mir mir::Statement<'tcx>,
         location: Location,
@@ -141,7 +143,7 @@ where
 
     fn visit_after_primary_terminator_effect<'mir>(
         &mut self,
-        _results: &mut Results<'tcx, A>,
+        _analysis: &mut A,
         state: &A::Domain,
         _terminator: &'mir mir::Terminator<'tcx>,
         location: Location,
diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
index 399141aa921..303fc767b9a 100644
--- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs
+++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
@@ -39,23 +39,23 @@ pub fn sanity_check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
     let move_data = MoveData::gather_moves(body, tcx, |_| true);
 
     if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_init).is_some() {
-        let flow_inits =
-            MaybeInitializedPlaces::new(tcx, body, &move_data).iterate_to_fixpoint(tcx, body, None);
-
-        sanity_check_via_rustc_peek(tcx, flow_inits.into_results_cursor(body));
+        let flow_inits = MaybeInitializedPlaces::new(tcx, body, &move_data)
+            .iterate_to_fixpoint(tcx, body, None)
+            .into_results_cursor(body);
+        sanity_check_via_rustc_peek(tcx, flow_inits);
     }
 
     if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_uninit).is_some() {
         let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &move_data)
-            .iterate_to_fixpoint(tcx, body, None);
-
-        sanity_check_via_rustc_peek(tcx, flow_uninits.into_results_cursor(body));
+            .iterate_to_fixpoint(tcx, body, None)
+            .into_results_cursor(body);
+        sanity_check_via_rustc_peek(tcx, flow_uninits);
     }
 
     if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_liveness).is_some() {
-        let flow_liveness = MaybeLiveLocals.iterate_to_fixpoint(tcx, body, None);
-
-        sanity_check_via_rustc_peek(tcx, flow_liveness.into_results_cursor(body));
+        let flow_liveness =
+            MaybeLiveLocals.iterate_to_fixpoint(tcx, body, None).into_results_cursor(body);
+        sanity_check_via_rustc_peek(tcx, flow_liveness);
     }
 
     if has_rustc_mir_with(tcx, def_id, sym::stop_after_dataflow).is_some() {
diff --git a/compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs b/compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs
index 4aff127908e..8da17a056e3 100644
--- a/compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs
+++ b/compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs
@@ -55,18 +55,45 @@ impl<'a, 'tcx> UnnecessaryTransmuteChecker<'a, 'tcx> {
             },
             // char → u32
             (Char, Uint(UintTy::U32)) => err(format!("u32::from({arg})")),
+            // char (→ u32) → i32
+            (Char, Int(IntTy::I32)) => err(format!("u32::from({arg}).cast_signed()")),
             // u32 → char
             (Uint(UintTy::U32), Char) => Error {
                 sugg: format!("char::from_u32_unchecked({arg})"),
                 help: Some("consider `char::from_u32(…).unwrap()`"),
                 span,
             },
+            // i32 → char
+            (Int(IntTy::I32), Char) => Error {
+                sugg: format!("char::from_u32_unchecked(i32::cast_unsigned({arg}))"),
+                help: Some("consider `char::from_u32(i32::cast_unsigned(…)).unwrap()`"),
+                span,
+            },
             // uNN → iNN
             (Uint(ty), Int(_)) => err(format!("{}::cast_signed({arg})", ty.name_str())),
             // iNN → uNN
             (Int(ty), Uint(_)) => err(format!("{}::cast_unsigned({arg})", ty.name_str())),
+            // fNN → xsize
+            (Float(ty), Uint(UintTy::Usize)) => {
+                err(format!("{}::to_bits({arg}) as usize", ty.name_str()))
+            }
+            (Float(ty), Int(IntTy::Isize)) => {
+                err(format!("{}::to_bits({arg}) as isize", ty.name_str()))
+            }
+            // fNN (→ uNN) → iNN
+            (Float(ty), Int(..)) => err(format!("{}::to_bits({arg}).cast_signed()", ty.name_str())),
             // fNN → uNN
             (Float(ty), Uint(..)) => err(format!("{}::to_bits({arg})", ty.name_str())),
+            // xsize → fNN
+            (Uint(UintTy::Usize) | Int(IntTy::Isize), Float(ty)) => {
+                err(format!("{}::from_bits({arg} as _)", ty.name_str(),))
+            }
+            // iNN (→ uNN) → fNN
+            (Int(int_ty), Float(ty)) => err(format!(
+                "{}::from_bits({}::cast_unsigned({arg}))",
+                ty.name_str(),
+                int_ty.name_str()
+            )),
             // uNN → fNN
             (Uint(_), Float(ty)) => err(format!("{}::from_bits({arg})", ty.name_str())),
             // bool → { x8 }
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index 263f0c40f5a..cddb2f84778 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -79,7 +79,9 @@ use rustc_mir_dataflow::impls::{
     MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive,
     always_storage_live_locals,
 };
-use rustc_mir_dataflow::{Analysis, Results, ResultsVisitor};
+use rustc_mir_dataflow::{
+    Analysis, Results, ResultsCursor, ResultsVisitor, visit_reachable_results,
+};
 use rustc_span::def_id::{DefId, LocalDefId};
 use rustc_span::source_map::dummy_spanned;
 use rustc_span::symbol::sym;
@@ -680,18 +682,29 @@ fn locals_live_across_suspend_points<'tcx>(
         .iterate_to_fixpoint(tcx, body, None)
         .into_results_cursor(body);
 
-    // Calculate the MIR locals which have been previously
-    // borrowed (even if they are still active).
-    let borrowed_locals_results =
-        MaybeBorrowedLocals.iterate_to_fixpoint(tcx, body, Some("coroutine"));
-
-    let mut borrowed_locals_cursor = borrowed_locals_results.clone().into_results_cursor(body);
+    // Calculate the MIR locals that have been previously borrowed (even if they are still active).
+    let borrowed_locals = MaybeBorrowedLocals.iterate_to_fixpoint(tcx, body, Some("coroutine"));
+    let mut borrowed_locals_analysis1 = borrowed_locals.analysis;
+    let mut borrowed_locals_analysis2 = borrowed_locals_analysis1.clone(); // trivial
+    let borrowed_locals_cursor1 = ResultsCursor::new_borrowing(
+        body,
+        &mut borrowed_locals_analysis1,
+        &borrowed_locals.results,
+    );
+    let mut borrowed_locals_cursor2 = ResultsCursor::new_borrowing(
+        body,
+        &mut borrowed_locals_analysis2,
+        &borrowed_locals.results,
+    );
 
     // Calculate the MIR locals that we need to keep storage around for.
-    let mut requires_storage_results =
-        MaybeRequiresStorage::new(borrowed_locals_results.into_results_cursor(body))
-            .iterate_to_fixpoint(tcx, body, None);
-    let mut requires_storage_cursor = requires_storage_results.as_results_cursor(body);
+    let mut requires_storage =
+        MaybeRequiresStorage::new(borrowed_locals_cursor1).iterate_to_fixpoint(tcx, body, None);
+    let mut requires_storage_cursor = ResultsCursor::new_borrowing(
+        body,
+        &mut requires_storage.analysis,
+        &requires_storage.results,
+    );
 
     // Calculate the liveness of MIR locals ignoring borrows.
     let mut liveness =
@@ -720,8 +733,8 @@ fn locals_live_across_suspend_points<'tcx>(
                 // If a borrow is converted to a raw reference, we must also assume that it lives
                 // forever. Note that the final liveness is still bounded by the storage liveness
                 // of the local, which happens using the `intersect` operation below.
-                borrowed_locals_cursor.seek_before_primary_effect(loc);
-                live_locals.union(borrowed_locals_cursor.get());
+                borrowed_locals_cursor2.seek_before_primary_effect(loc);
+                live_locals.union(borrowed_locals_cursor2.get());
             }
 
             // Store the storage liveness for later use so we can restore the state
@@ -763,7 +776,8 @@ fn locals_live_across_suspend_points<'tcx>(
         body,
         &saved_locals,
         always_live_locals.clone(),
-        requires_storage_results,
+        &mut requires_storage.analysis,
+        &requires_storage.results,
     );
 
     LivenessInfo {
@@ -828,7 +842,8 @@ fn compute_storage_conflicts<'mir, 'tcx>(
     body: &'mir Body<'tcx>,
     saved_locals: &'mir CoroutineSavedLocals,
     always_live_locals: DenseBitSet<Local>,
-    mut requires_storage: Results<'tcx, MaybeRequiresStorage<'mir, 'tcx>>,
+    analysis: &mut MaybeRequiresStorage<'mir, 'tcx>,
+    results: &Results<DenseBitSet<Local>>,
 ) -> BitMatrix<CoroutineSavedLocal, CoroutineSavedLocal> {
     assert_eq!(body.local_decls.len(), saved_locals.domain_size());
 
@@ -848,7 +863,7 @@ fn compute_storage_conflicts<'mir, 'tcx>(
         eligible_storage_live: DenseBitSet::new_empty(body.local_decls.len()),
     };
 
-    requires_storage.visit_reachable_with(body, &mut visitor);
+    visit_reachable_results(body, analysis, results, &mut visitor);
 
     let local_conflicts = visitor.local_conflicts;
 
@@ -891,7 +906,7 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, MaybeRequiresStorage<'a, 'tcx>>
 {
     fn visit_after_early_statement_effect(
         &mut self,
-        _results: &mut Results<'tcx, MaybeRequiresStorage<'a, 'tcx>>,
+        _analysis: &mut MaybeRequiresStorage<'a, 'tcx>,
         state: &DenseBitSet<Local>,
         _statement: &Statement<'tcx>,
         loc: Location,
@@ -901,7 +916,7 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, MaybeRequiresStorage<'a, 'tcx>>
 
     fn visit_after_early_terminator_effect(
         &mut self,
-        _results: &mut Results<'tcx, MaybeRequiresStorage<'a, 'tcx>>,
+        _analysis: &mut MaybeRequiresStorage<'a, 'tcx>,
         state: &DenseBitSet<Local>,
         _terminator: &Terminator<'tcx>,
         loc: Location,
@@ -1064,10 +1079,8 @@ fn insert_switch<'tcx>(
         },
     );
 
-    let blocks = body.basic_blocks_mut().iter_mut();
-
-    for target in blocks.flat_map(|b| b.terminator_mut().successors_mut()) {
-        *target += 1;
+    for b in body.basic_blocks_mut().iter_mut() {
+        b.terminator_mut().successors_mut(|target| *target += 1);
     }
 }
 
diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
index dd0e07f2218..0a839d91404 100644
--- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
@@ -73,6 +73,7 @@ use rustc_data_structures::unord::UnordMap;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::definitions::DisambiguatorState;
 use rustc_middle::bug;
 use rustc_middle::hir::place::{Projection, ProjectionKind};
 use rustc_middle::mir::visit::MutVisitor;
@@ -213,8 +214,15 @@ pub(crate) fn coroutine_by_move_body_def_id<'tcx>(
     let mut by_move_body = body.clone();
     MakeByMoveBody { tcx, field_remapping, by_move_coroutine_ty }.visit_body(&mut by_move_body);
 
-    // This will always be `{closure#1}`, since the original coroutine is `{closure#0}`.
-    let body_def = tcx.create_def(parent_def_id, None, DefKind::SyntheticCoroutineBody);
+    // This path is unique since we're in a query so we'll only be called once with `parent_def_id`
+    // and this is the only location creating `SyntheticCoroutineBody`.
+    let body_def = tcx.create_def(
+        parent_def_id,
+        None,
+        DefKind::SyntheticCoroutineBody,
+        None,
+        &mut DisambiguatorState::new(),
+    );
     by_move_body.source =
         mir::MirSource::from_instance(InstanceKind::Item(body_def.def_id().to_def_id()));
     dump_mir(tcx, false, "built", &"after", &by_move_body, |_, _| Ok(()));
diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs
index 73bd2d0705e..b4b4d0416fb 100644
--- a/compiler/rustc_mir_transform/src/coverage/mappings.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs
@@ -91,7 +91,7 @@ pub(super) fn extract_all_mapping_info_from_mir<'tcx>(
         // When debugging flag `-Zcoverage-options=no-mir-spans` is set, we need
         // to give the same treatment to _all_ functions, because `llvm-cov`
         // seems to ignore functions that don't have any ordinary code spans.
-        if let Some(span) = hir_info.fn_sig_span_extended {
+        if let Some(span) = hir_info.fn_sig_span {
             code_mappings.push(CodeMapping { span, bcb: START_BCB });
         }
     } else {
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index f2e8f9e1bcd..702c62eddc7 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -268,9 +268,9 @@ fn inject_statement(mir_body: &mut mir::Body<'_>, counter_kind: CoverageKind, bb
 struct ExtractedHirInfo {
     function_source_hash: u64,
     is_async_fn: bool,
-    /// The span of the function's signature, extended to the start of `body_span`.
+    /// The span of the function's signature, if available.
     /// Must have the same context and filename as the body span.
-    fn_sig_span_extended: Option<Span>,
+    fn_sig_span: Option<Span>,
     body_span: Span,
     /// "Holes" are regions within the function body (or its expansions) that
     /// should not be included in coverage spans for this function
@@ -308,30 +308,20 @@ fn extract_hir_info<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ExtractedHir
 
     // The actual signature span is only used if it has the same context and
     // filename as the body, and precedes the body.
-    let fn_sig_span_extended = maybe_fn_sig
-        .map(|fn_sig| fn_sig.span)
-        .filter(|&fn_sig_span| {
-            let source_map = tcx.sess.source_map();
-            let file_idx = |span: Span| source_map.lookup_source_file_idx(span.lo());
-
-            fn_sig_span.eq_ctxt(body_span)
-                && fn_sig_span.hi() <= body_span.lo()
-                && file_idx(fn_sig_span) == file_idx(body_span)
-        })
-        // If so, extend it to the start of the body span.
-        .map(|fn_sig_span| fn_sig_span.with_hi(body_span.lo()));
+    let fn_sig_span = maybe_fn_sig.map(|fn_sig| fn_sig.span).filter(|&fn_sig_span| {
+        let source_map = tcx.sess.source_map();
+        let file_idx = |span: Span| source_map.lookup_source_file_idx(span.lo());
+
+        fn_sig_span.eq_ctxt(body_span)
+            && fn_sig_span.hi() <= body_span.lo()
+            && file_idx(fn_sig_span) == file_idx(body_span)
+    });
 
     let function_source_hash = hash_mir_source(tcx, hir_body);
 
     let hole_spans = extract_hole_spans_from_hir(tcx, hir_body);
 
-    ExtractedHirInfo {
-        function_source_hash,
-        is_async_fn,
-        fn_sig_span_extended,
-        body_span,
-        hole_spans,
-    }
+    ExtractedHirInfo { function_source_hash, is_async_fn, fn_sig_span, body_span, hole_spans }
 }
 
 fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx hir::Body<'tcx>) -> u64 {
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index f57a158e3e4..ec76076020e 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -1,11 +1,8 @@
-use std::collections::VecDeque;
-use std::iter;
-
 use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::mir;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::{DesugaringKind, ExpnKind, MacroKind, Span};
-use tracing::{debug, debug_span, instrument};
+use tracing::instrument;
 
 use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph};
 use crate::coverage::spans::from_mir::{Hole, RawSpanFromMir, SpanFromMir};
@@ -42,12 +39,12 @@ pub(super) fn extract_refined_covspans<'tcx>(
         return;
     }
 
-    // Also add the adjusted function signature span, if available.
+    // Also add the function signature span, if available.
     // Otherwise, add a fake span at the start of the body, to avoid an ugly
     // gap between the start of the body and the first real span.
     // FIXME: Find a more principled way to solve this problem.
     covspans.push(SpanFromMir::for_fn_sig(
-        hir_info.fn_sig_span_extended.unwrap_or_else(|| body_span.shrink_to_lo()),
+        hir_info.fn_sig_span.unwrap_or_else(|| body_span.shrink_to_lo()),
     ));
 
     // First, perform the passes that need macro information.
@@ -83,24 +80,17 @@ pub(super) fn extract_refined_covspans<'tcx>(
     holes.sort_by(|a, b| compare_spans(a.span, b.span));
     holes.dedup_by(|b, a| a.merge_if_overlapping_or_adjacent(b));
 
-    // Split the covspans into separate buckets that don't overlap any holes.
-    let buckets = divide_spans_into_buckets(covspans, &holes);
-
-    for covspans in buckets {
-        let _span = debug_span!("processing bucket", ?covspans).entered();
+    // Discard any span that overlaps with a hole.
+    discard_spans_overlapping_holes(&mut covspans, &holes);
 
-        let mut covspans = remove_unwanted_overlapping_spans(covspans);
-        debug!(?covspans, "after removing overlaps");
+    // Perform more refinement steps after holes have been dealt with.
+    let mut covspans = remove_unwanted_overlapping_spans(covspans);
+    covspans.dedup_by(|b, a| a.merge_if_eligible(b));
 
-        // Do one last merge pass, to simplify the output.
-        covspans.dedup_by(|b, a| a.merge_if_eligible(b));
-        debug!(?covspans, "after merge");
-
-        code_mappings.extend(covspans.into_iter().map(|Covspan { span, bcb }| {
-            // Each span produced by the refiner represents an ordinary code region.
-            mappings::CodeMapping { span, bcb }
-        }));
-    }
+    code_mappings.extend(covspans.into_iter().map(|Covspan { span, bcb }| {
+        // Each span produced by the refiner represents an ordinary code region.
+        mappings::CodeMapping { span, bcb }
+    }));
 }
 
 /// Macros that expand into branches (e.g. `assert!`, `trace!`) tend to generate
@@ -142,52 +132,36 @@ fn shrink_visible_macro_spans(tcx: TyCtxt<'_>, covspans: &mut Vec<SpanFromMir>)
     }
 }
 
-/// Uses the holes to divide the given covspans into buckets, such that:
-/// - No span in any hole overlaps a bucket (discarding spans if necessary).
-/// - The spans in each bucket are strictly after all spans in previous buckets,
-///   and strictly before all spans in subsequent buckets.
+/// Discard all covspans that overlap a hole.
 ///
-/// The lists of covspans and holes must be sorted.
-/// The resulting buckets are sorted relative to each other, and each bucket's
-/// contents are sorted.
-#[instrument(level = "debug")]
-fn divide_spans_into_buckets(input_covspans: Vec<Covspan>, holes: &[Hole]) -> Vec<Vec<Covspan>> {
-    debug_assert!(input_covspans.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le()));
+/// The lists of covspans and holes must be sorted, and any holes that overlap
+/// with each other must have already been merged.
+fn discard_spans_overlapping_holes(covspans: &mut Vec<Covspan>, holes: &[Hole]) {
+    debug_assert!(covspans.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le()));
     debug_assert!(holes.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le()));
+    debug_assert!(holes.array_windows().all(|[a, b]| !a.span.overlaps_or_adjacent(b.span)));
+
+    let mut curr_hole = 0usize;
+    let mut overlaps_hole = |covspan: &Covspan| -> bool {
+        while let Some(hole) = holes.get(curr_hole) {
+            // Both lists are sorted, so we can permanently skip any holes that
+            // end before the start of the current span.
+            if hole.span.hi() <= covspan.span.lo() {
+                curr_hole += 1;
+                continue;
+            }
 
-    // Now we're ready to start grouping spans into buckets separated by holes.
-
-    let mut input_covspans = VecDeque::from(input_covspans);
-
-    // For each hole:
-    // - Identify the spans that are entirely or partly before the hole.
-    // - Discard any that overlap with the hole.
-    // - Add the remaining identified spans to the corresponding bucket.
-    let mut buckets = (0..holes.len()).map(|_| vec![]).collect::<Vec<_>>();
-    for (hole, bucket) in holes.iter().zip(&mut buckets) {
-        bucket.extend(
-            drain_front_while(&mut input_covspans, |c| c.span.lo() < hole.span.hi())
-                .filter(|c| !c.span.overlaps(hole.span)),
-        );
-    }
-
-    // Any remaining spans form their own final bucket, after the final hole.
-    // (If there were no holes, this will just be all of the initial spans.)
-    buckets.push(Vec::from(input_covspans));
+            return hole.span.overlaps(covspan.span);
+        }
 
-    buckets
-}
+        // No holes left, so this covspan doesn't overlap with any holes.
+        false
+    };
 
-/// Similar to `.drain(..)`, but stops just before it would remove an item not
-/// satisfying the predicate.
-fn drain_front_while<'a, T>(
-    queue: &'a mut VecDeque<T>,
-    mut pred_fn: impl FnMut(&T) -> bool,
-) -> impl Iterator<Item = T> {
-    iter::from_fn(move || queue.pop_front_if(|x| pred_fn(x)))
+    covspans.retain(|covspan| !overlaps_hole(covspan));
 }
 
-/// Takes one of the buckets of (sorted) spans extracted from MIR, and "refines"
+/// Takes a list of sorted spans extracted from MIR, and "refines"
 /// those spans by removing spans that overlap in unwanted ways.
 #[instrument(level = "debug")]
 fn remove_unwanted_overlapping_spans(sorted_spans: Vec<Covspan>) -> Vec<Covspan> {
@@ -227,19 +201,21 @@ struct Covspan {
 }
 
 impl Covspan {
-    /// If `self` and `other` can be merged (i.e. they have the same BCB),
-    /// mutates `self.span` to also include `other.span` and returns true.
+    /// If `self` and `other` can be merged, mutates `self.span` to also
+    /// include `other.span` and returns true.
     ///
-    /// Note that compatible covspans can be merged even if their underlying
-    /// spans are not overlapping/adjacent; any space between them will also be
-    /// part of the merged covspan.
+    /// Two covspans can be merged if they have the same BCB, and they are
+    /// overlapping or adjacent.
     fn merge_if_eligible(&mut self, other: &Self) -> bool {
-        if self.bcb != other.bcb {
-            return false;
+        let eligible_for_merge =
+            |a: &Self, b: &Self| (a.bcb == b.bcb) && a.span.overlaps_or_adjacent(b.span);
+
+        if eligible_for_merge(self, other) {
+            self.span = self.span.to(other.span);
+            true
+        } else {
+            false
         }
-
-        self.span = self.span.to(other.span);
-        true
     }
 }
 
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index a2103a004d2..99b95e7312b 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -23,7 +23,7 @@ use rustc_mir_dataflow::lattice::{FlatSet, HasBottom};
 use rustc_mir_dataflow::value_analysis::{
     Map, PlaceIndex, State, TrackElem, ValueOrPlace, debug_with_context,
 };
-use rustc_mir_dataflow::{Analysis, Results, ResultsVisitor};
+use rustc_mir_dataflow::{Analysis, ResultsVisitor, visit_reachable_results};
 use rustc_span::DUMMY_SP;
 use tracing::{debug, debug_span, instrument};
 
@@ -61,13 +61,14 @@ impl<'tcx> crate::MirPass<'tcx> for DataflowConstProp {
         let map = Map::new(tcx, body, place_limit);
 
         // Perform the actual dataflow analysis.
-        let analysis = ConstAnalysis::new(tcx, body, map);
-        let mut results =
-            debug_span!("analyze").in_scope(|| analysis.iterate_to_fixpoint(tcx, body, None));
+        let mut const_ = debug_span!("analyze")
+            .in_scope(|| ConstAnalysis::new(tcx, body, map).iterate_to_fixpoint(tcx, body, None));
 
         // Collect results and patch the body afterwards.
         let mut visitor = Collector::new(tcx, &body.local_decls);
-        debug_span!("collect").in_scope(|| results.visit_reachable_with(body, &mut visitor));
+        debug_span!("collect").in_scope(|| {
+            visit_reachable_results(body, &mut const_.analysis, &const_.results, &mut visitor)
+        });
         let mut patch = visitor.patch;
         debug_span!("patch").in_scope(|| patch.visit_body_preserves_cfg(body));
     }
@@ -959,10 +960,10 @@ fn try_write_constant<'tcx>(
 }
 
 impl<'tcx> ResultsVisitor<'tcx, ConstAnalysis<'_, 'tcx>> for Collector<'_, 'tcx> {
-    #[instrument(level = "trace", skip(self, results, statement))]
+    #[instrument(level = "trace", skip(self, analysis, statement))]
     fn visit_after_early_statement_effect(
         &mut self,
-        results: &mut Results<'tcx, ConstAnalysis<'_, 'tcx>>,
+        analysis: &mut ConstAnalysis<'_, 'tcx>,
         state: &State<FlatSet<Scalar>>,
         statement: &Statement<'tcx>,
         location: Location,
@@ -972,8 +973,8 @@ impl<'tcx> ResultsVisitor<'tcx, ConstAnalysis<'_, 'tcx>> for Collector<'_, 'tcx>
                 OperandCollector {
                     state,
                     visitor: self,
-                    ecx: &mut results.analysis.ecx,
-                    map: &results.analysis.map,
+                    ecx: &mut analysis.ecx,
+                    map: &analysis.map,
                 }
                 .visit_rvalue(rvalue, location);
             }
@@ -981,10 +982,10 @@ impl<'tcx> ResultsVisitor<'tcx, ConstAnalysis<'_, 'tcx>> for Collector<'_, 'tcx>
         }
     }
 
-    #[instrument(level = "trace", skip(self, results, statement))]
+    #[instrument(level = "trace", skip(self, analysis, statement))]
     fn visit_after_primary_statement_effect(
         &mut self,
-        results: &mut Results<'tcx, ConstAnalysis<'_, 'tcx>>,
+        analysis: &mut ConstAnalysis<'_, 'tcx>,
         state: &State<FlatSet<Scalar>>,
         statement: &Statement<'tcx>,
         location: Location,
@@ -994,12 +995,9 @@ impl<'tcx> ResultsVisitor<'tcx, ConstAnalysis<'_, 'tcx>> for Collector<'_, 'tcx>
                 // Don't overwrite the assignment if it already uses a constant (to keep the span).
             }
             StatementKind::Assign(box (place, _)) => {
-                if let Some(value) = self.try_make_constant(
-                    &mut results.analysis.ecx,
-                    place,
-                    state,
-                    &results.analysis.map,
-                ) {
+                if let Some(value) =
+                    self.try_make_constant(&mut analysis.ecx, place, state, &analysis.map)
+                {
                     self.patch.assignments.insert(location, value);
                 }
             }
@@ -1009,18 +1007,13 @@ impl<'tcx> ResultsVisitor<'tcx, ConstAnalysis<'_, 'tcx>> for Collector<'_, 'tcx>
 
     fn visit_after_early_terminator_effect(
         &mut self,
-        results: &mut Results<'tcx, ConstAnalysis<'_, 'tcx>>,
+        analysis: &mut ConstAnalysis<'_, 'tcx>,
         state: &State<FlatSet<Scalar>>,
         terminator: &Terminator<'tcx>,
         location: Location,
     ) {
-        OperandCollector {
-            state,
-            visitor: self,
-            ecx: &mut results.analysis.ecx,
-            map: &results.analysis.map,
-        }
-        .visit_terminator(terminator, location);
+        OperandCollector { state, visitor: self, ecx: &mut analysis.ecx, map: &analysis.map }
+            .visit_terminator(terminator, location);
     }
 }
 
diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
index 7395ad496db..4c94a6c524e 100644
--- a/compiler/rustc_mir_transform/src/dest_prop.rs
+++ b/compiler/rustc_mir_transform/src/dest_prop.rs
@@ -171,7 +171,7 @@ impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
 
         let live = MaybeLiveLocals.iterate_to_fixpoint(tcx, body, Some("MaybeLiveLocals-DestProp"));
         let points = DenseLocationMap::new(body);
-        let mut live = save_as_intervals(&points, body, live);
+        let mut live = save_as_intervals(&points, body, live.analysis, live.results);
 
         // In order to avoid having to collect data for every single pair of locals in the body, we
         // do not allow doing more than one merge for places that are derived from the same local at
diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs
index ada2c0b76cf..31b361ec1a9 100644
--- a/compiler/rustc_mir_transform/src/jump_threading.rs
+++ b/compiler/rustc_mir_transform/src/jump_threading.rs
@@ -757,12 +757,12 @@ impl OpportunitySet {
 
             // Replace `succ` by `new_succ` where it appears.
             let mut num_edges = 0;
-            for s in basic_blocks[current].terminator_mut().successors_mut() {
+            basic_blocks[current].terminator_mut().successors_mut(|s| {
                 if *s == succ {
                     *s = new_succ;
                     num_edges += 1;
                 }
-            }
+            });
 
             // Update predecessors with the new block.
             let _new_succ = self.predecessors.push(num_edges);
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 24f4c11a66d..dc0eacd3613 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -701,8 +701,6 @@ pub(crate) fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'
             // Now, we need to shrink the generated MIR.
             &ref_prop::ReferencePropagation,
             &sroa::ScalarReplacementOfAggregates,
-            &match_branches::MatchBranchSimplification,
-            // inst combine is after MatchBranchSimplification to clean up Ne(_1, false)
             &multiple_return_terminators::MultipleReturnTerminators,
             // After simplifycfg, it allows us to discover new opportunities for peephole
             // optimizations.
@@ -711,6 +709,7 @@ pub(crate) fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'
             &dead_store_elimination::DeadStoreElimination::Initial,
             &gvn::GVN,
             &simplify::SimplifyLocals::AfterGVN,
+            &match_branches::MatchBranchSimplification,
             &dataflow_const_prop::DataflowConstProp,
             &single_use_consts::SingleUseConsts,
             &o1(simplify_branches::SimplifyConstCondition::AfterConstProp),
diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs
index b8cb101f93c..75f351f05c3 100644
--- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs
+++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs
@@ -235,8 +235,9 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
     // When we encounter a DROP of some place P we only care
     // about the drop if `P` may be initialized.
     let move_data = MoveData::gather_moves(body, tcx, |_| true);
-    let maybe_init = MaybeInitializedPlaces::new(tcx, body, &move_data);
-    let mut maybe_init = maybe_init.iterate_to_fixpoint(tcx, body, None).into_results_cursor(body);
+    let mut maybe_init = MaybeInitializedPlaces::new(tcx, body, &move_data)
+        .iterate_to_fixpoint(tcx, body, None)
+        .into_results_cursor(body);
     let mut block_drop_value_info =
         IndexVec::from_elem_n(MovePathIndexAtBlock::Unknown, body.basic_blocks.len());
     for (&block, candidates) in &bid_per_block {
diff --git a/compiler/rustc_mir_transform/src/match_branches.rs b/compiler/rustc_mir_transform/src/match_branches.rs
index b37241185c9..8c0c3096899 100644
--- a/compiler/rustc_mir_transform/src/match_branches.rs
+++ b/compiler/rustc_mir_transform/src/match_branches.rs
@@ -19,30 +19,32 @@ impl<'tcx> crate::MirPass<'tcx> for MatchBranchSimplification {
 
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         let typing_env = body.typing_env(tcx);
-        let mut should_cleanup = false;
-        for bb_idx in body.basic_blocks.indices() {
-            match &body.basic_blocks[bb_idx].terminator().kind {
+        let mut apply_patch = false;
+        let mut patch = MirPatch::new(body);
+        for (bb, bb_data) in body.basic_blocks.iter_enumerated() {
+            match &bb_data.terminator().kind {
                 TerminatorKind::SwitchInt {
                     discr: Operand::Copy(_) | Operand::Move(_),
                     targets,
                     ..
                     // We require that the possible target blocks don't contain this block.
-                } if !targets.all_targets().contains(&bb_idx) => {}
+                } if !targets.all_targets().contains(&bb) => {}
                 // Only optimize switch int statements
                 _ => continue,
             };
 
-            if SimplifyToIf.simplify(tcx, body, bb_idx, typing_env).is_some() {
-                should_cleanup = true;
+            if SimplifyToIf.simplify(tcx, body, &mut patch, bb, typing_env).is_some() {
+                apply_patch = true;
                 continue;
             }
-            if SimplifyToExp::default().simplify(tcx, body, bb_idx, typing_env).is_some() {
-                should_cleanup = true;
+            if SimplifyToExp::default().simplify(tcx, body, &mut patch, bb, typing_env).is_some() {
+                apply_patch = true;
                 continue;
             }
         }
 
-        if should_cleanup {
+        if apply_patch {
+            patch.apply(body);
             simplify_cfg(tcx, body);
         }
     }
@@ -59,7 +61,8 @@ trait SimplifyMatch<'tcx> {
     fn simplify(
         &mut self,
         tcx: TyCtxt<'tcx>,
-        body: &mut Body<'tcx>,
+        body: &Body<'tcx>,
+        patch: &mut MirPatch<'tcx>,
         switch_bb_idx: BasicBlock,
         typing_env: ty::TypingEnv<'tcx>,
     ) -> Option<()> {
@@ -73,8 +76,6 @@ trait SimplifyMatch<'tcx> {
         let discr_ty = discr.ty(body.local_decls(), tcx);
         self.can_simplify(tcx, targets, typing_env, bbs, discr_ty)?;
 
-        let mut patch = MirPatch::new(body);
-
         // Take ownership of items now that we know we can optimize.
         let discr = discr.clone();
 
@@ -87,19 +88,9 @@ trait SimplifyMatch<'tcx> {
         let parent_end = Location { block: switch_bb_idx, statement_index };
         patch.add_statement(parent_end, StatementKind::StorageLive(discr_local));
         patch.add_assign(parent_end, Place::from(discr_local), Rvalue::Use(discr));
-        self.new_stmts(
-            tcx,
-            targets,
-            typing_env,
-            &mut patch,
-            parent_end,
-            bbs,
-            discr_local,
-            discr_ty,
-        );
+        self.new_stmts(tcx, targets, typing_env, patch, parent_end, bbs, discr_local, discr_ty);
         patch.add_statement(parent_end, StatementKind::StorageDead(discr_local));
         patch.patch_terminator(switch_bb_idx, bbs[first].terminator().kind.clone());
-        patch.apply(body);
         Some(())
     }
 
diff --git a/compiler/rustc_mir_transform/src/prettify.rs b/compiler/rustc_mir_transform/src/prettify.rs
index 8ccfbe2f194..8217feff24e 100644
--- a/compiler/rustc_mir_transform/src/prettify.rs
+++ b/compiler/rustc_mir_transform/src/prettify.rs
@@ -115,9 +115,7 @@ impl<'tcx> MutVisitor<'tcx> for BasicBlockUpdater<'tcx> {
     }
 
     fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, _location: Location) {
-        for succ in terminator.successors_mut() {
-            *succ = self.map[*succ];
-        }
+        terminator.successors_mut(|succ| *succ = self.map[*succ]);
     }
 }
 
diff --git a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
index 1dd34005d66..797056ad52d 100644
--- a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
+++ b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
@@ -58,13 +58,13 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads {
                 }
             }
 
-            for target in body[bb].terminator_mut().successors_mut() {
+            body[bb].terminator_mut().successors_mut(|target| {
                 if *target != resume_block && nop_landing_pads.contains(*target) {
                     debug!("    folding noop jump to {:?} to resume block", target);
                     *target = resume_block;
                     jumps_folded += 1;
                 }
-            }
+            });
 
             let is_nop_landing_pad = self.is_nop_landing_pad(bb, body, &nop_landing_pads);
             if is_nop_landing_pad {
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index 0d9a04b760a..9688ac8ed2e 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -298,10 +298,9 @@ fn local_decls_for_sig<'tcx>(
 fn dropee_emit_retag<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &mut Body<'tcx>,
-    dropee_ptr: Place<'tcx>,
+    mut dropee_ptr: Place<'tcx>,
     span: Span,
 ) -> Place<'tcx> {
-    let mut dropee_ptr = dropee_ptr;
     if tcx.sess.opts.unstable_opts.mir_emit_retag {
         let source_info = SourceInfo::outermost(span);
         // We want to treat the function argument as if it was passed by `&mut`. As such, we
@@ -365,8 +364,8 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
         new_body(source, blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span);
 
     // The first argument (index 0), but add 1 for the return value.
-    let mut dropee_ptr = Place::from(Local::new(1 + 0));
-    dropee_ptr = dropee_emit_retag(tcx, &mut body, dropee_ptr, span);
+    let dropee_ptr = Place::from(Local::new(1 + 0));
+    let dropee_ptr = dropee_emit_retag(tcx, &mut body, dropee_ptr, span);
 
     if ty.is_some() {
         let patch = {
diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs
index 4f2cce8ac10..8f88228d9bb 100644
--- a/compiler/rustc_mir_transform/src/simplify.rs
+++ b/compiler/rustc_mir_transform/src/simplify.rs
@@ -147,9 +147,8 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
                 let mut terminator =
                     self.basic_blocks[bb].terminator.take().expect("invalid terminator state");
 
-                for successor in terminator.successors_mut() {
-                    self.collapse_goto_chain(successor, &mut changed);
-                }
+                terminator
+                    .successors_mut(|successor| self.collapse_goto_chain(successor, &mut changed));
 
                 let mut inner_changed = true;
                 merged_blocks.clear();
@@ -375,9 +374,7 @@ pub(super) fn remove_dead_blocks(body: &mut Body<'_>) {
     }
 
     for block in basic_blocks {
-        for target in block.terminator_mut().successors_mut() {
-            *target = replacements[target.index()];
-        }
+        block.terminator_mut().successors_mut(|target| *target = replacements[target.index()]);
     }
 }
 
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 1e3744e19f5..c6a81e60b2b 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -931,7 +931,7 @@ fn visit_instance_use<'tcx>(
             // We explicitly skip this otherwise to ensure we get a linker error
             // if anyone tries to call this intrinsic and the codegen backend did not
             // override the implementation.
-            let instance = ty::Instance::new(instance.def_id(), instance.args);
+            let instance = ty::Instance::new_raw(instance.def_id(), instance.args);
             if tcx.should_codegen_locally(instance) {
                 output.push(create_fn_mono_item(tcx, instance, source));
             }
@@ -1520,7 +1520,7 @@ impl<'v> RootCollector<'_, 'v> {
                         ty::Closure(def_id, args)
                         | ty::Coroutine(def_id, args)
                         | ty::CoroutineClosure(def_id, args) => {
-                            Instance::new(def_id, self.tcx.erase_regions(args))
+                            Instance::new_raw(def_id, self.tcx.erase_regions(args))
                         }
                         _ => unreachable!(),
                     };
diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs
index 25493970a0c..90a7c2e9f78 100644
--- a/compiler/rustc_next_trait_solver/src/delegate.rs
+++ b/compiler/rustc_next_trait_solver/src/delegate.rs
@@ -39,10 +39,6 @@ pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
         term: <Self::Interner as Interner>::Term,
     ) -> Option<Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>>;
 
-    fn clone_opaque_types_for_query_response(
-        &self,
-    ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
-
     fn make_deduplicated_outlives_constraints(
         &self,
     ) -> Vec<ty::OutlivesPredicate<Self::Interner, <Self::Interner as Interner>::GenericArg>>;
@@ -61,14 +57,6 @@ pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
         span: <Self::Interner as Interner>::Span,
         universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
     ) -> <Self::Interner as Interner>::GenericArg;
-
-    fn register_hidden_type_in_storage(
-        &self,
-        opaque_type_key: ty::OpaqueTypeKey<Self::Interner>,
-        hidden_ty: <Self::Interner as Interner>::Ty,
-        span: <Self::Interner as Interner>::Span,
-    ) -> Option<<Self::Interner as Interner>::Ty>;
-
     fn add_item_bounds_for_hidden_type(
         &self,
         def_id: <Self::Interner as Interner>::DefId,
@@ -77,7 +65,6 @@ pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
         hidden_ty: <Self::Interner as Interner>::Ty,
         goals: &mut Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>,
     );
-    fn reset_opaque_types(&self);
 
     fn fetch_eligible_assoc_item(
         &self,
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
index 101129a231e..345a272895d 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -2,21 +2,24 @@
 
 pub(super) mod structural_traits;
 
+use std::ops::ControlFlow;
+
 use derive_where::derive_where;
 use rustc_type_ir::inherent::*;
 use rustc_type_ir::lang_items::TraitSolverLangItem;
 use rustc_type_ir::{
-    self as ty, Interner, TypeFoldable, TypeVisitableExt as _, TypingMode, Upcast as _, elaborate,
+    self as ty, Interner, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt as _,
+    TypeVisitor, TypingMode, Upcast as _, elaborate,
 };
 use tracing::{debug, instrument};
 
-use super::has_only_region_constraints;
 use super::trait_goals::TraitGoalProvenVia;
+use super::{has_only_region_constraints, inspect};
 use crate::delegate::SolverDelegate;
 use crate::solve::inspect::ProbeKind;
 use crate::solve::{
     BuiltinImplSource, CandidateSource, CanonicalResponse, Certainty, EvalCtxt, Goal, GoalSource,
-    MaybeCause, NoSolution, QueryResult,
+    MaybeCause, NoSolution, ParamEnvSource, QueryResult,
 };
 
 enum AliasBoundKind {
@@ -49,18 +52,6 @@ where
 
     fn trait_def_id(self, cx: I) -> I::DefId;
 
-    /// Try equating an assumption predicate against a goal's predicate. If it
-    /// holds, then execute the `then` callback, which should do any additional
-    /// work, then produce a response (typically by executing
-    /// [`EvalCtxt::evaluate_added_goals_and_make_canonical_response`]).
-    fn probe_and_match_goal_against_assumption(
-        ecx: &mut EvalCtxt<'_, D>,
-        source: CandidateSource<I>,
-        goal: Goal<I, Self>,
-        assumption: I::Clause,
-        then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
-    ) -> Result<Candidate<I>, NoSolution>;
-
     /// Consider a clause, which consists of a "assumption" and some "requirements",
     /// to satisfy a goal. If the requirements hold, then attempt to satisfy our
     /// goal by equating it with the assumption.
@@ -119,6 +110,67 @@ where
         alias_ty: ty::AliasTy<I>,
     ) -> Vec<Candidate<I>>;
 
+    fn probe_and_consider_param_env_candidate(
+        ecx: &mut EvalCtxt<'_, D>,
+        goal: Goal<I, Self>,
+        assumption: I::Clause,
+    ) -> Result<Candidate<I>, NoSolution> {
+        Self::fast_reject_assumption(ecx, goal, assumption)?;
+
+        ecx.probe(|candidate: &Result<Candidate<I>, NoSolution>| match candidate {
+            Ok(candidate) => inspect::ProbeKind::TraitCandidate {
+                source: candidate.source,
+                result: Ok(candidate.result),
+            },
+            Err(NoSolution) => inspect::ProbeKind::TraitCandidate {
+                source: CandidateSource::ParamEnv(ParamEnvSource::Global),
+                result: Err(NoSolution),
+            },
+        })
+        .enter(|ecx| {
+            Self::match_assumption(ecx, goal, assumption)?;
+            let source = ecx.characterize_param_env_assumption(goal.param_env, assumption)?;
+            Ok(Candidate {
+                source,
+                result: ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)?,
+            })
+        })
+    }
+
+    /// Try equating an assumption predicate against a goal's predicate. If it
+    /// holds, then execute the `then` callback, which should do any additional
+    /// work, then produce a response (typically by executing
+    /// [`EvalCtxt::evaluate_added_goals_and_make_canonical_response`]).
+    fn probe_and_match_goal_against_assumption(
+        ecx: &mut EvalCtxt<'_, D>,
+        source: CandidateSource<I>,
+        goal: Goal<I, Self>,
+        assumption: I::Clause,
+        then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
+    ) -> Result<Candidate<I>, NoSolution> {
+        Self::fast_reject_assumption(ecx, goal, assumption)?;
+
+        ecx.probe_trait_candidate(source).enter(|ecx| {
+            Self::match_assumption(ecx, goal, assumption)?;
+            then(ecx)
+        })
+    }
+
+    /// Try to reject the assumption based off of simple heuristics, such as [`ty::ClauseKind`]
+    /// and `DefId`.
+    fn fast_reject_assumption(
+        ecx: &mut EvalCtxt<'_, D>,
+        goal: Goal<I, Self>,
+        assumption: I::Clause,
+    ) -> Result<(), NoSolution>;
+
+    /// Relate the goal and assumption.
+    fn match_assumption(
+        ecx: &mut EvalCtxt<'_, D>,
+        goal: Goal<I, Self>,
+        assumption: I::Clause,
+    ) -> Result<(), NoSolution>;
+
     fn consider_impl_candidate(
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, Self>,
@@ -500,14 +552,8 @@ where
         goal: Goal<I, G>,
         candidates: &mut Vec<Candidate<I>>,
     ) {
-        for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() {
-            candidates.extend(G::probe_and_consider_implied_clause(
-                self,
-                CandidateSource::ParamEnv(i),
-                goal,
-                assumption,
-                [],
-            ));
+        for assumption in goal.param_env.caller_bounds().iter() {
+            candidates.extend(G::probe_and_consider_param_env_candidate(self, goal, assumption));
         }
     }
 
@@ -943,4 +989,88 @@ where
             }
         }
     }
+
+    /// Compute whether a param-env assumption is global or non-global after normalizing it.
+    ///
+    /// This is necessary because, for example, given:
+    ///
+    /// ```ignore,rust
+    /// where
+    ///     T: Trait<Assoc = u32>,
+    ///     i32: From<T::Assoc>,
+    /// ```
+    ///
+    /// The `i32: From<T::Assoc>` bound is non-global before normalization, but is global after.
+    /// Since the old trait solver normalized param-envs eagerly, we want to emulate this
+    /// behavior lazily.
+    fn characterize_param_env_assumption(
+        &mut self,
+        param_env: I::ParamEnv,
+        assumption: I::Clause,
+    ) -> Result<CandidateSource<I>, NoSolution> {
+        // FIXME: This should be fixed, but it also requires changing the behavior
+        // in the old solver which is currently relied on.
+        if assumption.has_bound_vars() {
+            return Ok(CandidateSource::ParamEnv(ParamEnvSource::NonGlobal));
+        }
+
+        match assumption.visit_with(&mut FindParamInClause { ecx: self, param_env }) {
+            ControlFlow::Break(Err(NoSolution)) => Err(NoSolution),
+            ControlFlow::Break(Ok(())) => Ok(CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)),
+            ControlFlow::Continue(()) => Ok(CandidateSource::ParamEnv(ParamEnvSource::Global)),
+        }
+    }
+}
+
+struct FindParamInClause<'a, 'b, D: SolverDelegate<Interner = I>, I: Interner> {
+    ecx: &'a mut EvalCtxt<'b, D>,
+    param_env: I::ParamEnv,
+}
+
+impl<D, I> TypeVisitor<I> for FindParamInClause<'_, '_, D, I>
+where
+    D: SolverDelegate<Interner = I>,
+    I: Interner,
+{
+    type Result = ControlFlow<Result<(), NoSolution>>;
+
+    fn visit_binder<T: TypeFoldable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::Result {
+        self.ecx.enter_forall(t.clone(), |ecx, v| {
+            v.visit_with(&mut FindParamInClause { ecx, param_env: self.param_env })
+        })
+    }
+
+    fn visit_ty(&mut self, ty: I::Ty) -> Self::Result {
+        let Ok(ty) = self.ecx.structurally_normalize_ty(self.param_env, ty) else {
+            return ControlFlow::Break(Err(NoSolution));
+        };
+
+        if let ty::Placeholder(_) = ty.kind() {
+            ControlFlow::Break(Ok(()))
+        } else {
+            ty.super_visit_with(self)
+        }
+    }
+
+    fn visit_const(&mut self, ct: I::Const) -> Self::Result {
+        let Ok(ct) = self.ecx.structurally_normalize_const(self.param_env, ct) else {
+            return ControlFlow::Break(Err(NoSolution));
+        };
+
+        if let ty::ConstKind::Placeholder(_) = ct.kind() {
+            ControlFlow::Break(Ok(()))
+        } else {
+            ct.super_visit_with(self)
+        }
+    }
+
+    fn visit_region(&mut self, r: I::Region) -> Self::Result {
+        match self.ecx.eager_resolve_region(r).kind() {
+            ty::ReStatic | ty::ReError(_) => ControlFlow::Continue(()),
+            ty::ReVar(_) | ty::RePlaceholder(_) => ControlFlow::Break(Ok(())),
+            ty::ReErased | ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReBound(..) => {
+                unreachable!()
+            }
+        }
+    }
 }
diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
index 5edc777262b..84a83d79cf0 100644
--- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
@@ -36,39 +36,38 @@ where
         self.def_id()
     }
 
-    fn probe_and_match_goal_against_assumption(
+    fn fast_reject_assumption(
         ecx: &mut EvalCtxt<'_, D>,
-        source: rustc_type_ir::solve::CandidateSource<I>,
         goal: Goal<I, Self>,
-        assumption: <I as Interner>::Clause,
-        then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
-    ) -> Result<Candidate<I>, NoSolution> {
+        assumption: I::Clause,
+    ) -> Result<(), NoSolution> {
         if let Some(host_clause) = assumption.as_host_effect_clause() {
             if host_clause.def_id() == goal.predicate.def_id()
                 && host_clause.constness().satisfies(goal.predicate.constness)
             {
-                if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
+                if DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
                     goal.predicate.trait_ref.args,
                     host_clause.skip_binder().trait_ref.args,
                 ) {
-                    return Err(NoSolution);
+                    return Ok(());
                 }
-
-                ecx.probe_trait_candidate(source).enter(|ecx| {
-                    let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause);
-                    ecx.eq(
-                        goal.param_env,
-                        goal.predicate.trait_ref,
-                        assumption_trait_pred.trait_ref,
-                    )?;
-                    then(ecx)
-                })
-            } else {
-                Err(NoSolution)
             }
-        } else {
-            Err(NoSolution)
         }
+
+        Err(NoSolution)
+    }
+
+    fn match_assumption(
+        ecx: &mut EvalCtxt<'_, D>,
+        goal: Goal<I, Self>,
+        assumption: I::Clause,
+    ) -> Result<(), NoSolution> {
+        let host_clause = assumption.as_host_effect_clause().unwrap();
+
+        let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause);
+        ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?;
+
+        Ok(())
     }
 
     /// Register additional assumptions for aliases corresponding to `~const` item bounds.
@@ -124,7 +123,7 @@ where
     fn consider_impl_candidate(
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, Self>,
-        impl_def_id: <I as Interner>::DefId,
+        impl_def_id: I::DefId,
     ) -> Result<Candidate<I>, NoSolution> {
         let cx = ecx.cx();
 
@@ -178,7 +177,7 @@ where
 
     fn consider_error_guaranteed_candidate(
         ecx: &mut EvalCtxt<'_, D>,
-        _guar: <I as Interner>::ErrorGuaranteed,
+        _guar: I::ErrorGuaranteed,
     ) -> Result<Candidate<I>, NoSolution> {
         ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
             .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
index dded84f6768..36f68808a2c 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
@@ -56,7 +56,10 @@ where
         &self,
         goal: Goal<I, T>,
     ) -> (Vec<I::GenericArg>, CanonicalInput<I, T>) {
-        let opaque_types = self.delegate.clone_opaque_types_for_query_response();
+        // We only care about one entry per `OpaqueTypeKey` here,
+        // so we only canonicalize the lookup table and ignore
+        // duplicate entries.
+        let opaque_types = self.delegate.clone_opaque_types_lookup_table();
         let (goal, opaque_types) =
             (goal, opaque_types).fold_with(&mut EagerResolver::new(self.delegate));
 
@@ -129,12 +132,14 @@ where
                     (Certainty::Yes, NestedNormalizationGoals(goals))
                 }
                 _ => {
-                    let certainty = shallow_certainty.unify_with(goals_certainty);
+                    let certainty = shallow_certainty.and(goals_certainty);
                     (certainty, NestedNormalizationGoals::empty())
                 }
             };
 
-        if let Certainty::Maybe(cause @ MaybeCause::Overflow { .. }) = certainty {
+        if let Certainty::Maybe(cause @ MaybeCause::Overflow { keep_constraints: false, .. }) =
+            certainty
+        {
             // If we have overflow, it's probable that we're substituting a type
             // into itself infinitely and any partial substitutions in the query
             // response are probably not useful anyways, so just return an empty
@@ -190,6 +195,7 @@ where
                     debug!(?num_non_region_vars, "too many inference variables -> overflow");
                     return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow {
                         suggest_increasing_limit: true,
+                        keep_constraints: false,
                     }));
                 }
             }
@@ -241,19 +247,15 @@ where
             Default::default()
         };
 
-        ExternalConstraintsData {
-            region_constraints,
-            opaque_types: self
-                .delegate
-                .clone_opaque_types_for_query_response()
-                .into_iter()
-                // Only return *newly defined* opaque types.
-                .filter(|(a, _)| {
-                    self.predefined_opaques_in_body.opaque_types.iter().all(|(pa, _)| pa != a)
-                })
-                .collect(),
-            normalization_nested_goals,
-        }
+        // We only return *newly defined* opaque types from canonical queries.
+        //
+        // Constraints for any existing opaque types are already tracked by changes
+        // to the `var_values`.
+        let opaque_types = self
+            .delegate
+            .clone_opaque_types_added_since(self.initial_opaque_types_storage_num_entries);
+
+        ExternalConstraintsData { region_constraints, opaque_types, normalization_nested_goals }
     }
 
     /// After calling a canonical query, we apply the constraints returned
@@ -432,7 +434,16 @@ where
     fn register_new_opaque_types(&mut self, opaque_types: &[(ty::OpaqueTypeKey<I>, I::Ty)]) {
         for &(key, ty) in opaque_types {
             let prev = self.delegate.register_hidden_type_in_storage(key, ty, self.origin_span);
-            assert_eq!(prev, None);
+            // We eagerly resolve inference variables when computing the query response.
+            // This can cause previously distinct opaque type keys to now be structurally equal.
+            //
+            // To handle this, we store any duplicate entries in a separate list to check them
+            // at the end of typeck/borrowck. We could alternatively eagerly equate the hidden
+            // types here. However, doing so is difficult as it may result in nested goals and
+            // any errors may make it harder to track the control flow for diagnostics.
+            if let Some(prev) = prev {
+                self.delegate.add_duplicate_opaque_type(key, prev, self.origin_span);
+            }
         }
     }
 }
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 6dd554299a6..fc5dad9a3ed 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
@@ -14,7 +14,7 @@ use rustc_type_ir::{
     TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
     TypingMode,
 };
-use tracing::{instrument, trace};
+use tracing::{debug, instrument, trace};
 
 use super::has_only_region_constraints;
 use crate::coherence;
@@ -23,8 +23,7 @@ use crate::solve::inspect::{self, ProofTreeBuilder};
 use crate::solve::search_graph::SearchGraph;
 use crate::solve::{
     CanonicalInput, Certainty, FIXPOINT_STEP_LIMIT, Goal, GoalEvaluationKind, GoalSource,
-    HasChanged, NestedNormalizationGoals, NoSolution, PredefinedOpaquesData, QueryInput,
-    QueryResult,
+    HasChanged, NestedNormalizationGoals, NoSolution, QueryInput, QueryResult,
 };
 
 pub(super) mod canonical;
@@ -99,8 +98,6 @@ where
     current_goal_kind: CurrentGoalKind,
     pub(super) var_values: CanonicalVarValues<I>,
 
-    predefined_opaques_in_body: I::PredefinedOpaques,
-
     /// The highest universe index nameable by the caller.
     ///
     /// When we enter a new binder inside of the query we create new universes
@@ -111,6 +108,10 @@ where
     /// if we have a coinductive cycle and because that's the only way we can return
     /// new placeholders to the caller.
     pub(super) max_input_universe: ty::UniverseIndex,
+    /// The opaque types from the canonical input. We only need to return opaque types
+    /// which have been added to the storage while evaluating this goal.
+    pub(super) initial_opaque_types_storage_num_entries:
+        <D::Infcx as InferCtxtLike>::OpaqueTypeStorageEntries,
 
     pub(super) search_graph: &'a mut SearchGraph<D>,
 
@@ -305,10 +306,8 @@ where
 
             // Only relevant when canonicalizing the response,
             // which we don't do within this evaluation context.
-            predefined_opaques_in_body: delegate
-                .cx()
-                .mk_predefined_opaques_in_body(PredefinedOpaquesData::default()),
             max_input_universe: ty::UniverseIndex::ROOT,
+            initial_opaque_types_storage_num_entries: Default::default(),
             variables: Default::default(),
             var_values: CanonicalVarValues::dummy(),
             current_goal_kind: CurrentGoalKind::Misc,
@@ -342,16 +341,34 @@ where
         canonical_goal_evaluation: &mut ProofTreeBuilder<D>,
         f: impl FnOnce(&mut EvalCtxt<'_, D>, Goal<I, I::Predicate>) -> R,
     ) -> R {
-        let (ref delegate, input, var_values) =
-            SolverDelegate::build_with_canonical(cx, &canonical_input);
+        let (ref delegate, input, var_values) = D::build_with_canonical(cx, &canonical_input);
+
+        for &(key, ty) in &input.predefined_opaques_in_body.opaque_types {
+            let prev = delegate.register_hidden_type_in_storage(key, ty, I::Span::dummy());
+            // It may be possible that two entries in the opaque type storage end up
+            // with the same key after resolving contained inference variables.
+            //
+            // We could put them in the duplicate list but don't have to. The opaques we
+            // encounter here are already tracked in the caller, so there's no need to
+            // also store them here. We'd take them out when computing the query response
+            // and then discard them, as they're already present in the input.
+            //
+            // Ideally we'd drop duplicate opaque type definitions when computing
+            // the canonical input. This is more annoying to implement and may cause a
+            // perf regression, so we do it inside of the query for now.
+            if let Some(prev) = prev {
+                debug!(?key, ?ty, ?prev, "ignore duplicate in `opaque_types_storage`");
+            }
+        }
 
+        let initial_opaque_types_storage_num_entries = delegate.opaque_types_storage_num_entries();
         let mut ecx = EvalCtxt {
             delegate,
             variables: canonical_input.canonical.variables,
             var_values,
             current_goal_kind: CurrentGoalKind::from_query_input(cx, input),
-            predefined_opaques_in_body: input.predefined_opaques_in_body,
             max_input_universe: canonical_input.canonical.max_universe,
+            initial_opaque_types_storage_num_entries,
             search_graph,
             nested_goals: Default::default(),
             origin_span: I::Span::dummy(),
@@ -359,15 +376,6 @@ where
             inspect: canonical_goal_evaluation.new_goal_evaluation_step(var_values),
         };
 
-        for &(key, ty) in &input.predefined_opaques_in_body.opaque_types {
-            let prev = ecx.delegate.register_hidden_type_in_storage(key, ty, ecx.origin_span);
-            assert_eq!(prev, None);
-        }
-
-        if !ecx.nested_goals.is_empty() {
-            panic!("prepopulating opaque types shouldn't add goals: {:?}", ecx.nested_goals);
-        }
-
         let result = f(&mut ecx, input.goal);
         ecx.inspect.probe_final_state(ecx.delegate, ecx.max_input_universe);
         canonical_goal_evaluation.goal_evaluation_step(ecx.inspect);
@@ -653,7 +661,7 @@ where
                     Certainty::Yes => {}
                     Certainty::Maybe(_) => {
                         self.nested_goals.push((source, with_resolved_vars));
-                        unchanged_certainty = unchanged_certainty.map(|c| c.unify_with(certainty));
+                        unchanged_certainty = unchanged_certainty.map(|c| c.and(certainty));
                     }
                 }
             } else {
@@ -667,7 +675,7 @@ where
                     Certainty::Yes => {}
                     Certainty::Maybe(_) => {
                         self.nested_goals.push((source, goal));
-                        unchanged_certainty = unchanged_certainty.map(|c| c.unify_with(certainty));
+                        unchanged_certainty = unchanged_certainty.map(|c| c.and(certainty));
                     }
                 }
             }
@@ -987,6 +995,14 @@ where
         self.delegate.resolve_vars_if_possible(value)
     }
 
+    pub(super) fn eager_resolve_region(&self, r: I::Region) -> I::Region {
+        if let ty::ReVar(vid) = r.kind() {
+            self.delegate.opportunistic_resolve_lt_var(vid)
+        } else {
+            r
+        }
+    }
+
     pub(super) fn fresh_args_for_item(&mut self, def_id: I::DefId) -> I::GenericArgs {
         let args = self.delegate.fresh_args_for_item(def_id);
         for arg in args.iter() {
@@ -1065,14 +1081,17 @@ where
         &mut self,
         key: ty::OpaqueTypeKey<I>,
     ) -> Option<(ty::OpaqueTypeKey<I>, I::Ty)> {
-        let mut matching =
-            self.delegate.clone_opaque_types_for_query_response().into_iter().filter(
-                |(candidate_key, _)| {
-                    candidate_key.def_id == key.def_id
-                        && DeepRejectCtxt::relate_rigid_rigid(self.cx())
-                            .args_may_unify(candidate_key.args, key.args)
-                },
-            );
+        // We shouldn't have any duplicate entries when using
+        // this function during `TypingMode::Analysis`.
+        let duplicate_entries = self.delegate.clone_duplicate_opaque_types();
+        assert!(duplicate_entries.is_empty(), "unexpected duplicates: {duplicate_entries:?}");
+        let mut matching = self.delegate.clone_opaque_types_lookup_table().into_iter().filter(
+            |(candidate_key, _)| {
+                candidate_key.def_id == key.def_id
+                    && DeepRejectCtxt::relate_rigid_rigid(self.cx())
+                        .args_may_unify(candidate_key.args, key.args)
+            },
+        );
         let first = matching.next();
         let second = matching.next();
         assert_eq!(second, None);
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs
index 0a9e7fafaea..ed0cedc4077 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs
@@ -26,32 +26,33 @@ where
     I: Interner,
 {
     pub(in crate::solve) fn enter(self, f: impl FnOnce(&mut EvalCtxt<'_, D>) -> T) -> T {
-        let ProbeCtxt { ecx: outer_ecx, probe_kind, _result } = self;
+        let ProbeCtxt { ecx: outer, probe_kind, _result } = self;
 
-        let delegate = outer_ecx.delegate;
-        let max_input_universe = outer_ecx.max_input_universe;
-        let mut nested_ecx = EvalCtxt {
+        let delegate = outer.delegate;
+        let max_input_universe = outer.max_input_universe;
+        let mut nested = EvalCtxt {
             delegate,
-            variables: outer_ecx.variables,
-            var_values: outer_ecx.var_values,
-            current_goal_kind: outer_ecx.current_goal_kind,
-            predefined_opaques_in_body: outer_ecx.predefined_opaques_in_body,
+            variables: outer.variables,
+            var_values: outer.var_values,
+            current_goal_kind: outer.current_goal_kind,
             max_input_universe,
-            search_graph: outer_ecx.search_graph,
-            nested_goals: outer_ecx.nested_goals.clone(),
-            origin_span: outer_ecx.origin_span,
-            tainted: outer_ecx.tainted,
-            inspect: outer_ecx.inspect.take_and_enter_probe(),
+            initial_opaque_types_storage_num_entries: outer
+                .initial_opaque_types_storage_num_entries,
+            search_graph: outer.search_graph,
+            nested_goals: outer.nested_goals.clone(),
+            origin_span: outer.origin_span,
+            tainted: outer.tainted,
+            inspect: outer.inspect.take_and_enter_probe(),
         };
-        let r = nested_ecx.delegate.probe(|| {
-            let r = f(&mut nested_ecx);
-            nested_ecx.inspect.probe_final_state(delegate, max_input_universe);
+        let r = nested.delegate.probe(|| {
+            let r = f(&mut nested);
+            nested.inspect.probe_final_state(delegate, max_input_universe);
             r
         });
-        if !nested_ecx.inspect.is_noop() {
+        if !nested.inspect.is_noop() {
             let probe_kind = probe_kind(&r);
-            nested_ecx.inspect.probe_kind(probe_kind);
-            outer_ecx.inspect = nested_ecx.inspect.finish_probe();
+            nested.inspect.probe_kind(probe_kind);
+            outer.inspect = nested.inspect.finish_probe();
         }
         r
     }
diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs
index c9f4fc649b5..8173146e2fe 100644
--- a/compiler/rustc_next_trait_solver/src/solve/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs
@@ -253,16 +253,18 @@ where
     }
 
     fn bail_with_ambiguity(&mut self, responses: &[CanonicalResponse<I>]) -> CanonicalResponse<I> {
-        debug_assert!(!responses.is_empty());
-        if let Certainty::Maybe(maybe_cause) =
-            responses.iter().fold(Certainty::AMBIGUOUS, |certainty, response| {
-                certainty.unify_with(response.value.certainty)
-            })
-        {
-            self.make_ambiguous_response_no_constraints(maybe_cause)
-        } else {
-            panic!("expected flounder response to be ambiguous")
-        }
+        debug_assert!(responses.len() > 1);
+        let maybe_cause = responses.iter().fold(MaybeCause::Ambiguity, |maybe_cause, response| {
+            // Pull down the certainty of `Certainty::Yes` to ambiguity when combining
+            // these responses, b/c we're combining more than one response and this we
+            // don't know which one applies.
+            let candidate = match response.value.certainty {
+                Certainty::Yes => MaybeCause::Ambiguity,
+                Certainty::Maybe(candidate) => candidate,
+            };
+            maybe_cause.or(candidate)
+        });
+        self.make_ambiguous_response_no_constraints(maybe_cause)
     }
 
     /// If we fail to merge responses we flounder and return overflow or ambiguity.
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs
index d077f8a9be8..8aa6e4a3d71 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs
@@ -19,19 +19,25 @@ where
         goal: Goal<I, ty::NormalizesTo<I>>,
     ) -> QueryResult<I> {
         let cx = self.cx();
-        let free_ty = goal.predicate.alias;
+        let free_alias = goal.predicate.alias;
 
         // Check where clauses
         self.add_goals(
             GoalSource::Misc,
-            cx.predicates_of(free_ty.def_id)
-                .iter_instantiated(cx, free_ty.args)
+            cx.predicates_of(free_alias.def_id)
+                .iter_instantiated(cx, free_alias.args)
                 .map(|pred| goal.with(cx, pred)),
         );
 
-        let actual = cx.type_of(free_ty.def_id).instantiate(cx, free_ty.args);
-        self.instantiate_normalizes_to_term(goal, actual.into());
+        let actual = if free_alias.kind(cx).is_type() {
+            cx.type_of(free_alias.def_id).instantiate(cx, free_alias.args)
+        } else {
+            // FIXME(mgca): once const items are actual aliases defined as equal to type system consts
+            // this should instead return that.
+            panic!("normalizing free const aliases in the type system is unsupported");
+        };
 
+        self.instantiate_normalizes_to_term(goal, actual.into());
         self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
     }
 }
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs
index 1d1ff09ee41..2640238f5a9 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs
@@ -15,12 +15,12 @@ where
     D: SolverDelegate<Interner = I>,
     I: Interner,
 {
-    pub(super) fn normalize_inherent_associated_type(
+    pub(super) fn normalize_inherent_associated_term(
         &mut self,
         goal: Goal<I, ty::NormalizesTo<I>>,
     ) -> QueryResult<I> {
         let cx = self.cx();
-        let inherent = goal.predicate.alias.expect_ty(cx);
+        let inherent = goal.predicate.alias;
 
         let impl_def_id = cx.parent(inherent.def_id);
         let impl_args = self.fresh_args_for_item(impl_def_id);
@@ -48,8 +48,13 @@ where
                 .map(|pred| goal.with(cx, pred)),
         );
 
-        let normalized = cx.type_of(inherent.def_id).instantiate(cx, inherent_args);
-        self.instantiate_normalizes_to_term(goal, normalized.into());
+        let normalized = if inherent.kind(cx).is_type() {
+            cx.type_of(inherent.def_id).instantiate(cx, inherent_args).into()
+        } else {
+            // FIXME(mgca): Properly handle IACs in the type system
+            panic!("normalizing inherent associated consts in the type system is unsupported");
+        };
+        self.instantiate_normalizes_to_term(goal, normalized);
         self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
     }
 }
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index b030af48381..b90e34e7810 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -48,9 +48,13 @@ where
                     })
                 })
             }
-            ty::AliasTermKind::InherentTy => self.normalize_inherent_associated_type(goal),
+            ty::AliasTermKind::InherentTy | ty::AliasTermKind::InherentConst => {
+                self.normalize_inherent_associated_term(goal)
+            }
             ty::AliasTermKind::OpaqueTy => self.normalize_opaque_type(goal),
-            ty::AliasTermKind::FreeTy => self.normalize_free_alias(goal),
+            ty::AliasTermKind::FreeTy | ty::AliasTermKind::FreeConst => {
+                self.normalize_free_alias(goal)
+            }
             ty::AliasTermKind::UnevaluatedConst => self.normalize_anon_const(goal),
         }
     }
@@ -102,50 +106,48 @@ where
         self.trait_def_id(cx)
     }
 
-    fn probe_and_match_goal_against_assumption(
+    fn fast_reject_assumption(
         ecx: &mut EvalCtxt<'_, D>,
-        source: CandidateSource<I>,
         goal: Goal<I, Self>,
         assumption: I::Clause,
-        then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
-    ) -> Result<Candidate<I>, NoSolution> {
+    ) -> Result<(), NoSolution> {
         if let Some(projection_pred) = assumption.as_projection_clause() {
             if projection_pred.item_def_id() == goal.predicate.def_id() {
-                let cx = ecx.cx();
-                if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
+                if DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
                     goal.predicate.alias.args,
                     projection_pred.skip_binder().projection_term.args,
                 ) {
-                    return Err(NoSolution);
+                    return Ok(());
                 }
-                ecx.probe_trait_candidate(source).enter(|ecx| {
-                    let assumption_projection_pred =
-                        ecx.instantiate_binder_with_infer(projection_pred);
-                    ecx.eq(
-                        goal.param_env,
-                        goal.predicate.alias,
-                        assumption_projection_pred.projection_term,
-                    )?;
-
-                    ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term);
-
-                    // Add GAT where clauses from the trait's definition
-                    // FIXME: We don't need these, since these are the type's own WF obligations.
-                    ecx.add_goals(
-                        GoalSource::AliasWellFormed,
-                        cx.own_predicates_of(goal.predicate.def_id())
-                            .iter_instantiated(cx, goal.predicate.alias.args)
-                            .map(|pred| goal.with(cx, pred)),
-                    );
-
-                    then(ecx)
-                })
-            } else {
-                Err(NoSolution)
             }
-        } else {
-            Err(NoSolution)
         }
+
+        Err(NoSolution)
+    }
+
+    fn match_assumption(
+        ecx: &mut EvalCtxt<'_, D>,
+        goal: Goal<I, Self>,
+        assumption: I::Clause,
+    ) -> Result<(), NoSolution> {
+        let projection_pred = assumption.as_projection_clause().unwrap();
+
+        let assumption_projection_pred = ecx.instantiate_binder_with_infer(projection_pred);
+        ecx.eq(goal.param_env, goal.predicate.alias, assumption_projection_pred.projection_term)?;
+
+        ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term);
+
+        // Add GAT where clauses from the trait's definition
+        // FIXME: We don't need these, since these are the type's own WF obligations.
+        let cx = ecx.cx();
+        ecx.add_goals(
+            GoalSource::AliasWellFormed,
+            cx.own_predicates_of(goal.predicate.def_id())
+                .iter_instantiated(cx, goal.predicate.alias.args)
+                .map(|pred| goal.with(cx, pred)),
+        );
+
+        Ok(())
     }
 
     fn consider_additional_alias_assumptions(
@@ -333,6 +335,8 @@ where
                     cx.type_of(target_item_def_id).map_bound(|ty| ty.into())
                 }
                 ty::AliasTermKind::ProjectionConst => {
+                    // FIXME(mgca): once const items are actual aliases defined as equal to type system consts
+                    // this should instead return that.
                     if cx.features().associated_const_equality() {
                         panic!("associated const projection is not supported yet")
                     } else {
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index d19249df387..e3addf8bf93 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -17,7 +17,7 @@ use crate::solve::assembly::{self, AllowInferenceConstraints, AssembleCandidates
 use crate::solve::inspect::ProbeKind;
 use crate::solve::{
     BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause,
-    NoSolution, QueryResult,
+    NoSolution, ParamEnvSource,
 };
 
 impl<D, I> assembly::GoalKind<D> for TraitPredicate<I>
@@ -125,39 +125,38 @@ where
             .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
     }
 
-    fn probe_and_match_goal_against_assumption(
+    fn fast_reject_assumption(
         ecx: &mut EvalCtxt<'_, D>,
-        source: CandidateSource<I>,
         goal: Goal<I, Self>,
         assumption: I::Clause,
-        then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
-    ) -> Result<Candidate<I>, NoSolution> {
+    ) -> Result<(), NoSolution> {
         if let Some(trait_clause) = assumption.as_trait_clause() {
             if trait_clause.def_id() == goal.predicate.def_id()
                 && trait_clause.polarity() == goal.predicate.polarity
             {
-                if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
+                if DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
                     goal.predicate.trait_ref.args,
                     trait_clause.skip_binder().trait_ref.args,
                 ) {
-                    return Err(NoSolution);
+                    return Ok(());
                 }
-
-                ecx.probe_trait_candidate(source).enter(|ecx| {
-                    let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause);
-                    ecx.eq(
-                        goal.param_env,
-                        goal.predicate.trait_ref,
-                        assumption_trait_pred.trait_ref,
-                    )?;
-                    then(ecx)
-                })
-            } else {
-                Err(NoSolution)
             }
-        } else {
-            Err(NoSolution)
         }
+
+        Err(NoSolution)
+    }
+
+    fn match_assumption(
+        ecx: &mut EvalCtxt<'_, D>,
+        goal: Goal<I, Self>,
+        assumption: I::Clause,
+    ) -> Result<(), NoSolution> {
+        let trait_clause = assumption.as_trait_clause().unwrap();
+
+        let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause);
+        ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?;
+
+        Ok(())
     }
 
     fn consider_auto_trait_candidate(
@@ -1253,10 +1252,9 @@ where
     D: SolverDelegate<Interner = I>,
     I: Interner,
 {
-    #[instrument(level = "debug", skip(self, goal), ret)]
+    #[instrument(level = "debug", skip(self), ret)]
     pub(super) fn merge_trait_candidates(
         &mut self,
-        goal: Goal<I, TraitPredicate<I>>,
         mut candidates: Vec<Candidate<I>>,
     ) -> Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>), NoSolution> {
         if let TypingMode::Coherence = self.typing_mode() {
@@ -1284,21 +1282,9 @@ where
 
         // If there are non-global where-bounds, prefer where-bounds
         // (including global ones) over everything else.
-        let has_non_global_where_bounds = candidates.iter().any(|c| match c.source {
-            CandidateSource::ParamEnv(idx) => {
-                let where_bound = goal.param_env.caller_bounds().get(idx).unwrap();
-                let ty::ClauseKind::Trait(trait_pred) = where_bound.kind().skip_binder() else {
-                    unreachable!("expected trait-bound: {where_bound:?}");
-                };
-
-                if trait_pred.has_bound_vars() || !trait_pred.is_global() {
-                    return true;
-                }
-
-                false
-            }
-            _ => false,
-        });
+        let has_non_global_where_bounds = candidates
+            .iter()
+            .any(|c| matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)));
         if has_non_global_where_bounds {
             let where_bounds: Vec<_> = candidates
                 .iter()
@@ -1331,13 +1317,16 @@ where
         // is still reported as being proven-via the param-env so that rigid projections
         // operate correctly. Otherwise, drop all global where-bounds before merging the
         // remaining candidates.
-        let proven_via =
-            if candidates.iter().all(|c| matches!(c.source, CandidateSource::ParamEnv(_))) {
-                TraitGoalProvenVia::ParamEnv
-            } else {
-                candidates.retain(|c| !matches!(c.source, CandidateSource::ParamEnv(_)));
-                TraitGoalProvenVia::Misc
-            };
+        let proven_via = if candidates
+            .iter()
+            .all(|c| matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::Global)))
+        {
+            TraitGoalProvenVia::ParamEnv
+        } else {
+            candidates
+                .retain(|c| !matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::Global)));
+            TraitGoalProvenVia::Misc
+        };
 
         let all_candidates: Vec<_> = candidates.into_iter().map(|c| c.result).collect();
         if let Some(response) = self.try_merge_responses(&all_candidates) {
@@ -1353,7 +1342,7 @@ where
         goal: Goal<I, TraitPredicate<I>>,
     ) -> Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>), NoSolution> {
         let candidates = self.assemble_and_evaluate_candidates(goal, AssembleCandidatesFrom::All);
-        self.merge_trait_candidates(goal, candidates)
+        self.merge_trait_candidates(candidates)
     }
 
     fn try_stall_coroutine_witness(
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index ac4f7ed64e2..3d7e0fcc308 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -297,6 +297,19 @@ parse_forgot_paren = perhaps you forgot parentheses?
 parse_found_expr_would_be_stmt = expected expression, found `{$token}`
     .label = expected expression
 
+parse_frontmatter_extra_characters_after_close = extra characters after frontmatter close are not allowed
+parse_frontmatter_invalid_close_preceding_whitespace = invalid preceding whitespace for frontmatter close
+    .note = frontmatter close should not be preceded by whitespace
+parse_frontmatter_invalid_infostring = invalid infostring for frontmatter
+    .note = frontmatter infostrings must be a single identifier immediately following the opening
+parse_frontmatter_invalid_opening_preceding_whitespace = invalid preceding whitespace for frontmatter opening
+    .note = frontmatter opening should not be preceded by whitespace
+parse_frontmatter_length_mismatch = frontmatter close does not match the opening
+    .label_opening = the opening here has {$len_opening} dashes...
+    .label_close = ...while the close has {$len_close} dashes
+parse_frontmatter_unclosed = unclosed frontmatter
+    .note = frontmatter opening here was not closed
+
 parse_function_body_equals_expr = function body cannot be `= expression;`
     .suggestion = surround the expression with `{"{"}` and `{"}"}` instead of `=` and `;`
 
@@ -702,6 +715,16 @@ parse_parenthesized_lifetime_suggestion = remove the parentheses
 parse_path_double_colon = path separator must be a double colon
     .suggestion = use a double colon instead
 
+
+parse_path_found_attribute_in_params = `Trait(...)` syntax does not support attributes in parameters
+    .suggestion = remove the attributes
+
+parse_path_found_c_variadic_params = `Trait(...)` syntax does not support c_variadic parameters
+    .suggestion = remove the `...`
+
+parse_path_found_named_params = `Trait(...)` syntax does not support named parameters
+    .suggestion = remove the parameter name
+
 parse_pattern_method_param_without_body = patterns aren't allowed in methods without bodies
     .suggestion = give this argument a name or use an underscore to ignore it
 
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 6a6fb0eb9b5..766baf6f80c 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -736,6 +736,61 @@ pub(crate) struct FoundExprWouldBeStmt {
 }
 
 #[derive(Diagnostic)]
+#[diag(parse_frontmatter_extra_characters_after_close)]
+pub(crate) struct FrontmatterExtraCharactersAfterClose {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_frontmatter_invalid_infostring)]
+#[note]
+pub(crate) struct FrontmatterInvalidInfostring {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_frontmatter_invalid_opening_preceding_whitespace)]
+pub(crate) struct FrontmatterInvalidOpeningPrecedingWhitespace {
+    #[primary_span]
+    pub span: Span,
+    #[note]
+    pub note_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_frontmatter_unclosed)]
+pub(crate) struct FrontmatterUnclosed {
+    #[primary_span]
+    pub span: Span,
+    #[note]
+    pub note_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_frontmatter_invalid_close_preceding_whitespace)]
+pub(crate) struct FrontmatterInvalidClosingPrecedingWhitespace {
+    #[primary_span]
+    pub span: Span,
+    #[note]
+    pub note_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_frontmatter_length_mismatch)]
+pub(crate) struct FrontmatterLengthMismatch {
+    #[primary_span]
+    pub span: Span,
+    #[label(parse_label_opening)]
+    pub opening: Span,
+    #[label(parse_label_close)]
+    pub close: Span,
+    pub len_opening: usize,
+    pub len_close: usize,
+}
+
+#[derive(Diagnostic)]
 #[diag(parse_leading_plus_not_supported)]
 pub(crate) struct LeadingPlusNotSupported {
     #[primary_span]
@@ -1592,6 +1647,30 @@ pub(crate) struct ExpectedFnPathFoundFnKeyword {
 }
 
 #[derive(Diagnostic)]
+#[diag(parse_path_found_named_params)]
+pub(crate) struct FnPathFoundNamedParams {
+    #[primary_span]
+    #[suggestion(applicability = "machine-applicable", code = "")]
+    pub named_param_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_path_found_c_variadic_params)]
+pub(crate) struct PathFoundCVariadicParams {
+    #[primary_span]
+    #[suggestion(applicability = "machine-applicable", code = "")]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_path_found_attribute_in_params)]
+pub(crate) struct PathFoundAttributeInParams {
+    #[primary_span]
+    #[suggestion(applicability = "machine-applicable", code = "")]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(parse_path_double_colon)]
 pub(crate) struct PathSingleColon {
     #[primary_span]
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index e8a5cae54cf..78c5742414b 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -7,7 +7,9 @@ use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::util::unicode::contains_text_flow_control_chars;
 use rustc_errors::codes::*;
 use rustc_errors::{Applicability, Diag, DiagCtxtHandle, StashKey};
-use rustc_lexer::{Base, Cursor, DocStyle, LiteralKind, RawStrError};
+use rustc_lexer::{
+    Base, Cursor, DocStyle, FrontmatterAllowed, LiteralKind, RawStrError, is_whitespace,
+};
 use rustc_literal_escaper::{EscapeError, Mode, unescape_mixed, unescape_unicode};
 use rustc_session::lint::BuiltinLintDiag;
 use rustc_session::lint::builtin::{
@@ -15,7 +17,7 @@ use rustc_session::lint::builtin::{
     TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
 };
 use rustc_session::parse::ParseSess;
-use rustc_span::{BytePos, Pos, Span, Symbol};
+use rustc_span::{BytePos, Pos, Span, Symbol, sym};
 use tracing::debug;
 
 use crate::errors;
@@ -56,7 +58,7 @@ pub(crate) fn lex_token_trees<'psess, 'src>(
         start_pos = start_pos + BytePos::from_usize(shebang_len);
     }
 
-    let cursor = Cursor::new(src);
+    let cursor = Cursor::new(src, FrontmatterAllowed::Yes);
     let mut lexer = Lexer {
         psess,
         start_pos,
@@ -193,6 +195,11 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
                     let content = self.str_from_to(content_start, content_end);
                     self.cook_doc_comment(content_start, content, CommentKind::Block, doc_style)
                 }
+                rustc_lexer::TokenKind::Frontmatter { has_invalid_preceding_whitespace, invalid_infostring } => {
+                    self.validate_frontmatter(start, has_invalid_preceding_whitespace, invalid_infostring);
+                    preceded_by_whitespace = true;
+                    continue;
+                }
                 rustc_lexer::TokenKind::Whitespace => {
                     preceded_by_whitespace = true;
                     continue;
@@ -256,7 +263,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
                     // was consumed.
                     let lit_start = start + BytePos(prefix_len);
                     self.pos = lit_start;
-                    self.cursor = Cursor::new(&str_before[prefix_len as usize..]);
+                    self.cursor = Cursor::new(&str_before[prefix_len as usize..], FrontmatterAllowed::No);
                     self.report_unknown_prefix(start);
                     let prefix_span = self.mk_sp(start, lit_start);
                     return (Token::new(self.ident(start), prefix_span), preceded_by_whitespace);
@@ -361,7 +368,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
                         // Reset the state so we just lex the `'r`.
                         let lt_start = start + BytePos(2);
                         self.pos = lt_start;
-                        self.cursor = Cursor::new(&str_before[2 as usize..]);
+                        self.cursor = Cursor::new(&str_before[2 as usize..], FrontmatterAllowed::No);
 
                         let lifetime_name = self.str_from(start);
                         let ident = Symbol::intern(lifetime_name);
@@ -474,6 +481,91 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
         }
     }
 
+    fn validate_frontmatter(
+        &self,
+        start: BytePos,
+        has_invalid_preceding_whitespace: bool,
+        invalid_infostring: bool,
+    ) {
+        let s = self.str_from(start);
+        let real_start = s.find("---").unwrap();
+        let frontmatter_opening_pos = BytePos(real_start as u32) + start;
+        let s_new = &s[real_start..];
+        let within = s_new.trim_start_matches('-');
+        let len_opening = s_new.len() - within.len();
+
+        let frontmatter_opening_end_pos = frontmatter_opening_pos + BytePos(len_opening as u32);
+        if has_invalid_preceding_whitespace {
+            let line_start =
+                BytePos(s[..real_start].rfind("\n").map_or(0, |i| i as u32 + 1)) + start;
+            let span = self.mk_sp(line_start, frontmatter_opening_end_pos);
+            let label_span = self.mk_sp(line_start, frontmatter_opening_pos);
+            self.dcx().emit_err(errors::FrontmatterInvalidOpeningPrecedingWhitespace {
+                span,
+                note_span: label_span,
+            });
+        }
+
+        if invalid_infostring {
+            let line_end = s[real_start..].find('\n').unwrap_or(s[real_start..].len());
+            let span = self.mk_sp(
+                frontmatter_opening_end_pos,
+                frontmatter_opening_pos + BytePos(line_end as u32),
+            );
+            self.dcx().emit_err(errors::FrontmatterInvalidInfostring { span });
+        }
+
+        let last_line_start = within.rfind('\n').map_or(0, |i| i + 1);
+        let last_line = &within[last_line_start..];
+        let last_line_trimmed = last_line.trim_start_matches(is_whitespace);
+        let last_line_start_pos = frontmatter_opening_end_pos + BytePos(last_line_start as u32);
+
+        let frontmatter_span = self.mk_sp(frontmatter_opening_pos, self.pos);
+        self.psess.gated_spans.gate(sym::frontmatter, frontmatter_span);
+
+        if !last_line_trimmed.starts_with("---") {
+            let label_span = self.mk_sp(frontmatter_opening_pos, frontmatter_opening_end_pos);
+            self.dcx().emit_err(errors::FrontmatterUnclosed {
+                span: frontmatter_span,
+                note_span: label_span,
+            });
+            return;
+        }
+
+        if last_line_trimmed.len() != last_line.len() {
+            let line_end = last_line_start_pos + BytePos(last_line.len() as u32);
+            let span = self.mk_sp(last_line_start_pos, line_end);
+            let whitespace_end =
+                last_line_start_pos + BytePos((last_line.len() - last_line_trimmed.len()) as u32);
+            let label_span = self.mk_sp(last_line_start_pos, whitespace_end);
+            self.dcx().emit_err(errors::FrontmatterInvalidClosingPrecedingWhitespace {
+                span,
+                note_span: label_span,
+            });
+        }
+
+        let rest = last_line_trimmed.trim_start_matches('-');
+        let len_close = last_line_trimmed.len() - rest.len();
+        if len_close != len_opening {
+            let span = self.mk_sp(frontmatter_opening_pos, self.pos);
+            let opening = self.mk_sp(frontmatter_opening_pos, frontmatter_opening_end_pos);
+            let last_line_close_pos = last_line_start_pos + BytePos(len_close as u32);
+            let close = self.mk_sp(last_line_start_pos, last_line_close_pos);
+            self.dcx().emit_err(errors::FrontmatterLengthMismatch {
+                span,
+                opening,
+                close,
+                len_opening,
+                len_close,
+            });
+        }
+
+        if !rest.trim_matches(is_whitespace).is_empty() {
+            let span = self.mk_sp(last_line_start_pos, self.pos);
+            self.dcx().emit_err(errors::FrontmatterExtraCharactersAfterClose { span });
+        }
+    }
+
     fn cook_doc_comment(
         &self,
         content_start: BytePos,
@@ -839,7 +931,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
         let space_pos = start + BytePos(1);
         let space_span = self.mk_sp(space_pos, space_pos);
 
-        let mut cursor = Cursor::new(str_before);
+        let mut cursor = Cursor::new(str_before, FrontmatterAllowed::No);
 
         let (is_string, span, unterminated) = match cursor.guarded_double_quoted_string() {
             Some(rustc_lexer::GuardedStr { n_hashes, terminated, token_len }) => {
@@ -905,7 +997,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
             // For backwards compatibility, roll back to after just the first `#`
             // and return the `Pound` token.
             self.pos = start + BytePos(1);
-            self.cursor = Cursor::new(&str_before[1..]);
+            self.cursor = Cursor::new(&str_before[1..], FrontmatterAllowed::No);
             token::Pound
         }
     }
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index f3b53971b29..2a7910a6af4 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -3828,7 +3828,7 @@ impl<'a> Parser<'a> {
         // Convert `label` -> `'label`,
         // so that nameres doesn't complain about non-existing label
         let label = format!("'{}", ident.name);
-        let ident = Ident { name: Symbol::intern(&label), span: ident.span };
+        let ident = Ident::new(Symbol::intern(&label), ident.span);
 
         self.dcx().emit_err(errors::ExpectedLabelFoundIdent {
             span: ident.span,
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 4be8a90368d..babc55ccc0f 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2894,7 +2894,7 @@ impl<'a> Parser<'a> {
         let (mut params, _) = self.parse_paren_comma_seq(|p| {
             p.recover_vcs_conflict_marker();
             let snapshot = p.create_snapshot_for_diagnostic();
-            let param = p.parse_param_general(req_name, first_param).or_else(|e| {
+            let param = p.parse_param_general(req_name, first_param, true).or_else(|e| {
                 let guar = e.emit();
                 // When parsing a param failed, we should check to make the span of the param
                 // not contain '(' before it.
@@ -2922,7 +2922,13 @@ impl<'a> Parser<'a> {
     /// Parses a single function parameter.
     ///
     /// - `self` is syntactically allowed when `first_param` holds.
-    fn parse_param_general(&mut self, req_name: ReqName, first_param: bool) -> PResult<'a, Param> {
+    /// - `recover_arg_parse` is used to recover from a failed argument parse.
+    pub(super) fn parse_param_general(
+        &mut self,
+        req_name: ReqName,
+        first_param: bool,
+        recover_arg_parse: bool,
+    ) -> PResult<'a, Param> {
         let lo = self.token.span;
         let attrs = self.parse_outer_attributes()?;
         self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
@@ -2990,12 +2996,13 @@ impl<'a> Parser<'a> {
                     // If this is a C-variadic argument and we hit an error, return the error.
                     Err(err) if this.token == token::DotDotDot => return Err(err),
                     Err(err) if this.unmatched_angle_bracket_count > 0 => return Err(err),
-                    // Recover from attempting to parse the argument as a type without pattern.
-                    Err(err) => {
+                    Err(err) if recover_arg_parse => {
+                        // Recover from attempting to parse the argument as a type without pattern.
                         err.cancel();
                         this.restore_snapshot(parser_snapshot_before_ty);
                         this.recover_arg_parse()?
                     }
+                    Err(err) => return Err(err),
                 }
             };
 
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 1093e4f4af0..9bce2fa74ca 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -15,7 +15,11 @@ use tracing::debug;
 
 use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
 use super::{Parser, Restrictions, TokenType};
-use crate::errors::{self, PathSingleColon, PathTripleColon};
+use crate::ast::{PatKind, TyKind};
+use crate::errors::{
+    self, FnPathFoundNamedParams, PathFoundAttributeInParams, PathFoundCVariadicParams,
+    PathSingleColon, PathTripleColon,
+};
 use crate::exp;
 use crate::parser::{CommaRecoveryMode, RecoverColon, RecoverComma};
 
@@ -396,7 +400,28 @@ impl<'a> Parser<'a> {
                         snapshot = Some(self.create_snapshot_for_diagnostic());
                     }
 
-                    let (inputs, _) = match self.parse_paren_comma_seq(|p| p.parse_ty()) {
+                    let dcx = self.dcx();
+                    let parse_params_result = self.parse_paren_comma_seq(|p| {
+                        let param = p.parse_param_general(|_| false, false, false);
+                        param.map(move |param| {
+                            if !matches!(param.pat.kind, PatKind::Missing) {
+                                dcx.emit_err(FnPathFoundNamedParams {
+                                    named_param_span: param.pat.span,
+                                });
+                            }
+                            if matches!(param.ty.kind, TyKind::CVarArgs) {
+                                dcx.emit_err(PathFoundCVariadicParams { span: param.pat.span });
+                            }
+                            if !param.attrs.is_empty() {
+                                dcx.emit_err(PathFoundAttributeInParams {
+                                    span: param.attrs[0].span,
+                                });
+                            }
+                            param.ty
+                        })
+                    });
+
+                    let (inputs, _) = match parse_params_result {
                         Ok(output) => output,
                         Err(mut error) if prev_token_before_parsing == token::PathSep => {
                             error.span_label(
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index 6a1c2af48ed..378cbb84637 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -3,7 +3,8 @@
 use rustc_ast::token::Delimiter;
 use rustc_ast::tokenstream::DelimSpan;
 use rustc_ast::{
-    self as ast, AttrArgs, Attribute, DelimArgs, MetaItem, MetaItemInner, MetaItemKind, Safety,
+    self as ast, AttrArgs, Attribute, DelimArgs, MetaItem, MetaItemInner, MetaItemKind, NodeId,
+    Safety,
 };
 use rustc_errors::{Applicability, FatalError, PResult};
 use rustc_feature::{AttributeSafety, AttributeTemplate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute};
@@ -15,21 +16,19 @@ use rustc_span::{Span, Symbol, sym};
 
 use crate::{errors, parse_in};
 
-pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
+pub fn check_attr(psess: &ParseSess, attr: &Attribute, id: NodeId) {
     if attr.is_doc_comment() || attr.has_name(sym::cfg_trace) || attr.has_name(sym::cfg_attr_trace)
     {
         return;
     }
 
-    let attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name));
-    let attr_item = attr.get_normal_item();
+    let builtin_attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name));
 
-    // All non-builtin attributes are considered safe
-    let safety = attr_info.map(|x| x.safety).unwrap_or(AttributeSafety::Normal);
-    check_attribute_safety(psess, safety, attr);
+    let builtin_attr_safety = builtin_attr_info.map(|x| x.safety);
+    check_attribute_safety(psess, builtin_attr_safety, attr, id);
 
     // Check input tokens for built-in and key-value attributes.
-    match attr_info {
+    match builtin_attr_info {
         // `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
         Some(BuiltinAttribute { name, template, .. }) if *name != sym::rustc_dummy => {
             match parse_meta(psess, attr) {
@@ -43,6 +42,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
             }
         }
         _ => {
+            let attr_item = attr.get_normal_item();
             if let AttrArgs::Eq { .. } = attr_item.args {
                 // All key-value attributes are restricted to meta-item syntax.
                 match parse_meta(psess, attr) {
@@ -154,11 +154,23 @@ fn is_attr_template_compatible(template: &AttributeTemplate, meta: &ast::MetaIte
     }
 }
 
-pub fn check_attribute_safety(psess: &ParseSess, safety: AttributeSafety, attr: &Attribute) {
+pub fn check_attribute_safety(
+    psess: &ParseSess,
+    builtin_attr_safety: Option<AttributeSafety>,
+    attr: &Attribute,
+    id: NodeId,
+) {
     let attr_item = attr.get_normal_item();
+    match (builtin_attr_safety, attr_item.unsafety) {
+        // - Unsafe builtin attribute
+        // - User wrote `#[unsafe(..)]`, which is permitted on any edition
+        (Some(AttributeSafety::Unsafe { .. }), Safety::Unsafe(..)) => {
+            // OK
+        }
 
-    if let AttributeSafety::Unsafe { unsafe_since } = safety {
-        if let ast::Safety::Default = attr_item.unsafety {
+        // - Unsafe builtin attribute
+        // - User did not write `#[unsafe(..)]`
+        (Some(AttributeSafety::Unsafe { unsafe_since }), Safety::Default) => {
             let path_span = attr_item.path.span;
 
             // If the `attr_item`'s span is not from a macro, then just suggest
@@ -185,7 +197,7 @@ pub fn check_attribute_safety(psess: &ParseSess, safety: AttributeSafety, attr:
                 psess.buffer_lint(
                     UNSAFE_ATTR_OUTSIDE_UNSAFE,
                     path_span,
-                    ast::CRATE_NODE_ID,
+                    id,
                     BuiltinLintDiag::UnsafeAttrOutsideUnsafe {
                         attribute_name_span: path_span,
                         sugg_spans: (diag_span.shrink_to_lo(), diag_span.shrink_to_hi()),
@@ -193,11 +205,38 @@ pub fn check_attribute_safety(psess: &ParseSess, safety: AttributeSafety, attr:
                 );
             }
         }
-    } else if let Safety::Unsafe(unsafe_span) = attr_item.unsafety {
-        psess.dcx().emit_err(errors::InvalidAttrUnsafe {
-            span: unsafe_span,
-            name: attr_item.path.clone(),
-        });
+
+        // - Normal builtin attribute, or any non-builtin attribute
+        // - All non-builtin attributes are currently considered safe; writing `#[unsafe(..)]` is
+        //   not permitted on non-builtin attributes or normal builtin attributes
+        (Some(AttributeSafety::Normal) | None, Safety::Unsafe(unsafe_span)) => {
+            psess.dcx().emit_err(errors::InvalidAttrUnsafe {
+                span: unsafe_span,
+                name: attr_item.path.clone(),
+            });
+        }
+
+        // - Normal builtin attribute
+        // - No explicit `#[unsafe(..)]` written.
+        (Some(AttributeSafety::Normal), Safety::Default) => {
+            // OK
+        }
+
+        // - Non-builtin attribute
+        // - No explicit `#[unsafe(..)]` written.
+        (None, Safety::Default) => {
+            // OK
+        }
+
+        (
+            Some(AttributeSafety::Unsafe { .. } | AttributeSafety::Normal) | None,
+            Safety::Safe(..),
+        ) => {
+            psess.dcx().span_delayed_bug(
+                attr_item.span(),
+                "`check_attribute_safety` does not expect `Safety::Safe` on attributes",
+            );
+        }
     }
 }
 
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index c59e6cb5c33..9dd064aca66 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -15,50 +15,13 @@
 )]
 // tidy-alphabetical-end
 
+use std::ops::Range;
+
 pub use Alignment::*;
 pub use Count::*;
 pub use Position::*;
 use rustc_literal_escaper::{Mode, unescape_unicode};
 
-// Note: copied from rustc_span
-/// Range inside of a `Span` used for diagnostics when we only have access to relative positions.
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-pub struct InnerSpan {
-    pub start: usize,
-    pub end: usize,
-}
-
-impl InnerSpan {
-    pub fn new(start: usize, end: usize) -> InnerSpan {
-        InnerSpan { start, end }
-    }
-}
-
-/// The location and before/after width of a character whose width has changed from its source code
-/// representation
-#[derive(Copy, Clone, PartialEq, Eq)]
-pub struct InnerWidthMapping {
-    /// Index of the character in the source
-    pub position: usize,
-    /// The inner width in characters
-    pub before: usize,
-    /// The transformed width in characters
-    pub after: usize,
-}
-
-impl InnerWidthMapping {
-    pub fn new(position: usize, before: usize, after: usize) -> InnerWidthMapping {
-        InnerWidthMapping { position, before, after }
-    }
-}
-
-/// Whether the input string is a literal. If yes, it contains the inner width mappings.
-#[derive(Clone, PartialEq, Eq)]
-enum InputStringKind {
-    NotALiteral,
-    Literal { width_mappings: Vec<InnerWidthMapping> },
-}
-
 /// The type of format string that we are parsing.
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub enum ParseMode {
@@ -68,15 +31,6 @@ pub enum ParseMode {
     InlineAsm,
 }
 
-#[derive(Copy, Clone)]
-struct InnerOffset(usize);
-
-impl InnerOffset {
-    fn to(self, end: InnerOffset) -> InnerSpan {
-        InnerSpan::new(self.0, end.0)
-    }
-}
-
 /// A piece is a portion of the format string which represents the next part
 /// to emit. These are emitted as a stream by the `Parser` class.
 #[derive(Clone, Debug, PartialEq)]
@@ -89,24 +43,48 @@ pub enum Piece<'a> {
 }
 
 /// Representation of an argument specification.
-#[derive(Copy, Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq)]
 pub struct Argument<'a> {
     /// Where to find this argument
     pub position: Position<'a>,
     /// The span of the position indicator. Includes any whitespace in implicit
     /// positions (`{  }`).
-    pub position_span: InnerSpan,
+    pub position_span: Range<usize>,
     /// How to format the argument
     pub format: FormatSpec<'a>,
 }
 
+impl<'a> Argument<'a> {
+    pub fn is_identifier(&self) -> bool {
+        matches!(self.position, Position::ArgumentNamed(_))
+            && matches!(
+                self.format,
+                FormatSpec {
+                    fill: None,
+                    fill_span: None,
+                    align: AlignUnknown,
+                    sign: None,
+                    alternate: false,
+                    zero_pad: false,
+                    debug_hex: None,
+                    precision: CountImplied,
+                    precision_span: None,
+                    width: CountImplied,
+                    width_span: None,
+                    ty: "",
+                    ty_span: None,
+                },
+            )
+    }
+}
+
 /// Specification for the formatting of an argument in the format string.
-#[derive(Copy, Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq)]
 pub struct FormatSpec<'a> {
     /// Optionally specified character to fill alignment with.
     pub fill: Option<char>,
     /// Span of the optionally specified fill character.
-    pub fill_span: Option<InnerSpan>,
+    pub fill_span: Option<Range<usize>>,
     /// Optionally specified alignment.
     pub align: Alignment,
     /// The `+` or `-` flag.
@@ -120,21 +98,21 @@ pub struct FormatSpec<'a> {
     /// The integer precision to use.
     pub precision: Count<'a>,
     /// The span of the precision formatting flag (for diagnostics).
-    pub precision_span: Option<InnerSpan>,
+    pub precision_span: Option<Range<usize>>,
     /// The string width requested for the resulting format.
     pub width: Count<'a>,
     /// The span of the width formatting flag (for diagnostics).
-    pub width_span: Option<InnerSpan>,
+    pub width_span: Option<Range<usize>>,
     /// The descriptor string representing the name of the format desired for
     /// this argument, this can be empty or any number of characters, although
     /// it is required to be one word.
     pub ty: &'a str,
     /// The span of the descriptor string (for diagnostics).
-    pub ty_span: Option<InnerSpan>,
+    pub ty_span: Option<Range<usize>>,
 }
 
 /// Enum describing where an argument for a format can be located.
-#[derive(Copy, Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq)]
 pub enum Position<'a> {
     /// The argument is implied to be located at an index
     ArgumentImplicitlyIs(usize),
@@ -186,12 +164,12 @@ pub enum DebugHex {
 
 /// A count is used for the precision and width parameters of an integer, and
 /// can reference either an argument or a literal integer.
-#[derive(Copy, Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq)]
 pub enum Count<'a> {
     /// The count is specified explicitly.
     CountIs(u16),
     /// The count is specified by the argument with the given name.
-    CountIsName(&'a str, InnerSpan),
+    CountIsName(&'a str, Range<usize>),
     /// The count is specified by the argument at the given index.
     CountIsParam(usize),
     /// The count is specified by a star (like in `{:.*}`) that refers to the argument at the given index.
@@ -204,8 +182,8 @@ pub struct ParseError {
     pub description: String,
     pub note: Option<String>,
     pub label: String,
-    pub span: InnerSpan,
-    pub secondary_label: Option<(String, InnerSpan)>,
+    pub span: Range<usize>,
+    pub secondary_label: Option<(String, Range<usize>)>,
     pub suggestion: Suggestion,
 }
 
@@ -216,12 +194,12 @@ pub enum Suggestion {
     UsePositional,
     /// Remove `r#` from identifier:
     /// `format!("{r#foo}")` -> `format!("{foo}")`
-    RemoveRawIdent(InnerSpan),
+    RemoveRawIdent(Range<usize>),
     /// Reorder format parameter:
     /// `format!("{foo:?#}")` -> `format!("{foo:#?}")`
     /// `format!("{foo:?x}")` -> `format!("{foo:x?}")`
     /// `format!("{foo:?X}")` -> `format!("{foo:X?}")`
-    ReorderFormatParameter(InnerSpan, String),
+    ReorderFormatParameter(Range<usize>, String),
 }
 
 /// The parser structure for interpreting the input format string. This is
@@ -232,92 +210,94 @@ pub enum Suggestion {
 /// necessary there's probably lots of room for improvement performance-wise.
 pub struct Parser<'a> {
     mode: ParseMode,
+    /// Input to be parsed
     input: &'a str,
-    cur: std::iter::Peekable<std::str::CharIndices<'a>>,
+    /// Tuples of the span in the code snippet (input as written before being unescaped), the pos in input, and the char in input
+    input_vec: Vec<(Range<usize>, usize, char)>,
+    /// Index into input_vec
+    input_vec_index: usize,
     /// Error messages accumulated during parsing
     pub errors: Vec<ParseError>,
     /// Current position of implicit positional argument pointer
     pub curarg: usize,
-    /// `Some(raw count)` when the string is "raw", used to position spans correctly
-    style: Option<usize>,
     /// Start and end byte offset of every successfully parsed argument
-    pub arg_places: Vec<InnerSpan>,
-    /// Characters whose length has been changed from their in-code representation
-    width_map: Vec<InnerWidthMapping>,
+    pub arg_places: Vec<Range<usize>>,
     /// Span of the last opening brace seen, used for error reporting
-    last_opening_brace: Option<InnerSpan>,
-    /// Whether the source string is comes from `println!` as opposed to `format!` or `print!`
-    append_newline: bool,
+    last_open_brace: Option<Range<usize>>,
     /// Whether this formatting string was written directly in the source. This controls whether we
     /// can use spans to refer into it and give better error messages.
     /// N.B: This does _not_ control whether implicit argument captures can be used.
     pub is_source_literal: bool,
+    /// Index to the end of the literal snippet
+    end_of_snippet: usize,
     /// Start position of the current line.
     cur_line_start: usize,
     /// Start and end byte offset of every line of the format string. Excludes
     /// newline characters and leading whitespace.
-    pub line_spans: Vec<InnerSpan>,
+    pub line_spans: Vec<Range<usize>>,
 }
 
 impl<'a> Iterator for Parser<'a> {
     type Item = Piece<'a>;
 
     fn next(&mut self) -> Option<Piece<'a>> {
-        if let Some(&(pos, c)) = self.cur.peek() {
-            match c {
+        if let Some(&(Range { start, end }, idx, ch)) = self.input_vec.get(self.input_vec_index) {
+            match ch {
                 '{' => {
-                    let curr_last_brace = self.last_opening_brace;
-                    let byte_pos = self.to_span_index(pos);
-                    let lbrace_end = InnerOffset(byte_pos.0 + self.to_span_width(pos));
-                    self.last_opening_brace = Some(byte_pos.to(lbrace_end));
-                    self.cur.next();
-                    if self.consume('{') {
-                        self.last_opening_brace = curr_last_brace;
-
-                        Some(Piece::Lit(self.string(pos + 1)))
+                    self.input_vec_index += 1;
+                    if let Some(&(_, i, '{')) = self.input_vec.get(self.input_vec_index) {
+                        self.input_vec_index += 1;
+                        // double open brace escape: "{{"
+                        // next state after this is either end-of-input or seen-a-brace
+                        Some(Piece::Lit(self.string(i)))
                     } else {
-                        let arg = self.argument(lbrace_end);
-                        if let Some(rbrace_pos) = self.consume_closing_brace(&arg) {
+                        // single open brace
+                        self.last_open_brace = Some(start..end);
+                        let arg = self.argument();
+                        if let Some(close_brace_range) = self.consume_closing_brace(&arg) {
                             if self.is_source_literal {
-                                let lbrace_byte_pos = self.to_span_index(pos);
-                                let rbrace_byte_pos = self.to_span_index(rbrace_pos);
-
-                                let width = self.to_span_width(rbrace_pos);
-
-                                self.arg_places.push(
-                                    lbrace_byte_pos.to(InnerOffset(rbrace_byte_pos.0 + width)),
-                                );
+                                self.arg_places.push(start..close_brace_range.end);
                             }
-                        } else if let Some(&(_, maybe)) = self.cur.peek() {
-                            match maybe {
+                        } else if let Some(&(_, _, c)) = self.input_vec.get(self.input_vec_index) {
+                            match c {
                                 '?' => self.suggest_format_debug(),
-                                '<' | '^' | '>' => self.suggest_format_align(maybe),
-                                _ => self.suggest_positional_arg_instead_of_captured_arg(arg),
+                                '<' | '^' | '>' => self.suggest_format_align(c),
+                                _ => {
+                                    self.suggest_positional_arg_instead_of_captured_arg(arg.clone())
+                                }
                             }
                         }
                         Some(Piece::NextArgument(Box::new(arg)))
                     }
                 }
                 '}' => {
-                    self.cur.next();
-                    if self.consume('}') {
-                        Some(Piece::Lit(self.string(pos + 1)))
+                    self.input_vec_index += 1;
+                    if let Some(&(_, i, '}')) = self.input_vec.get(self.input_vec_index) {
+                        self.input_vec_index += 1;
+                        // double close brace escape: "}}"
+                        // next state after this is either end-of-input or start
+                        Some(Piece::Lit(self.string(i)))
                     } else {
-                        let err_pos = self.to_span_index(pos);
-                        self.err_with_note(
-                            "unmatched `}` found",
-                            "unmatched `}`",
-                            "if you intended to print `}`, you can escape it using `}}`",
-                            err_pos.to(err_pos),
-                        );
+                        // error: single close brace without corresponding open brace
+                        self.errors.push(ParseError {
+                            description: "unmatched `}` found".into(),
+                            note: Some(
+                                "if you intended to print `}`, you can escape it using `}}`".into(),
+                            ),
+                            label: "unmatched `}`".into(),
+                            span: start..end,
+                            secondary_label: None,
+                            suggestion: Suggestion::None,
+                        });
                         None
                     }
                 }
-                _ => Some(Piece::Lit(self.string(pos))),
+                _ => Some(Piece::Lit(self.string(idx))),
             }
         } else {
+            // end of input
             if self.is_source_literal {
-                let span = self.span(self.cur_line_start, self.input.len());
+                let span = self.cur_line_start..self.end_of_snippet;
                 if self.line_spans.last() != Some(&span) {
                     self.line_spans.push(span);
                 }
@@ -328,71 +308,104 @@ impl<'a> Iterator for Parser<'a> {
 }
 
 impl<'a> Parser<'a> {
-    /// Creates a new parser for the given format string
+    /// Creates a new parser for the given unescaped input string and
+    /// optional code snippet (the input as written before being unescaped),
+    /// where `style` is `Some(nr_hashes)` when the snippet is a raw string with that many hashes.
+    /// If the input comes via `println` or `panic`, then it has a newline already appended,
+    /// which is reflected in the `appended_newline` parameter.
     pub fn new(
-        s: &'a str,
+        input: &'a str,
         style: Option<usize>,
         snippet: Option<String>,
-        append_newline: bool,
+        appended_newline: bool,
         mode: ParseMode,
-    ) -> Parser<'a> {
-        let input_string_kind = find_width_map_from_snippet(s, snippet, style);
-        let (width_map, is_source_literal) = match input_string_kind {
-            InputStringKind::Literal { width_mappings } => (width_mappings, true),
-            InputStringKind::NotALiteral => (Vec::new(), false),
+    ) -> Self {
+        let quote_offset = style.map_or(1, |nr_hashes| nr_hashes + 2);
+
+        let (is_source_literal, end_of_snippet, pre_input_vec) = if let Some(snippet) = snippet {
+            if let Some(nr_hashes) = style {
+                // snippet is a raw string, which starts with 'r', a number of hashes, and a quote
+                // and ends with a quote and the same number of hashes
+                (true, snippet.len() - nr_hashes - 1, vec![])
+            } else {
+                // snippet is not a raw string
+                if snippet.starts_with('"') {
+                    // snippet looks like an ordinary string literal
+                    // check whether it is the escaped version of input
+                    let without_quotes = &snippet[1..snippet.len() - 1];
+                    let (mut ok, mut vec) = (true, vec![]);
+                    let mut chars = input.chars();
+                    unescape_unicode(without_quotes, Mode::Str, &mut |range, res| match res {
+                        Ok(ch) if ok && chars.next().is_some_and(|c| ch == c) => {
+                            vec.push((range, ch));
+                        }
+                        _ => {
+                            ok = false;
+                            vec = vec![];
+                        }
+                    });
+                    let end = vec.last().map(|(r, _)| r.end).unwrap_or(0);
+                    if ok {
+                        if appended_newline {
+                            if chars.as_str() == "\n" {
+                                vec.push((end..end + 1, '\n'));
+                                (true, 1 + end, vec)
+                            } else {
+                                (false, snippet.len(), vec![])
+                            }
+                        } else if chars.as_str() == "" {
+                            (true, 1 + end, vec)
+                        } else {
+                            (false, snippet.len(), vec![])
+                        }
+                    } else {
+                        (false, snippet.len(), vec![])
+                    }
+                } else {
+                    // snippet is not a raw string and does not start with '"'
+                    (false, snippet.len(), vec![])
+                }
+            }
+        } else {
+            // snippet is None
+            (false, input.len() - if appended_newline { 1 } else { 0 }, vec![])
+        };
+
+        let input_vec: Vec<(Range<usize>, usize, char)> = if pre_input_vec.is_empty() {
+            // Snippet is *not* input before unescaping, so spans pointing at it will be incorrect.
+            // This can happen with proc macros that respan generated literals.
+            input
+                .char_indices()
+                .map(|(idx, c)| {
+                    let i = idx + quote_offset;
+                    (i..i + c.len_utf8(), idx, c)
+                })
+                .collect()
+        } else {
+            // Snippet is input before unescaping
+            input
+                .char_indices()
+                .zip(pre_input_vec)
+                .map(|((i, c), (r, _))| (r.start + quote_offset..r.end + quote_offset, i, c))
+                .collect()
         };
 
         Parser {
             mode,
-            input: s,
-            cur: s.char_indices().peekable(),
+            input,
+            input_vec,
+            input_vec_index: 0,
             errors: vec![],
             curarg: 0,
-            style,
             arg_places: vec![],
-            width_map,
-            last_opening_brace: None,
-            append_newline,
+            last_open_brace: None,
             is_source_literal,
-            cur_line_start: 0,
+            end_of_snippet,
+            cur_line_start: quote_offset,
             line_spans: vec![],
         }
     }
 
-    /// Notifies of an error. The message doesn't actually need to be of type
-    /// String, but I think it does when this eventually uses conditions so it
-    /// might as well start using it now.
-    fn err(&mut self, description: impl Into<String>, label: impl Into<String>, span: InnerSpan) {
-        self.errors.push(ParseError {
-            description: description.into(),
-            note: None,
-            label: label.into(),
-            span,
-            secondary_label: None,
-            suggestion: Suggestion::None,
-        });
-    }
-
-    /// Notifies of an error. The message doesn't actually need to be of type
-    /// String, but I think it does when this eventually uses conditions so it
-    /// might as well start using it now.
-    fn err_with_note(
-        &mut self,
-        description: impl Into<String>,
-        label: impl Into<String>,
-        note: impl Into<String>,
-        span: InnerSpan,
-    ) {
-        self.errors.push(ParseError {
-            description: description.into(),
-            note: Some(note.into()),
-            label: label.into(),
-            span,
-            secondary_label: None,
-            suggestion: Suggestion::None,
-        });
-    }
-
     /// Optionally consumes the specified character. If the character is not at
     /// the current position, then the current iterator isn't moved and `false` is
     /// returned, otherwise the character is consumed and `true` is returned.
@@ -404,94 +417,56 @@ impl<'a> Parser<'a> {
     /// the current position, then the current iterator isn't moved and `None` is
     /// returned, otherwise the character is consumed and the current position is
     /// returned.
-    fn consume_pos(&mut self, c: char) -> Option<usize> {
-        if let Some(&(pos, maybe)) = self.cur.peek() {
-            if c == maybe {
-                self.cur.next();
-                return Some(pos);
+    fn consume_pos(&mut self, ch: char) -> Option<(Range<usize>, usize)> {
+        if let Some((r, i, c)) = self.input_vec.get(self.input_vec_index) {
+            if ch == *c {
+                self.input_vec_index += 1;
+                return Some((r.clone(), *i));
             }
         }
         None
     }
 
-    fn remap_pos(&self, mut pos: usize) -> InnerOffset {
-        for width in &self.width_map {
-            if pos > width.position {
-                pos += width.before - width.after;
-            } else if pos == width.position && width.after == 0 {
-                pos += width.before;
-            } else {
-                break;
-            }
-        }
-
-        InnerOffset(pos)
-    }
-
-    fn to_span_index(&self, pos: usize) -> InnerOffset {
-        // This handles the raw string case, the raw argument is the number of #
-        // in r###"..."### (we need to add one because of the `r`).
-        let raw = self.style.map_or(0, |raw| raw + 1);
-        let pos = self.remap_pos(pos);
-        InnerOffset(raw + pos.0 + 1)
-    }
-
-    fn to_span_width(&self, pos: usize) -> usize {
-        let pos = self.remap_pos(pos);
-        match self.width_map.iter().find(|w| w.position == pos.0) {
-            Some(w) => w.before,
-            None => 1,
-        }
-    }
-
-    fn span(&self, start_pos: usize, end_pos: usize) -> InnerSpan {
-        let start = self.to_span_index(start_pos);
-        let end = self.to_span_index(end_pos);
-        start.to(end)
-    }
-
     /// Forces consumption of the specified character. If the character is not
     /// found, an error is emitted.
-    fn consume_closing_brace(&mut self, arg: &Argument<'_>) -> Option<usize> {
+    fn consume_closing_brace(&mut self, arg: &Argument<'_>) -> Option<Range<usize>> {
         self.ws();
 
-        let pos;
-        let description;
-
-        if let Some(&(peek_pos, maybe)) = self.cur.peek() {
-            if maybe == '}' {
-                self.cur.next();
-                return Some(peek_pos);
+        let (range, description) = if let Some((r, _, c)) = self.input_vec.get(self.input_vec_index)
+        {
+            if *c == '}' {
+                self.input_vec_index += 1;
+                return Some(r.clone());
             }
-
-            pos = peek_pos;
-            description = format!("expected `}}`, found `{}`", maybe.escape_debug());
+            // or r.clone()?
+            (r.start..r.start, format!("expected `}}`, found `{}`", c.escape_debug()))
         } else {
-            description = "expected `}` but string was terminated".to_owned();
-            // point at closing `"`
-            pos = self.input.len() - if self.append_newline { 1 } else { 0 };
-        }
-
-        let pos = self.to_span_index(pos);
+            (
+                // point at closing `"`
+                self.end_of_snippet..self.end_of_snippet,
+                "expected `}` but string was terminated".to_owned(),
+            )
+        };
 
-        let label = "expected `}`".to_owned();
         let (note, secondary_label) = if arg.format.fill == Some('}') {
             (
                 Some("the character `}` is interpreted as a fill character because of the `:` that precedes it".to_owned()),
-                arg.format.fill_span.map(|sp| ("this is not interpreted as a formatting closing brace".to_owned(), sp)),
+                arg.format.fill_span.clone().map(|sp| ("this is not interpreted as a formatting closing brace".to_owned(), sp)),
             )
         } else {
             (
                 Some("if you intended to print `{`, you can escape it using `{{`".to_owned()),
-                self.last_opening_brace.map(|sp| ("because of this opening brace".to_owned(), sp)),
+                self.last_open_brace
+                    .clone()
+                    .map(|sp| ("because of this opening brace".to_owned(), sp)),
             )
         };
 
         self.errors.push(ParseError {
             description,
             note,
-            label,
-            span: pos.to(pos),
+            label: "expected `}`".to_owned(),
+            span: range.start..range.start,
             secondary_label,
             suggestion: Suggestion::None,
         });
@@ -501,28 +476,30 @@ impl<'a> Parser<'a> {
 
     /// Consumes all whitespace characters until the first non-whitespace character
     fn ws(&mut self) {
-        while let Some(_) = self.cur.next_if(|&(_, c)| c.is_whitespace()) {}
+        let rest = &self.input_vec[self.input_vec_index..];
+        let step = rest.iter().position(|&(_, _, c)| !c.is_whitespace()).unwrap_or(rest.len());
+        self.input_vec_index += step;
     }
 
     /// Parses all of a string which is to be considered a "raw literal" in a
     /// format string. This is everything outside of the braces.
     fn string(&mut self, start: usize) -> &'a str {
-        // we may not consume the character, peek the iterator
-        while let Some(&(pos, c)) = self.cur.peek() {
+        while let Some((r, i, c)) = self.input_vec.get(self.input_vec_index) {
             match c {
                 '{' | '}' => {
-                    return &self.input[start..pos];
+                    return &self.input[start..*i];
                 }
                 '\n' if self.is_source_literal => {
-                    self.line_spans.push(self.span(self.cur_line_start, pos));
-                    self.cur_line_start = pos + 1;
-                    self.cur.next();
+                    self.input_vec_index += 1;
+                    self.line_spans.push(self.cur_line_start..r.start);
+                    self.cur_line_start = r.end;
                 }
                 _ => {
-                    if self.is_source_literal && pos == self.cur_line_start && c.is_whitespace() {
-                        self.cur_line_start = pos + c.len_utf8();
+                    self.input_vec_index += 1;
+                    if self.is_source_literal && r.start == self.cur_line_start && c.is_whitespace()
+                    {
+                        self.cur_line_start = r.end;
                     }
-                    self.cur.next();
                 }
             }
         }
@@ -530,15 +507,13 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses an `Argument` structure, or what's contained within braces inside the format string.
-    fn argument(&mut self, start: InnerOffset) -> Argument<'a> {
-        let pos = self.position();
+    fn argument(&mut self) -> Argument<'a> {
+        let start_idx = self.input_vec_index;
 
-        let end = self
-            .cur
-            .clone()
-            .find(|(_, ch)| !ch.is_whitespace())
-            .map_or(start, |(end, _)| self.to_span_index(end));
-        let position_span = start.to(end);
+        let position = self.position();
+        self.ws();
+
+        let end_idx = self.input_vec_index;
 
         let format = match self.mode {
             ParseMode::Format => self.format(),
@@ -546,16 +521,15 @@ impl<'a> Parser<'a> {
         };
 
         // Resolve position after parsing format spec.
-        let pos = match pos {
-            Some(position) => position,
-            None => {
-                let i = self.curarg;
-                self.curarg += 1;
-                ArgumentImplicitlyIs(i)
-            }
-        };
+        let position = position.unwrap_or_else(|| {
+            let i = self.curarg;
+            self.curarg += 1;
+            ArgumentImplicitlyIs(i)
+        });
 
-        Argument { position: pos, position_span, format }
+        let position_span =
+            self.input_vec_index2range(start_idx).start..self.input_vec_index2range(end_idx).start;
+        Argument { position, position_span, format }
     }
 
     /// Parses a positional argument for a format. This could either be an
@@ -566,23 +540,26 @@ impl<'a> Parser<'a> {
         if let Some(i) = self.integer() {
             Some(ArgumentIs(i.into()))
         } else {
-            match self.cur.peek() {
-                Some(&(lo, c)) if rustc_lexer::is_id_start(c) => {
+            match self.input_vec.get(self.input_vec_index) {
+                Some((range, _, c)) if rustc_lexer::is_id_start(*c) => {
+                    let start = range.start;
                     let word = self.word();
 
                     // Recover from `r#ident` in format strings.
                     // FIXME: use a let chain
                     if word == "r" {
-                        if let Some((pos, '#')) = self.cur.peek() {
-                            if self.input[pos + 1..]
-                                .chars()
-                                .next()
-                                .is_some_and(rustc_lexer::is_id_start)
+                        if let Some((r, _, '#')) = self.input_vec.get(self.input_vec_index) {
+                            if self
+                                .input_vec
+                                .get(self.input_vec_index + 1)
+                                .is_some_and(|(_, _, c)| rustc_lexer::is_id_start(*c))
                             {
-                                self.cur.next();
+                                self.input_vec_index += 1;
+                                let prefix_end = r.end;
                                 let word = self.word();
-                                let prefix_span = self.span(lo, lo + 2);
-                                let full_span = self.span(lo, lo + 2 + word.len());
+                                let prefix_span = start..prefix_end;
+                                let full_span =
+                                    start..self.input_vec_index2range(self.input_vec_index).start;
                                 self.errors.insert(0, ParseError {
                                     description: "raw identifiers are not supported".to_owned(),
                                     note: Some("identifiers in format strings can be keywords and don't need to be prefixed with `r#`".to_string()),
@@ -598,7 +575,6 @@ impl<'a> Parser<'a> {
 
                     Some(ArgumentNamed(word))
                 }
-
                 // This is an `ArgumentNext`.
                 // Record the fact and do the resolution after parsing the
                 // format spec, to make things like `{:.*}` work.
@@ -607,8 +583,16 @@ impl<'a> Parser<'a> {
         }
     }
 
-    fn current_pos(&mut self) -> usize {
-        if let Some(&(pos, _)) = self.cur.peek() { pos } else { self.input.len() }
+    fn input_vec_index2pos(&self, index: usize) -> usize {
+        if let Some(&(_, pos, _)) = self.input_vec.get(index) { pos } else { self.input.len() }
+    }
+
+    fn input_vec_index2range(&self, index: usize) -> Range<usize> {
+        if let Some((r, _, _)) = self.input_vec.get(index) {
+            r.clone()
+        } else {
+            self.end_of_snippet..self.end_of_snippet
+        }
     }
 
     /// Parses a format specifier at the current position, returning all of the
@@ -634,11 +618,11 @@ impl<'a> Parser<'a> {
         }
 
         // fill character
-        if let Some(&(idx, c)) = self.cur.peek() {
-            if let Some((_, '>' | '<' | '^')) = self.cur.clone().nth(1) {
+        if let Some(&(ref r, _, c)) = self.input_vec.get(self.input_vec_index) {
+            if let Some((_, _, '>' | '<' | '^')) = self.input_vec.get(self.input_vec_index + 1) {
+                self.input_vec_index += 1;
                 spec.fill = Some(c);
-                spec.fill_span = Some(self.span(idx, idx + 1));
-                self.cur.next();
+                spec.fill_span = Some(r.clone());
             }
         }
         // Alignment
@@ -662,14 +646,14 @@ impl<'a> Parser<'a> {
         // Width and precision
         let mut havewidth = false;
 
-        if self.consume('0') {
+        if let Some((range, _)) = self.consume_pos('0') {
             // small ambiguity with '0$' as a format string. In theory this is a
             // '0' flag and then an ill-formatted format string with just a '$'
             // and no count, but this is better if we instead interpret this as
             // no '0' flag and '0$' as the width instead.
-            if let Some(end) = self.consume_pos('$') {
+            if let Some((r, _)) = self.consume_pos('$') {
                 spec.width = CountIsParam(0);
-                spec.width_span = Some(self.span(end - 1, end + 1));
+                spec.width_span = Some(range.start..r.end);
                 havewidth = true;
             } else {
                 spec.zero_pad = true;
@@ -677,15 +661,15 @@ impl<'a> Parser<'a> {
         }
 
         if !havewidth {
-            let start = self.current_pos();
-            spec.width = self.count(start);
+            let start_idx = self.input_vec_index;
+            spec.width = self.count();
             if spec.width != CountImplied {
-                let end = self.current_pos();
-                spec.width_span = Some(self.span(start, end));
+                let end = self.input_vec_index2range(self.input_vec_index).start;
+                spec.width_span = Some(self.input_vec_index2range(start_idx).start..end);
             }
         }
 
-        if let Some(start) = self.consume_pos('.') {
+        if let Some((range, _)) = self.consume_pos('.') {
             if self.consume('*') {
                 // Resolve `CountIsNextParam`.
                 // We can do this immediately as `position` is resolved later.
@@ -693,13 +677,13 @@ impl<'a> Parser<'a> {
                 self.curarg += 1;
                 spec.precision = CountIsStar(i);
             } else {
-                spec.precision = self.count(start + 1);
+                spec.precision = self.count();
             }
-            let end = self.current_pos();
-            spec.precision_span = Some(self.span(start, end));
+            spec.precision_span =
+                Some(range.start..self.input_vec_index2range(self.input_vec_index).start);
         }
 
-        let ty_span_start = self.current_pos();
+        let start_idx = self.input_vec_index;
         // Optional radix followed by the actual format specifier
         if self.consume('x') {
             if self.consume('?') {
@@ -715,19 +699,33 @@ impl<'a> Parser<'a> {
             } else {
                 spec.ty = "X";
             }
-        } else if self.consume('?') {
+        } else if let Some((range, _)) = self.consume_pos('?') {
             spec.ty = "?";
-            if let Some(&(_, maybe)) = self.cur.peek() {
-                match maybe {
-                    '#' | 'x' | 'X' => self.suggest_format_parameter(maybe),
+            if let Some((r, _, c)) = self.input_vec.get(self.input_vec_index) {
+                match c {
+                    '#' | 'x' | 'X' => self.errors.insert(
+                        0,
+                        ParseError {
+                            description: format!("expected `}}`, found `{c}`"),
+                            note: None,
+                            label: "expected `'}'`".into(),
+                            span: r.clone(),
+                            secondary_label: None,
+                            suggestion: Suggestion::ReorderFormatParameter(
+                                range.start..r.end,
+                                format!("{c}?"),
+                            ),
+                        },
+                    ),
                     _ => (),
                 }
             }
         } else {
             spec.ty = self.word();
             if !spec.ty.is_empty() {
-                let ty_span_end = self.current_pos();
-                spec.ty_span = Some(self.span(ty_span_start, ty_span_end));
+                let start = self.input_vec_index2range(start_idx).start;
+                let end = self.input_vec_index2range(self.input_vec_index).start;
+                spec.ty_span = Some(start..end);
             }
         }
         spec
@@ -755,11 +753,12 @@ impl<'a> Parser<'a> {
             return spec;
         }
 
-        let ty_span_start = self.current_pos();
+        let start_idx = self.input_vec_index;
         spec.ty = self.word();
         if !spec.ty.is_empty() {
-            let ty_span_end = self.current_pos();
-            spec.ty_span = Some(self.span(ty_span_start, ty_span_end));
+            let start = self.input_vec_index2range(start_idx).start;
+            let end = self.input_vec_index2range(self.input_vec_index).start;
+            spec.ty_span = Some(start..end);
         }
 
         spec
@@ -768,55 +767,58 @@ impl<'a> Parser<'a> {
     /// Parses a `Count` parameter at the current position. This does not check
     /// for 'CountIsNextParam' because that is only used in precision, not
     /// width.
-    fn count(&mut self, start: usize) -> Count<'a> {
+    fn count(&mut self) -> Count<'a> {
         if let Some(i) = self.integer() {
             if self.consume('$') { CountIsParam(i.into()) } else { CountIs(i) }
         } else {
-            let tmp = self.cur.clone();
+            let start_idx = self.input_vec_index;
             let word = self.word();
             if word.is_empty() {
-                self.cur = tmp;
                 CountImplied
-            } else if let Some(end) = self.consume_pos('$') {
-                let name_span = self.span(start, end);
-                CountIsName(word, name_span)
+            } else if let Some((r, _)) = self.consume_pos('$') {
+                CountIsName(word, self.input_vec_index2range(start_idx).start..r.start)
             } else {
-                self.cur = tmp;
+                self.input_vec_index = start_idx;
                 CountImplied
             }
         }
     }
 
-    /// Parses a word starting at the current position. A word is the same as
+    /// Parses a word starting at the current position. A word is the same as a
     /// Rust identifier, except that it can't start with `_` character.
     fn word(&mut self) -> &'a str {
-        let start = match self.cur.peek() {
-            Some(&(pos, c)) if rustc_lexer::is_id_start(c) => {
-                self.cur.next();
-                pos
+        let index = self.input_vec_index;
+        match self.input_vec.get(self.input_vec_index) {
+            Some(&(ref r, i, c)) if rustc_lexer::is_id_start(c) => {
+                self.input_vec_index += 1;
+                (r.start, i)
             }
             _ => {
                 return "";
             }
         };
-        let mut end = None;
-        while let Some(&(pos, c)) = self.cur.peek() {
-            if rustc_lexer::is_id_continue(c) {
-                self.cur.next();
+        let (err_end, end): (usize, usize) = loop {
+            if let Some(&(ref r, i, c)) = self.input_vec.get(self.input_vec_index) {
+                if rustc_lexer::is_id_continue(c) {
+                    self.input_vec_index += 1;
+                } else {
+                    break (r.start, i);
+                }
             } else {
-                end = Some(pos);
-                break;
+                break (self.end_of_snippet, self.input.len());
             }
-        }
-        let end = end.unwrap_or(self.input.len());
-        let word = &self.input[start..end];
+        };
+
+        let word = &self.input[self.input_vec_index2pos(index)..end];
         if word == "_" {
-            self.err_with_note(
-                "invalid argument name `_`",
-                "invalid argument name",
-                "argument name cannot be a single underscore",
-                self.span(start, end),
-            );
+            self.errors.push(ParseError {
+                description: "invalid argument name `_`".into(),
+                note: Some("argument name cannot be a single underscore".into()),
+                label: "invalid argument name".into(),
+                span: self.input_vec_index2range(index).start..err_end,
+                secondary_label: None,
+                suggestion: Suggestion::None,
+            });
         }
         word
     }
@@ -825,9 +827,10 @@ impl<'a> Parser<'a> {
         let mut cur: u16 = 0;
         let mut found = false;
         let mut overflow = false;
-        let start = self.current_pos();
-        while let Some(&(_, c)) = self.cur.peek() {
+        let start_index = self.input_vec_index;
+        while let Some(&(_, _, c)) = self.input_vec.get(self.input_vec_index) {
             if let Some(i) = c.to_digit(10) {
+                self.input_vec_index += 1;
                 let (tmp, mul_overflow) = cur.overflowing_mul(10);
                 let (tmp, add_overflow) = tmp.overflowing_add(i as u16);
                 if mul_overflow || add_overflow {
@@ -835,40 +838,42 @@ impl<'a> Parser<'a> {
                 }
                 cur = tmp;
                 found = true;
-                self.cur.next();
             } else {
                 break;
             }
         }
 
         if overflow {
-            let end = self.current_pos();
-            let overflowed_int = &self.input[start..end];
-            self.err(
-                format!(
+            let overflowed_int = &self.input[self.input_vec_index2pos(start_index)
+                ..self.input_vec_index2pos(self.input_vec_index)];
+            self.errors.push(ParseError {
+                description: format!(
                     "integer `{}` does not fit into the type `u16` whose range is `0..={}`",
                     overflowed_int,
                     u16::MAX
                 ),
-                "integer out of range for `u16`",
-                self.span(start, end),
-            );
+                note: None,
+                label: "integer out of range for `u16`".into(),
+                span: self.input_vec_index2range(start_index).start
+                    ..self.input_vec_index2range(self.input_vec_index).end,
+                secondary_label: None,
+                suggestion: Suggestion::None,
+            });
         }
 
         found.then_some(cur)
     }
 
     fn suggest_format_debug(&mut self) {
-        if let (Some(pos), Some(_)) = (self.consume_pos('?'), self.consume_pos(':')) {
+        if let (Some((range, _)), Some(_)) = (self.consume_pos('?'), self.consume_pos(':')) {
             let word = self.word();
-            let pos = self.to_span_index(pos);
             self.errors.insert(
                 0,
                 ParseError {
                     description: "expected format parameter to occur after `:`".to_owned(),
                     note: Some(format!("`?` comes after `:`, try `{}:{}` instead", word, "?")),
                     label: "expected `?` to occur after `:`".to_owned(),
-                    span: pos.to(pos),
+                    span: range,
                     secondary_label: None,
                     suggestion: Suggestion::None,
                 },
@@ -877,15 +882,14 @@ impl<'a> Parser<'a> {
     }
 
     fn suggest_format_align(&mut self, alignment: char) {
-        if let Some(pos) = self.consume_pos(alignment) {
-            let pos = self.to_span_index(pos);
+        if let Some((range, _)) = self.consume_pos(alignment) {
             self.errors.insert(
                 0,
                 ParseError {
                     description: "expected format parameter to occur after `:`".to_owned(),
                     note: None,
                     label: format!("expected `{}` to occur after `:`", alignment),
-                    span: pos.to(pos),
+                    span: range,
                     secondary_label: None,
                     suggestion: Suggestion::None,
                 },
@@ -894,10 +898,13 @@ impl<'a> Parser<'a> {
     }
 
     fn suggest_positional_arg_instead_of_captured_arg(&mut self, arg: Argument<'a>) {
-        if let Some(end) = self.consume_pos('.') {
-            let byte_pos = self.to_span_index(end);
-            let start = InnerOffset(byte_pos.0 + 1);
-            let field = self.argument(start);
+        // If the argument is not an identifier, it is not a field access.
+        if !arg.is_identifier() {
+            return;
+        }
+
+        if let Some((_range, _pos)) = self.consume_pos('.') {
+            let field = self.argument();
             // We can only parse simple `foo.bar` field access or `foo.0` tuple index access, any
             // deeper nesting, or another type of expression, like method calls, are not supported
             if !self.consume('}') {
@@ -912,10 +919,7 @@ impl<'a> Parser<'a> {
                                 description: "field access isn't supported".to_string(),
                                 note: None,
                                 label: "not supported".to_string(),
-                                span: InnerSpan::new(
-                                    arg.position_span.start,
-                                    field.position_span.end,
-                                ),
+                                span: arg.position_span.start..field.position_span.end,
                                 secondary_label: None,
                                 suggestion: Suggestion::UsePositional,
                             },
@@ -928,10 +932,7 @@ impl<'a> Parser<'a> {
                                 description: "tuple index access isn't supported".to_string(),
                                 note: None,
                                 label: "not supported".to_string(),
-                                span: InnerSpan::new(
-                                    arg.position_span.start,
-                                    field.position_span.end,
-                                ),
+                                span: arg.position_span.start..field.position_span.end,
                                 secondary_label: None,
                                 suggestion: Suggestion::UsePositional,
                             },
@@ -942,164 +943,6 @@ impl<'a> Parser<'a> {
             }
         }
     }
-
-    fn suggest_format_parameter(&mut self, c: char) {
-        let replacement = match c {
-            '#' => "#?",
-            'x' => "x?",
-            'X' => "X?",
-            _ => return,
-        };
-        let Some(pos) = self.consume_pos(c) else {
-            return;
-        };
-
-        let span = self.span(pos - 1, pos + 1);
-        let pos = self.to_span_index(pos);
-
-        self.errors.insert(
-            0,
-            ParseError {
-                description: format!("expected `}}`, found `{c}`"),
-                note: None,
-                label: "expected `'}'`".into(),
-                span: pos.to(pos),
-                secondary_label: None,
-                suggestion: Suggestion::ReorderFormatParameter(span, format!("{replacement}")),
-            },
-        )
-    }
-}
-
-/// Finds the indices of all characters that have been processed and differ between the actual
-/// written code (code snippet) and the `InternedString` that gets processed in the `Parser`
-/// in order to properly synthesise the intra-string `Span`s for error diagnostics.
-fn find_width_map_from_snippet(
-    input: &str,
-    snippet: Option<String>,
-    str_style: Option<usize>,
-) -> InputStringKind {
-    let snippet = match snippet {
-        Some(ref s) if s.starts_with('"') || s.starts_with("r\"") || s.starts_with("r#") => s,
-        _ => return InputStringKind::NotALiteral,
-    };
-
-    if str_style.is_some() {
-        return InputStringKind::Literal { width_mappings: Vec::new() };
-    }
-
-    // Strip quotes.
-    let snippet = &snippet[1..snippet.len() - 1];
-
-    // Macros like `println` add a newline at the end. That technically doesn't make them "literals" anymore, but it's fine
-    // since we will never need to point our spans there, so we lie about it here by ignoring it.
-    // Since there might actually be newlines in the source code, we need to normalize away all trailing newlines.
-    // If we only trimmed it off the input, `format!("\n")` would cause a mismatch as here we they actually match up.
-    // Alternatively, we could just count the trailing newlines and only trim one from the input if they don't match up.
-    let input_no_nl = input.trim_end_matches('\n');
-    let Some(unescaped) = unescape_string(snippet) else {
-        return InputStringKind::NotALiteral;
-    };
-
-    let unescaped_no_nl = unescaped.trim_end_matches('\n');
-
-    if unescaped_no_nl != input_no_nl {
-        // The source string that we're pointing at isn't our input, so spans pointing at it will be incorrect.
-        // This can for example happen with proc macros that respan generated literals.
-        return InputStringKind::NotALiteral;
-    }
-
-    let mut s = snippet.char_indices();
-    let mut width_mappings = vec![];
-    while let Some((pos, c)) = s.next() {
-        match (c, s.clone().next()) {
-            // skip whitespace and empty lines ending in '\\'
-            ('\\', Some((_, '\n'))) => {
-                let _ = s.next();
-                let mut width = 2;
-
-                while let Some((_, c)) = s.clone().next() {
-                    if matches!(c, ' ' | '\n' | '\t') {
-                        width += 1;
-                        let _ = s.next();
-                    } else {
-                        break;
-                    }
-                }
-
-                width_mappings.push(InnerWidthMapping::new(pos, width, 0));
-            }
-            ('\\', Some((_, 'n' | 't' | 'r' | '0' | '\\' | '\'' | '\"'))) => {
-                width_mappings.push(InnerWidthMapping::new(pos, 2, 1));
-                let _ = s.next();
-            }
-            ('\\', Some((_, 'x'))) => {
-                // consume `\xAB` literal
-                s.nth(2);
-                width_mappings.push(InnerWidthMapping::new(pos, 4, 1));
-            }
-            ('\\', Some((_, 'u'))) => {
-                let mut width = 2;
-                let _ = s.next();
-
-                if let Some((_, next_c)) = s.next() {
-                    if next_c == '{' {
-                        // consume up to 6 hexanumeric chars
-                        let digits_len =
-                            s.clone().take(6).take_while(|(_, c)| c.is_ascii_hexdigit()).count();
-
-                        let len_utf8 = s
-                            .as_str()
-                            .get(..digits_len)
-                            .and_then(|digits| u32::from_str_radix(digits, 16).ok())
-                            .and_then(char::from_u32)
-                            .map_or(1, char::len_utf8);
-
-                        // Skip the digits, for chars that encode to more than 1 utf-8 byte
-                        // exclude as many digits as it is greater than 1 byte
-                        //
-                        // So for a 3 byte character, exclude 2 digits
-                        let required_skips = digits_len.saturating_sub(len_utf8.saturating_sub(1));
-
-                        // skip '{' and '}' also
-                        width += required_skips + 2;
-
-                        s.nth(digits_len);
-                    } else if next_c.is_ascii_hexdigit() {
-                        width += 1;
-
-                        // We suggest adding `{` and `}` when appropriate, accept it here as if
-                        // it were correct
-                        let mut i = 0; // consume up to 6 hexanumeric chars
-                        while let (Some((_, c)), _) = (s.next(), i < 6) {
-                            if c.is_ascii_hexdigit() {
-                                width += 1;
-                            } else {
-                                break;
-                            }
-                            i += 1;
-                        }
-                    }
-                }
-
-                width_mappings.push(InnerWidthMapping::new(pos, width, 1));
-            }
-            _ => {}
-        }
-    }
-
-    InputStringKind::Literal { width_mappings }
-}
-
-fn unescape_string(string: &str) -> Option<String> {
-    let mut buf = String::new();
-    let mut ok = true;
-    unescape_unicode(string, Mode::Str, &mut |_, unescaped_char| match unescaped_char {
-        Ok(c) => buf.push(c),
-        Err(_) => ok = false,
-    });
-
-    ok.then_some(buf)
 }
 
 // Assert a reasonable size for `Piece`
diff --git a/compiler/rustc_parse_format/src/tests.rs b/compiler/rustc_parse_format/src/tests.rs
index cc8a0069c4e..e6a7f24034a 100644
--- a/compiler/rustc_parse_format/src/tests.rs
+++ b/compiler/rustc_parse_format/src/tests.rs
@@ -41,7 +41,6 @@ fn simple() {
     same("}}", &[Lit("}")]);
     same("\\}}", &[Lit("\\"), Lit("}")]);
 }
-
 #[test]
 fn invalid01() {
     musterr("{")
@@ -79,23 +78,48 @@ fn invalid_precision() {
 }
 
 #[test]
-fn format_nothing() {
+fn format_empty() {
     same(
         "{}",
         &[NextArgument(Box::new(Argument {
             position: ArgumentImplicitlyIs(0),
-            position_span: InnerSpan { start: 2, end: 2 },
+            position_span: 2..2,
             format: fmtdflt(),
         }))],
     );
 }
 #[test]
+fn format_tab_empty() {
+    let fmt_pre = r###""\t{}""###;
+    let fmt = "\t{}";
+    let parser = Parser::new(fmt, None, Some(fmt_pre.into()), false, ParseMode::Format);
+    assert_eq!(
+        parser.collect::<Vec<Piece<'static>>>(),
+        &[
+            Lit("\t"),
+            NextArgument(Box::new(Argument {
+                position: ArgumentImplicitlyIs(0),
+                position_span: 4..4,
+                format: fmtdflt(),
+            }))
+        ],
+    );
+}
+#[test]
+fn format_open_brace_tab() {
+    let fmt_pre = r###""{\t""###;
+    let fmt = "{\t";
+    let mut parser = Parser::new(fmt, None, Some(fmt_pre.into()), false, ParseMode::Format);
+    let _ = parser.by_ref().collect::<Vec<Piece<'static>>>();
+    assert_eq!(parser.errors[0].span, 4..4);
+}
+#[test]
 fn format_position() {
     same(
         "{3}",
         &[NextArgument(Box::new(Argument {
             position: ArgumentIs(3),
-            position_span: InnerSpan { start: 2, end: 3 },
+            position_span: 2..3,
             format: fmtdflt(),
         }))],
     );
@@ -106,7 +130,7 @@ fn format_position_nothing_else() {
         "{3:}",
         &[NextArgument(Box::new(Argument {
             position: ArgumentIs(3),
-            position_span: InnerSpan { start: 2, end: 3 },
+            position_span: 2..3,
             format: fmtdflt(),
         }))],
     );
@@ -117,18 +141,54 @@ fn format_named() {
         "{name}",
         &[NextArgument(Box::new(Argument {
             position: ArgumentNamed("name"),
-            position_span: InnerSpan { start: 2, end: 6 },
+            position_span: 2..6,
             format: fmtdflt(),
         }))],
     )
 }
 #[test]
+fn format_named_space_nothing() {
+    same(
+        "{name} {}",
+        &[
+            NextArgument(Box::new(Argument {
+                position: ArgumentNamed("name"),
+                position_span: 2..6,
+                format: fmtdflt(),
+            })),
+            Lit(" "),
+            NextArgument(Box::new(Argument {
+                position: ArgumentImplicitlyIs(0),
+                position_span: 9..9,
+                format: fmtdflt(),
+            })),
+        ],
+    )
+}
+#[test]
+fn format_raw() {
+    let snippet = r###"r#"assertion `left {op} right` failed"#"###.into();
+    let source = r#"assertion `left {op} right` failed"#;
+
+    let parser = Parser::new(source, Some(1), Some(snippet), true, ParseMode::Format);
+    let expected = &[
+        Lit("assertion `left "),
+        NextArgument(Box::new(Argument {
+            position: ArgumentNamed("op"),
+            position_span: 20..22,
+            format: fmtdflt(),
+        })),
+        Lit(" right` failed"),
+    ];
+    assert_eq!(parser.collect::<Vec<Piece<'static>>>(), expected);
+}
+#[test]
 fn format_type() {
     same(
         "{3:x}",
         &[NextArgument(Box::new(Argument {
             position: ArgumentIs(3),
-            position_span: InnerSpan { start: 2, end: 3 },
+            position_span: 2..3,
             format: FormatSpec {
                 fill: None,
                 fill_span: None,
@@ -153,7 +213,7 @@ fn format_align_fill() {
         "{3:>}",
         &[NextArgument(Box::new(Argument {
             position: ArgumentIs(3),
-            position_span: InnerSpan { start: 2, end: 3 },
+            position_span: 2..3,
             format: FormatSpec {
                 fill: None,
                 fill_span: None,
@@ -175,10 +235,10 @@ fn format_align_fill() {
         "{3:0<}",
         &[NextArgument(Box::new(Argument {
             position: ArgumentIs(3),
-            position_span: InnerSpan { start: 2, end: 3 },
+            position_span: 2..3,
             format: FormatSpec {
                 fill: Some('0'),
-                fill_span: Some(InnerSpan::new(4, 5)),
+                fill_span: Some(4..5),
                 align: AlignLeft,
                 sign: None,
                 alternate: false,
@@ -197,10 +257,10 @@ fn format_align_fill() {
         "{3:*<abcd}",
         &[NextArgument(Box::new(Argument {
             position: ArgumentIs(3),
-            position_span: InnerSpan { start: 2, end: 3 },
+            position_span: 2..3,
             format: FormatSpec {
                 fill: Some('*'),
-                fill_span: Some(InnerSpan::new(4, 5)),
+                fill_span: Some(4..5),
                 align: AlignLeft,
                 sign: None,
                 alternate: false,
@@ -211,7 +271,7 @@ fn format_align_fill() {
                 precision_span: None,
                 width_span: None,
                 ty: "abcd",
-                ty_span: Some(InnerSpan::new(6, 10)),
+                ty_span: Some(6..10),
             },
         }))],
     );
@@ -222,7 +282,7 @@ fn format_counts() {
         "{:10x}",
         &[NextArgument(Box::new(Argument {
             position: ArgumentImplicitlyIs(0),
-            position_span: InnerSpan { start: 2, end: 2 },
+            position_span: 2..2,
             format: FormatSpec {
                 fill: None,
                 fill_span: None,
@@ -234,7 +294,7 @@ fn format_counts() {
                 precision: CountImplied,
                 precision_span: None,
                 width: CountIs(10),
-                width_span: Some(InnerSpan { start: 3, end: 5 }),
+                width_span: Some(3..5),
                 ty: "x",
                 ty_span: None,
             },
@@ -244,7 +304,7 @@ fn format_counts() {
         "{:10$.10x}",
         &[NextArgument(Box::new(Argument {
             position: ArgumentImplicitlyIs(0),
-            position_span: InnerSpan { start: 2, end: 2 },
+            position_span: 2..2,
             format: FormatSpec {
                 fill: None,
                 fill_span: None,
@@ -254,9 +314,9 @@ fn format_counts() {
                 zero_pad: false,
                 debug_hex: None,
                 precision: CountIs(10),
-                precision_span: Some(InnerSpan { start: 6, end: 9 }),
+                precision_span: Some(6..9),
                 width: CountIsParam(10),
-                width_span: Some(InnerSpan { start: 3, end: 6 }),
+                width_span: Some(3..6),
                 ty: "x",
                 ty_span: None,
             },
@@ -266,7 +326,7 @@ fn format_counts() {
         "{1:0$.10x}",
         &[NextArgument(Box::new(Argument {
             position: ArgumentIs(1),
-            position_span: InnerSpan { start: 2, end: 3 },
+            position_span: 2..3,
             format: FormatSpec {
                 fill: None,
                 fill_span: None,
@@ -276,9 +336,9 @@ fn format_counts() {
                 zero_pad: false,
                 debug_hex: None,
                 precision: CountIs(10),
-                precision_span: Some(InnerSpan { start: 6, end: 9 }),
+                precision_span: Some(6..9),
                 width: CountIsParam(0),
-                width_span: Some(InnerSpan { start: 4, end: 6 }),
+                width_span: Some(4..6),
                 ty: "x",
                 ty_span: None,
             },
@@ -288,7 +348,7 @@ fn format_counts() {
         "{:.*x}",
         &[NextArgument(Box::new(Argument {
             position: ArgumentImplicitlyIs(1),
-            position_span: InnerSpan { start: 2, end: 2 },
+            position_span: 2..2,
             format: FormatSpec {
                 fill: None,
                 fill_span: None,
@@ -298,7 +358,7 @@ fn format_counts() {
                 zero_pad: false,
                 debug_hex: None,
                 precision: CountIsStar(0),
-                precision_span: Some(InnerSpan { start: 3, end: 5 }),
+                precision_span: Some(3..5),
                 width: CountImplied,
                 width_span: None,
                 ty: "x",
@@ -310,7 +370,7 @@ fn format_counts() {
         "{:.10$x}",
         &[NextArgument(Box::new(Argument {
             position: ArgumentImplicitlyIs(0),
-            position_span: InnerSpan { start: 2, end: 2 },
+            position_span: 2..2,
             format: FormatSpec {
                 fill: None,
                 fill_span: None,
@@ -321,7 +381,7 @@ fn format_counts() {
                 debug_hex: None,
                 precision: CountIsParam(10),
                 width: CountImplied,
-                precision_span: Some(InnerSpan::new(3, 7)),
+                precision_span: Some(3..7),
                 width_span: None,
                 ty: "x",
                 ty_span: None,
@@ -332,7 +392,7 @@ fn format_counts() {
         "{:a$.b$?}",
         &[NextArgument(Box::new(Argument {
             position: ArgumentImplicitlyIs(0),
-            position_span: InnerSpan { start: 2, end: 2 },
+            position_span: 2..2,
             format: FormatSpec {
                 fill: None,
                 fill_span: None,
@@ -341,10 +401,10 @@ fn format_counts() {
                 alternate: false,
                 zero_pad: false,
                 debug_hex: None,
-                precision: CountIsName("b", InnerSpan { start: 6, end: 7 }),
-                precision_span: Some(InnerSpan { start: 5, end: 8 }),
-                width: CountIsName("a", InnerSpan { start: 3, end: 4 }),
-                width_span: Some(InnerSpan { start: 3, end: 5 }),
+                precision: CountIsName("b", 6..7),
+                precision_span: Some(5..8),
+                width: CountIsName("a", 3..4),
+                width_span: Some(3..5),
                 ty: "?",
                 ty_span: None,
             },
@@ -354,7 +414,7 @@ fn format_counts() {
         "{:.4}",
         &[NextArgument(Box::new(Argument {
             position: ArgumentImplicitlyIs(0),
-            position_span: InnerSpan { start: 2, end: 2 },
+            position_span: 2..2,
             format: FormatSpec {
                 fill: None,
                 fill_span: None,
@@ -364,7 +424,7 @@ fn format_counts() {
                 zero_pad: false,
                 debug_hex: None,
                 precision: CountIs(4),
-                precision_span: Some(InnerSpan { start: 3, end: 5 }),
+                precision_span: Some(3..5),
                 width: CountImplied,
                 width_span: None,
                 ty: "",
@@ -379,7 +439,7 @@ fn format_flags() {
         "{:-}",
         &[NextArgument(Box::new(Argument {
             position: ArgumentImplicitlyIs(0),
-            position_span: InnerSpan { start: 2, end: 2 },
+            position_span: 2..2,
             format: FormatSpec {
                 fill: None,
                 fill_span: None,
@@ -401,7 +461,7 @@ fn format_flags() {
         "{:+#}",
         &[NextArgument(Box::new(Argument {
             position: ArgumentImplicitlyIs(0),
-            position_span: InnerSpan { start: 2, end: 2 },
+            position_span: 2..2,
             format: FormatSpec {
                 fill: None,
                 fill_span: None,
@@ -428,7 +488,7 @@ fn format_mixture() {
             Lit("abcd "),
             NextArgument(Box::new(Argument {
                 position: ArgumentIs(3),
-                position_span: InnerSpan { start: 7, end: 8 },
+                position_span: 7..8,
                 format: FormatSpec {
                     fill: None,
                     fill_span: None,
@@ -455,7 +515,7 @@ fn format_whitespace() {
         "{ }",
         &[NextArgument(Box::new(Argument {
             position: ArgumentImplicitlyIs(0),
-            position_span: InnerSpan { start: 2, end: 3 },
+            position_span: 2..3,
             format: fmtdflt(),
         }))],
     );
@@ -463,8 +523,33 @@ fn format_whitespace() {
         "{  }",
         &[NextArgument(Box::new(Argument {
             position: ArgumentImplicitlyIs(0),
-            position_span: InnerSpan { start: 2, end: 4 },
+            position_span: 2..4,
             format: fmtdflt(),
         }))],
     );
 }
+#[test]
+fn asm_linespans() {
+    let asm_pre = r###"r"
+        .intel_syntax noprefix
+        nop""###;
+    let asm = r"
+        .intel_syntax noprefix
+        nop";
+    let mut parser = Parser::new(asm, Some(0), Some(asm_pre.into()), false, ParseMode::InlineAsm);
+    assert!(parser.is_source_literal);
+    assert_eq!(
+        parser.by_ref().collect::<Vec<Piece<'static>>>(),
+        &[Lit("\n        .intel_syntax noprefix\n        nop")]
+    );
+    assert_eq!(parser.line_spans, &[2..2, 11..33, 42..45]);
+}
+#[test]
+fn asm_concat() {
+    let asm_pre = r###"concat!("invalid", "_", "instruction")"###;
+    let asm = "invalid_instruction";
+    let mut parser = Parser::new(asm, None, Some(asm_pre.into()), false, ParseMode::InlineAsm);
+    assert!(!parser.is_source_literal);
+    assert_eq!(parser.by_ref().collect::<Vec<Piece<'static>>>(), &[Lit(asm)]);
+    assert_eq!(parser.line_spans, &[]);
+}
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 413726ddd82..6d815e510ea 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -356,6 +356,8 @@ passes_ignored_derived_impls =
 passes_implied_feature_not_exist =
     feature `{$implied_by}` implying `{$feature}` does not exist
 
+passes_incorrect_crate_type = lang items are not allowed in stable dylibs
+
 passes_incorrect_do_not_recommend_args =
     `#[diagnostic::do_not_recommend]` does not expect any arguments
 
@@ -742,6 +744,23 @@ passes_trait_impl_const_stable =
 passes_transparent_incompatible =
     transparent {$target} cannot have other repr hints
 
+passes_unexportable_adt_with_private_fields = ADT types with private fields are not exportable
+    .note = `{$field_name}` is private
+
+passes_unexportable_fn_abi = only functions with "C" ABI are exportable
+
+passes_unexportable_generic_fn = generic functions are not exportable
+
+passes_unexportable_item = {$descr}'s are not exportable
+
+passes_unexportable_priv_item = private items are not exportable
+    .note = is only usable at visibility `{$vis_descr}`
+
+passes_unexportable_type_in_interface = {$desc} with `#[export_stable]` attribute uses type `{$ty}`, which is not exportable
+    .label = not exportable
+
+passes_unexportable_type_repr = types with unstable layout are not exportable
+
 passes_unknown_external_lang_item =
     unknown external lang item: `{$lang_item}`
 
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index f04b167889f..c68f8df49fc 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -277,6 +277,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                             | sym::cfg_attr
                             | sym::cfg_trace
                             | sym::cfg_attr_trace
+                            | sym::export_stable // handled in `check_export`
                             // need to be fixed
                             | sym::cfi_encoding // FIXME(cfi_encoding)
                             | sym::pointee // FIXME(derive_coerce_pointee)
@@ -683,7 +684,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         }
                     }
 
-                    if !other_attr.has_any_name(ALLOW_LIST) {
+                    if !other_attr.has_any_name(ALLOW_LIST)
+                        && !matches!(other_attr.path().as_slice(), [sym::rustfmt, ..])
+                    {
                         let path = other_attr.path();
                         let path: Vec<_> = path.iter().map(|s| s.as_str()).collect();
                         let other_attr_name = path.join("::");
diff --git a/compiler/rustc_passes/src/check_export.rs b/compiler/rustc_passes/src/check_export.rs
new file mode 100644
index 00000000000..2bb698689be
--- /dev/null
+++ b/compiler/rustc_passes/src/check_export.rs
@@ -0,0 +1,398 @@
+use std::iter;
+use std::ops::ControlFlow;
+
+use rustc_abi::ExternAbi;
+use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
+use rustc_hir as hir;
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::intravisit::{self, Visitor};
+use rustc_middle::hir::nested_filter;
+use rustc_middle::middle::privacy::{EffectiveVisibility, Level};
+use rustc_middle::query::{LocalCrate, Providers};
+use rustc_middle::ty::{
+    self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Visibility,
+};
+use rustc_session::config::CrateType;
+use rustc_span::{Span, sym};
+
+use crate::errors::UnexportableItem;
+
+struct ExportableItemCollector<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    exportable_items: FxIndexSet<DefId>,
+    in_exportable_mod: bool,
+    seen_exportable_in_mod: bool,
+}
+
+impl<'tcx> ExportableItemCollector<'tcx> {
+    fn new(tcx: TyCtxt<'tcx>) -> ExportableItemCollector<'tcx> {
+        ExportableItemCollector {
+            tcx,
+            exportable_items: Default::default(),
+            in_exportable_mod: false,
+            seen_exportable_in_mod: false,
+        }
+    }
+
+    fn report_wrong_site(&self, def_id: LocalDefId) {
+        let def_descr = self.tcx.def_descr(def_id.to_def_id());
+        self.tcx.dcx().emit_err(UnexportableItem::Item {
+            descr: &format!("{}", def_descr),
+            span: self.tcx.def_span(def_id),
+        });
+    }
+
+    fn item_is_exportable(&self, def_id: LocalDefId) -> bool {
+        let has_attr = self.tcx.has_attr(def_id, sym::export_stable);
+        if !self.in_exportable_mod && !has_attr {
+            return false;
+        }
+
+        let visibilities = self.tcx.effective_visibilities(());
+        let is_pub = visibilities.is_directly_public(def_id);
+
+        if has_attr && !is_pub {
+            let vis = visibilities.effective_vis(def_id).cloned().unwrap_or(
+                EffectiveVisibility::from_vis(Visibility::Restricted(
+                    self.tcx.parent_module_from_def_id(def_id).to_local_def_id(),
+                )),
+            );
+            let vis = vis.at_level(Level::Direct);
+            let span = self.tcx.def_span(def_id);
+
+            self.tcx.dcx().emit_err(UnexportableItem::PrivItem {
+                vis_note: span,
+                vis_descr: &vis.to_string(def_id, self.tcx),
+                span,
+            });
+            return false;
+        }
+
+        is_pub && (has_attr || self.in_exportable_mod)
+    }
+
+    fn add_exportable(&mut self, def_id: LocalDefId) {
+        self.seen_exportable_in_mod = true;
+        self.exportable_items.insert(def_id.to_def_id());
+    }
+
+    fn walk_item_with_mod(&mut self, item: &'tcx hir::Item<'tcx>) {
+        let def_id = item.hir_id().owner.def_id;
+        let old_exportable_mod = self.in_exportable_mod;
+        if self.tcx.get_attr(def_id, sym::export_stable).is_some() {
+            self.in_exportable_mod = true;
+        }
+        let old_seen_exportable_in_mod = std::mem::replace(&mut self.seen_exportable_in_mod, false);
+
+        intravisit::walk_item(self, item);
+
+        if self.seen_exportable_in_mod || self.in_exportable_mod {
+            self.exportable_items.insert(def_id.to_def_id());
+        }
+
+        self.seen_exportable_in_mod = old_seen_exportable_in_mod;
+        self.in_exportable_mod = old_exportable_mod;
+    }
+}
+
+impl<'tcx> Visitor<'tcx> for ExportableItemCollector<'tcx> {
+    type NestedFilter = nested_filter::All;
+
+    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
+        self.tcx
+    }
+
+    fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
+        let def_id = item.hir_id().owner.def_id;
+        // Applying #[extern] attribute to modules is simply equivalent to
+        // applying the attribute to every public item within it.
+        match item.kind {
+            hir::ItemKind::Mod(..) => {
+                self.walk_item_with_mod(item);
+                return;
+            }
+            hir::ItemKind::Impl(impl_) if impl_.of_trait.is_none() => {
+                self.walk_item_with_mod(item);
+                return;
+            }
+            _ => {}
+        }
+
+        if !self.item_is_exportable(def_id) {
+            return;
+        }
+
+        match item.kind {
+            hir::ItemKind::Fn { .. }
+            | hir::ItemKind::Struct(..)
+            | hir::ItemKind::Enum(..)
+            | hir::ItemKind::Union(..)
+            | hir::ItemKind::TyAlias(..) => {
+                self.add_exportable(def_id);
+            }
+            hir::ItemKind::Use(path, _) => {
+                for res in &path.res {
+                    // Only local items are exportable.
+                    if let Some(res_id) = res.opt_def_id()
+                        && let Some(res_id) = res_id.as_local()
+                    {
+                        self.add_exportable(res_id);
+                    }
+                }
+            }
+            // handled above
+            hir::ItemKind::Mod(..) => unreachable!(),
+            hir::ItemKind::Impl(impl_) if impl_.of_trait.is_none() => {
+                unreachable!();
+            }
+            _ => self.report_wrong_site(def_id),
+        }
+    }
+
+    fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem<'tcx>) {
+        let def_id = item.hir_id().owner.def_id;
+        if !self.item_is_exportable(def_id) {
+            return;
+        }
+        match item.kind {
+            hir::ImplItemKind::Fn(..) | hir::ImplItemKind::Type(..) => {
+                self.add_exportable(def_id);
+            }
+            _ => self.report_wrong_site(def_id),
+        }
+    }
+
+    fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
+        let def_id = item.hir_id().owner.def_id;
+        if !self.item_is_exportable(def_id) {
+            self.report_wrong_site(def_id);
+        }
+    }
+
+    fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem<'tcx>) {
+        let def_id = item.hir_id().owner.def_id;
+        if !self.item_is_exportable(def_id) {
+            self.report_wrong_site(def_id);
+        }
+    }
+}
+
+struct ExportableItemsChecker<'tcx, 'a> {
+    tcx: TyCtxt<'tcx>,
+    exportable_items: &'a FxIndexSet<DefId>,
+    item_id: DefId,
+}
+
+impl<'tcx, 'a> ExportableItemsChecker<'tcx, 'a> {
+    fn check(&mut self) {
+        match self.tcx.def_kind(self.item_id) {
+            DefKind::Fn | DefKind::AssocFn => self.check_fn(),
+            DefKind::Enum | DefKind::Struct | DefKind::Union => self.check_ty(),
+            _ => {}
+        }
+    }
+
+    fn check_fn(&mut self) {
+        let def_id = self.item_id.expect_local();
+        let span = self.tcx.def_span(def_id);
+
+        if self.tcx.generics_of(def_id).requires_monomorphization(self.tcx) {
+            self.tcx.dcx().emit_err(UnexportableItem::GenericFn(span));
+            return;
+        }
+
+        let sig = self.tcx.fn_sig(def_id).instantiate_identity().skip_binder();
+        if !matches!(sig.abi, ExternAbi::C { .. }) {
+            self.tcx.dcx().emit_err(UnexportableItem::FnAbi(span));
+            return;
+        }
+
+        let sig = self
+            .tcx
+            .try_normalize_erasing_regions(ty::TypingEnv::non_body_analysis(self.tcx, def_id), sig)
+            .unwrap_or(sig);
+
+        let hir_id = self.tcx.local_def_id_to_hir_id(def_id);
+        let decl = self.tcx.hir_fn_decl_by_hir_id(hir_id).unwrap();
+
+        for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) {
+            self.check_nested_types_are_exportable(*input_ty, input_hir.span);
+        }
+
+        if let hir::FnRetTy::Return(ret_hir) = decl.output {
+            self.check_nested_types_are_exportable(sig.output(), ret_hir.span);
+        }
+    }
+
+    fn check_ty(&mut self) {
+        let ty = self.tcx.type_of(self.item_id).skip_binder();
+        if let ty::Adt(adt_def, _) = ty.kind() {
+            if !adt_def.repr().inhibit_struct_field_reordering() {
+                self.tcx
+                    .dcx()
+                    .emit_err(UnexportableItem::TypeRepr(self.tcx.def_span(self.item_id)));
+            }
+
+            // FIXME: support `#[export(unsafe_stable_abi = "hash")]` syntax
+            for variant in adt_def.variants() {
+                for field in &variant.fields {
+                    if !field.vis.is_public() {
+                        self.tcx.dcx().emit_err(UnexportableItem::AdtWithPrivFields {
+                            span: self.tcx.def_span(self.item_id),
+                            vis_note: self.tcx.def_span(field.did),
+                            field_name: field.name.as_str(),
+                        });
+                    }
+                }
+            }
+        }
+    }
+
+    fn check_nested_types_are_exportable(&mut self, ty: Ty<'tcx>, ty_span: Span) {
+        let res = ty.visit_with(self);
+        if let Some(err_cause) = res.break_value() {
+            self.tcx.dcx().emit_err(UnexportableItem::TypeInInterface {
+                span: self.tcx.def_span(self.item_id),
+                desc: self.tcx.def_descr(self.item_id),
+                ty: &format!("{}", err_cause),
+                ty_span,
+            });
+        }
+    }
+}
+
+impl<'tcx, 'a> TypeVisitor<TyCtxt<'tcx>> for ExportableItemsChecker<'tcx, 'a> {
+    type Result = ControlFlow<Ty<'tcx>>;
+
+    fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
+        match ty.kind() {
+            ty::Adt(adt_def, _) => {
+                let did = adt_def.did();
+                let exportable = if did.is_local() {
+                    self.exportable_items.contains(&did)
+                } else {
+                    self.tcx.is_exportable(did)
+                };
+                if !exportable {
+                    return ControlFlow::Break(ty);
+                }
+                for variant in adt_def.variants() {
+                    for field in &variant.fields {
+                        let field_ty = self.tcx.type_of(field.did).instantiate_identity();
+                        field_ty.visit_with(self)?;
+                    }
+                }
+
+                return ty.super_visit_with(self);
+            }
+
+            ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Bool | ty::Char | ty::Error(_) => {}
+
+            ty::Array(_, _)
+            | ty::Ref(_, _, _)
+            | ty::Param(_)
+            | ty::Closure(_, _)
+            | ty::Dynamic(_, _, _)
+            | ty::Coroutine(_, _)
+            | ty::Foreign(_)
+            | ty::Str
+            | ty::Tuple(_)
+            | ty::Pat(..)
+            | ty::Slice(_)
+            | ty::RawPtr(_, _)
+            | ty::FnDef(_, _)
+            | ty::FnPtr(_, _)
+            | ty::CoroutineClosure(_, _)
+            | ty::CoroutineWitness(_, _)
+            | ty::Never
+            | ty::UnsafeBinder(_)
+            | ty::Alias(ty::AliasTyKind::Opaque, _) => {
+                return ControlFlow::Break(ty);
+            }
+
+            ty::Alias(..) | ty::Infer(_) | ty::Placeholder(_) | ty::Bound(..) => unreachable!(),
+        }
+        ControlFlow::Continue(())
+    }
+}
+
+/// Exportable items:
+///
+/// 1. Structs/enums/unions with a stable representation (e.g. repr(i32) or repr(C)).
+/// 2. Primitive types.
+/// 3. Non-generic functions with a stable ABI (e.g. extern "C") for which every user
+///    defined type used in the signature is also marked as `#[export]`.
+fn exportable_items_provider_local<'tcx>(tcx: TyCtxt<'tcx>, _: LocalCrate) -> &'tcx [DefId] {
+    if !tcx.crate_types().contains(&CrateType::Sdylib) && !tcx.is_sdylib_interface_build() {
+        return &[];
+    }
+
+    let mut visitor = ExportableItemCollector::new(tcx);
+    tcx.hir_walk_toplevel_module(&mut visitor);
+    let exportable_items = visitor.exportable_items;
+    for item_id in exportable_items.iter() {
+        let mut validator =
+            ExportableItemsChecker { tcx, exportable_items: &exportable_items, item_id: *item_id };
+        validator.check();
+    }
+
+    tcx.arena.alloc_from_iter(exportable_items.into_iter())
+}
+
+struct ImplsOrderVisitor<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    order: FxIndexMap<DefId, usize>,
+}
+
+impl<'tcx> ImplsOrderVisitor<'tcx> {
+    fn new(tcx: TyCtxt<'tcx>) -> ImplsOrderVisitor<'tcx> {
+        ImplsOrderVisitor { tcx, order: Default::default() }
+    }
+}
+
+impl<'tcx> Visitor<'tcx> for ImplsOrderVisitor<'tcx> {
+    type NestedFilter = nested_filter::All;
+
+    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
+        self.tcx
+    }
+
+    fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
+        if let hir::ItemKind::Impl(impl_) = item.kind
+            && impl_.of_trait.is_none()
+            && self.tcx.is_exportable(item.owner_id.def_id.to_def_id())
+        {
+            self.order.insert(item.owner_id.def_id.to_def_id(), self.order.len());
+        }
+        intravisit::walk_item(self, item);
+    }
+}
+
+/// During symbol mangling rustc uses a special index to distinguish between two impls of
+/// the same type in the same module(See `DisambiguatedDefPathData`). For exportable items
+/// we cannot use the current approach because it is dependent on the compiler's
+/// implementation.
+///
+/// In order to make disambiguation independent of the compiler version we can assign an
+/// id to each impl according to the relative order of elements in the source code.
+fn stable_order_of_exportable_impls<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    _: LocalCrate,
+) -> &'tcx FxIndexMap<DefId, usize> {
+    if !tcx.crate_types().contains(&CrateType::Sdylib) && !tcx.is_sdylib_interface_build() {
+        return tcx.arena.alloc(FxIndexMap::<DefId, usize>::default());
+    }
+
+    let mut vis = ImplsOrderVisitor::new(tcx);
+    tcx.hir_walk_toplevel_module(&mut vis);
+    tcx.arena.alloc(vis.order)
+}
+
+pub(crate) fn provide(providers: &mut Providers) {
+    *providers = Providers {
+        exportable_items: exportable_items_provider_local,
+        stable_order_of_exportable_impls,
+        ..*providers
+    };
+}
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index b1b4b9ee927..00682a9c7a7 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1422,6 +1422,13 @@ pub(crate) struct IncorrectTarget<'a> {
     pub at_least: bool,
 }
 
+#[derive(Diagnostic)]
+#[diag(passes_incorrect_crate_type)]
+pub(crate) struct IncorrectCrateType {
+    #[primary_span]
+    pub span: Span,
+}
+
 #[derive(LintDiagnostic)]
 #[diag(passes_useless_assignment)]
 pub(crate) struct UselessAssignment<'a> {
@@ -1919,3 +1926,50 @@ pub(crate) struct UnsupportedAttributesInWhere {
     #[primary_span]
     pub span: MultiSpan,
 }
+
+#[derive(Diagnostic)]
+pub(crate) enum UnexportableItem<'a> {
+    #[diag(passes_unexportable_item)]
+    Item {
+        #[primary_span]
+        span: Span,
+        descr: &'a str,
+    },
+
+    #[diag(passes_unexportable_generic_fn)]
+    GenericFn(#[primary_span] Span),
+
+    #[diag(passes_unexportable_fn_abi)]
+    FnAbi(#[primary_span] Span),
+
+    #[diag(passes_unexportable_type_repr)]
+    TypeRepr(#[primary_span] Span),
+
+    #[diag(passes_unexportable_type_in_interface)]
+    TypeInInterface {
+        #[primary_span]
+        span: Span,
+        desc: &'a str,
+        ty: &'a str,
+        #[label]
+        ty_span: Span,
+    },
+
+    #[diag(passes_unexportable_priv_item)]
+    PrivItem {
+        #[primary_span]
+        span: Span,
+        #[note]
+        vis_note: Span,
+        vis_descr: &'a str,
+    },
+
+    #[diag(passes_unexportable_adt_with_private_fields)]
+    AdtWithPrivFields {
+        #[primary_span]
+        span: Span,
+        #[note]
+        vis_note: Span,
+        field_name: &'a str,
+    },
+}
diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs
index 664bd4ad0a2..275714c2d0e 100644
--- a/compiler/rustc_passes/src/lang_items.rs
+++ b/compiler/rustc_passes/src/lang_items.rs
@@ -19,7 +19,8 @@ use rustc_session::cstore::ExternCrate;
 use rustc_span::Span;
 
 use crate::errors::{
-    DuplicateLangItem, IncorrectTarget, LangItemOnIncorrectTarget, UnknownLangItem,
+    DuplicateLangItem, IncorrectCrateType, IncorrectTarget, LangItemOnIncorrectTarget,
+    UnknownLangItem,
 };
 use crate::weak_lang_items;
 
@@ -236,6 +237,10 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> {
             }
         }
 
+        if self.tcx.crate_types().contains(&rustc_session::config::CrateType::Sdylib) {
+            self.tcx.dcx().emit_err(IncorrectCrateType { span: attr_span });
+        }
+
         self.collect_item(lang_item, item_def_id.to_def_id(), Some(item_span));
     }
 }
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index 424bce9d4d4..001725e2882 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -19,6 +19,7 @@ use rustc_middle::query::Providers;
 
 pub mod abi_test;
 mod check_attr;
+mod check_export;
 pub mod dead;
 mod debugger_visualizer;
 mod diagnostic_items;
@@ -54,4 +55,5 @@ pub fn provide(providers: &mut Providers) {
     reachable::provide(providers);
     stability::provide(providers);
     upvars::provide(providers);
+    check_export::provide(providers);
 }
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index 321e5729b72..f0e8fa986fe 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -435,10 +435,12 @@ fn has_custom_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
 fn reachable_set(tcx: TyCtxt<'_>, (): ()) -> LocalDefIdSet {
     let effective_visibilities = &tcx.effective_visibilities(());
 
-    let any_library = tcx
-        .crate_types()
-        .iter()
-        .any(|ty| *ty == CrateType::Rlib || *ty == CrateType::Dylib || *ty == CrateType::ProcMacro);
+    let any_library = tcx.crate_types().iter().any(|ty| {
+        *ty == CrateType::Rlib
+            || *ty == CrateType::Dylib
+            || *ty == CrateType::ProcMacro
+            || *ty == CrateType::Sdylib
+    });
     let mut reachable_context = ReachableContext {
         tcx,
         maybe_typeck_results: None,
diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs
index 701f500e4f6..93d164e7d01 100644
--- a/compiler/rustc_passes/src/weak_lang_items.rs
+++ b/compiler/rustc_passes/src/weak_lang_items.rs
@@ -67,7 +67,8 @@ fn verify(tcx: TyCtxt<'_>, items: &lang_items::LanguageItems) {
         | CrateType::ProcMacro
         | CrateType::Cdylib
         | CrateType::Executable
-        | CrateType::Staticlib => true,
+        | CrateType::Staticlib
+        | CrateType::Sdylib => true,
         CrateType::Rlib => false,
     });
     if !needs_check {
diff --git a/compiler/rustc_pattern_analysis/messages.ftl b/compiler/rustc_pattern_analysis/messages.ftl
index 41a1d958f10..d3a3107f8e8 100644
--- a/compiler/rustc_pattern_analysis/messages.ftl
+++ b/compiler/rustc_pattern_analysis/messages.ftl
@@ -6,6 +6,10 @@ pattern_analysis_excluside_range_missing_max = exclusive range missing `{$max}`
     .label = this range doesn't match `{$max}` because `..` is an exclusive range
     .suggestion = use an inclusive range instead
 
+pattern_analysis_mixed_deref_pattern_constructors = mix of deref patterns and normal constructors
+    .deref_pattern_label = matches on the result of dereferencing `{$smart_pointer_ty}`
+    .normal_constructor_label = matches directly on `{$smart_pointer_ty}`
+
 pattern_analysis_non_exhaustive_omitted_pattern = some variants are not matched explicitly
     .help = ensure that all variants are matched explicitly by adding the suggested match arms
     .note = the matched value is of type `{$scrut_ty}` and the `non_exhaustive_omitted_patterns` attribute was found
diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs
index 4ce868f014f..f7a4931c111 100644
--- a/compiler/rustc_pattern_analysis/src/constructor.rs
+++ b/compiler/rustc_pattern_analysis/src/constructor.rs
@@ -696,6 +696,10 @@ pub enum Constructor<Cx: PatCx> {
     F128Range(IeeeFloat<QuadS>, IeeeFloat<QuadS>, RangeEnd),
     /// String literals. Strings are not quite the same as `&[u8]` so we treat them separately.
     Str(Cx::StrLit),
+    /// Deref patterns (enabled by the `deref_patterns` feature) provide a way of matching on a
+    /// smart pointer ADT through its pointee. They don't directly correspond to ADT constructors,
+    /// and currently are not supported alongside them. Carries the type of the pointee.
+    DerefPattern(Cx::Ty),
     /// Constants that must not be matched structurally. They are treated as black boxes for the
     /// purposes of exhaustiveness: we must not inspect them, and they don't count towards making a
     /// match exhaustive.
@@ -740,6 +744,7 @@ impl<Cx: PatCx> Clone for Constructor<Cx> {
             Constructor::F64Range(lo, hi, end) => Constructor::F64Range(*lo, *hi, *end),
             Constructor::F128Range(lo, hi, end) => Constructor::F128Range(*lo, *hi, *end),
             Constructor::Str(value) => Constructor::Str(value.clone()),
+            Constructor::DerefPattern(ty) => Constructor::DerefPattern(ty.clone()),
             Constructor::Opaque(inner) => Constructor::Opaque(inner.clone()),
             Constructor::Or => Constructor::Or,
             Constructor::Never => Constructor::Never,
@@ -856,6 +861,10 @@ impl<Cx: PatCx> Constructor<Cx> {
             }
             (Slice(self_slice), Slice(other_slice)) => self_slice.is_covered_by(*other_slice),
 
+            // Deref patterns only interact with other deref patterns. Prior to usefulness analysis,
+            // we ensure they don't appear alongside any other non-wild non-opaque constructors.
+            (DerefPattern(_), DerefPattern(_)) => true,
+
             // Opaque constructors don't interact with anything unless they come from the
             // syntactically identical pattern.
             (Opaque(self_id), Opaque(other_id)) => self_id == other_id,
@@ -932,6 +941,7 @@ impl<Cx: PatCx> Constructor<Cx> {
             F64Range(lo, hi, end) => write!(f, "{lo}{end}{hi}")?,
             F128Range(lo, hi, end) => write!(f, "{lo}{end}{hi}")?,
             Str(value) => write!(f, "{value:?}")?,
+            DerefPattern(_) => write!(f, "deref!({:?})", fields.next().unwrap())?,
             Opaque(..) => write!(f, "<constant pattern>")?,
             Or => {
                 for pat in fields {
@@ -1039,8 +1049,17 @@ impl<Cx: PatCx> ConstructorSet<Cx> {
         let mut missing = Vec::new();
         // Constructors in `ctors`, except wildcards and opaques.
         let mut seen = Vec::new();
+        // If we see a deref pattern, it must be the only non-wildcard non-opaque constructor; we
+        // ensure this prior to analysis.
+        let mut deref_pat_present = false;
         for ctor in ctors.cloned() {
             match ctor {
+                DerefPattern(..) => {
+                    if !deref_pat_present {
+                        deref_pat_present = true;
+                        present.push(ctor);
+                    }
+                }
                 Opaque(..) => present.push(ctor),
                 Wildcard => {} // discard wildcards
                 _ => seen.push(ctor),
@@ -1048,6 +1067,9 @@ impl<Cx: PatCx> ConstructorSet<Cx> {
         }
 
         match self {
+            _ if deref_pat_present => {
+                // Deref patterns are the only constructor; nothing is missing.
+            }
             ConstructorSet::Struct { empty } => {
                 if !seen.is_empty() {
                     present.push(Struct);
diff --git a/compiler/rustc_pattern_analysis/src/errors.rs b/compiler/rustc_pattern_analysis/src/errors.rs
index e60930d6cd2..156ba973767 100644
--- a/compiler/rustc_pattern_analysis/src/errors.rs
+++ b/compiler/rustc_pattern_analysis/src/errors.rs
@@ -1,5 +1,5 @@
 use rustc_errors::{Diag, EmissionGuarantee, Subdiagnostic};
-use rustc_macros::{LintDiagnostic, Subdiagnostic};
+use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
 use rustc_middle::ty::Ty;
 use rustc_span::Span;
 
@@ -133,3 +133,15 @@ pub(crate) struct NonExhaustiveOmittedPatternLintOnArm {
     pub lint_level: &'static str,
     pub lint_name: &'static str,
 }
+
+#[derive(Diagnostic)]
+#[diag(pattern_analysis_mixed_deref_pattern_constructors)]
+pub(crate) struct MixedDerefPatternConstructors<'tcx> {
+    #[primary_span]
+    pub spans: Vec<Span>,
+    pub smart_pointer_ty: Ty<'tcx>,
+    #[label(pattern_analysis_deref_pattern_label)]
+    pub deref_pattern_label: Span,
+    #[label(pattern_analysis_normal_constructor_label)]
+    pub normal_constructor_label: Span,
+}
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index 7c12f69f14c..a89d01dcbbe 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -269,6 +269,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
                 }
                 _ => bug!("bad slice pattern {:?} {:?}", ctor, ty),
             },
+            DerefPattern(pointee_ty) => reveal_and_alloc(cx, once(pointee_ty.inner())),
             Bool(..) | IntRange(..) | F16Range(..) | F32Range(..) | F64Range(..)
             | F128Range(..) | Str(..) | Opaque(..) | Never | NonExhaustive | Hidden | Missing
             | PrivateUninhabited | Wildcard => &[],
@@ -296,7 +297,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
                 }
                 _ => bug!("Unexpected type for constructor `{ctor:?}`: {ty:?}"),
             },
-            Ref => 1,
+            Ref | DerefPattern(_) => 1,
             Slice(slice) => slice.arity(),
             Bool(..) | IntRange(..) | F16Range(..) | F32Range(..) | F64Range(..)
             | F128Range(..) | Str(..) | Opaque(..) | Never | NonExhaustive | Hidden | Missing
@@ -493,11 +494,15 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
                     ),
                 };
             }
-            PatKind::DerefPattern { .. } => {
-                // FIXME(deref_patterns): At least detect that `box _` is irrefutable.
-                fields = vec![];
-                arity = 0;
-                ctor = Opaque(OpaqueId::new());
+            PatKind::DerefPattern { subpattern, .. } => {
+                // NB(deref_patterns): This assumes the deref pattern is matching on a trusted
+                // `DerefPure` type. If the `Deref` impl isn't trusted, exhaustiveness must take
+                // into account that multiple calls to deref may return different results. Hence
+                // multiple deref! patterns cannot be exhaustive together unless each is exhaustive
+                // by itself.
+                fields = vec![self.lower_pat(subpattern).at_index(0)];
+                arity = 1;
+                ctor = DerefPattern(cx.reveal_opaque_ty(subpattern.ty));
             }
             PatKind::Leaf { subpatterns } | PatKind::Variant { subpatterns, .. } => {
                 match ty.kind() {
@@ -874,6 +879,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
                 print::write_ref_like(&mut s, pat.ty().inner(), &print(&pat.fields[0])).unwrap();
                 s
             }
+            DerefPattern(_) => format!("deref!({})", print(&pat.fields[0])),
             Slice(slice) => {
                 let (prefix_len, has_dot_dot) = match slice.kind {
                     SliceKind::FixedLen(len) => (len, false),
@@ -1100,6 +1106,14 @@ pub fn analyze_match<'p, 'tcx>(
     scrut_ty: Ty<'tcx>,
 ) -> Result<UsefulnessReport<'p, 'tcx>, ErrorGuaranteed> {
     let scrut_ty = tycx.reveal_opaque_ty(scrut_ty);
+
+    // The analysis doesn't support deref patterns mixed with normal constructors; error if present.
+    // FIXME(deref_patterns): This only needs to run when a deref pattern was found during lowering.
+    if tycx.tcx.features().deref_patterns() {
+        let pat_column = PatternColumn::new(arms);
+        detect_mixed_deref_pat_ctors(tycx, &pat_column)?;
+    }
+
     let scrut_validity = PlaceValidity::from_bool(tycx.known_valid_scrutinee);
     let report = compute_match_usefulness(
         tycx,
@@ -1119,6 +1133,51 @@ pub fn analyze_match<'p, 'tcx>(
     Ok(report)
 }
 
+// FIXME(deref_patterns): Currently it's the responsibility of the frontend (rustc or rust-analyzer)
+// to ensure that deref patterns don't appear in the same column as normal constructors. Deref
+// patterns aren't currently implemented in rust-analyzer, but should they be, the columnwise check
+// here could be made generic and shared between frontends.
+fn detect_mixed_deref_pat_ctors<'p, 'tcx>(
+    cx: &RustcPatCtxt<'p, 'tcx>,
+    column: &PatternColumn<'p, RustcPatCtxt<'p, 'tcx>>,
+) -> Result<(), ErrorGuaranteed> {
+    let Some(&ty) = column.head_ty() else {
+        return Ok(());
+    };
+
+    // Check for a mix of deref patterns and normal constructors.
+    let mut normal_ctor_span = None;
+    let mut deref_pat_span = None;
+    for pat in column.iter() {
+        match pat.ctor() {
+            // The analysis can handle mixing deref patterns with wildcards and opaque patterns.
+            Wildcard | Opaque(_) => {}
+            DerefPattern(_) => deref_pat_span = Some(pat.data().span),
+            // Nothing else can be compared to deref patterns in `Constructor::is_covered_by`.
+            _ => normal_ctor_span = Some(pat.data().span),
+        }
+    }
+    if let Some(normal_constructor_label) = normal_ctor_span
+        && let Some(deref_pattern_label) = deref_pat_span
+    {
+        return Err(cx.tcx.dcx().emit_err(errors::MixedDerefPatternConstructors {
+            spans: vec![deref_pattern_label, normal_constructor_label],
+            smart_pointer_ty: ty.inner(),
+            deref_pattern_label,
+            normal_constructor_label,
+        }));
+    }
+
+    // Specialize and recurse into the patterns' fields.
+    let set = column.analyze_ctors(cx, &ty)?;
+    for ctor in set.present {
+        for specialized_column in column.specialize(cx, &ty, &ctor).iter() {
+            detect_mixed_deref_pat_ctors(cx, specialized_column)?;
+        }
+    }
+    Ok(())
+}
+
 struct RecursiveOpaque {
     def_id: DefId,
 }
diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs
index 11ebbea07fa..53638f2a57d 100644
--- a/compiler/rustc_pattern_analysis/src/usefulness.rs
+++ b/compiler/rustc_pattern_analysis/src/usefulness.rs
@@ -702,6 +702,7 @@
 //!   - `ui/consts/const_in_pattern`
 //!   - `ui/rfc-2008-non-exhaustive`
 //!   - `ui/half-open-range-patterns`
+//!   - `ui/pattern/deref-patterns`
 //!   - probably many others
 //!
 //! I (Nadrieril) prefer to put new tests in `ui/pattern/usefulness` unless there's a specific
@@ -866,7 +867,8 @@ impl PlaceValidity {
     /// inside `&` and union fields where validity is reset to `MaybeInvalid`.
     fn specialize<Cx: PatCx>(self, ctor: &Constructor<Cx>) -> Self {
         // We preserve validity except when we go inside a reference or a union field.
-        if matches!(ctor, Constructor::Ref | Constructor::UnionField) {
+        if matches!(ctor, Constructor::Ref | Constructor::DerefPattern(_) | Constructor::UnionField)
+        {
             // Validity of `x: &T` does not imply validity of `*x: T`.
             MaybeInvalid
         } else {
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 0d56db16099..3ae56cef2c4 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -11,7 +11,7 @@ use rustc_data_structures::outline;
 use rustc_data_structures::profiling::QueryInvocationId;
 use rustc_data_structures::sharded::{self, ShardedHashMap};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_data_structures::sync::{AtomicU64, Lock};
+use rustc_data_structures::sync::{AtomicU64, Lock, is_dyn_thread_safe};
 use rustc_data_structures::unord::UnordMap;
 use rustc_errors::DiagInner;
 use rustc_index::IndexVec;
@@ -124,19 +124,11 @@ impl<D: Deps> DepGraph<D> {
         prev_graph: Arc<SerializedDepGraph>,
         prev_work_products: WorkProductMap,
         encoder: FileEncoder,
-        record_graph: bool,
-        record_stats: bool,
     ) -> DepGraph<D> {
         let prev_graph_node_count = prev_graph.node_count();
 
-        let current = CurrentDepGraph::new(
-            session,
-            prev_graph_node_count,
-            encoder,
-            record_graph,
-            record_stats,
-            Arc::clone(&prev_graph),
-        );
+        let current =
+            CurrentDepGraph::new(session, prev_graph_node_count, encoder, Arc::clone(&prev_graph));
 
         let colors = DepNodeColorMap::new(prev_graph_node_count);
 
@@ -1052,17 +1044,8 @@ impl<D: Deps> DepGraph<D> {
         }
     }
 
-    pub fn print_incremental_info(&self) {
-        if let Some(data) = &self.data {
-            data.current.encoder.print_incremental_info(
-                data.current.total_read_count.load(Ordering::Relaxed),
-                data.current.total_duplicate_read_count.load(Ordering::Relaxed),
-            )
-        }
-    }
-
     pub fn finish_encoding(&self) -> FileEncodeResult {
-        if let Some(data) = &self.data { data.current.encoder.finish() } else { Ok(0) }
+        if let Some(data) = &self.data { data.current.encoder.finish(&data.current) } else { Ok(0) }
     }
 
     pub(crate) fn next_virtual_depnode_index(&self) -> DepNodeIndex {
@@ -1179,8 +1162,8 @@ pub(super) struct CurrentDepGraph<D: Deps> {
 
     /// These are simple counters that are for profiling and
     /// debugging and only active with `debug_assertions`.
-    total_read_count: AtomicU64,
-    total_duplicate_read_count: AtomicU64,
+    pub(super) total_read_count: AtomicU64,
+    pub(super) total_duplicate_read_count: AtomicU64,
 }
 
 impl<D: Deps> CurrentDepGraph<D> {
@@ -1188,8 +1171,6 @@ impl<D: Deps> CurrentDepGraph<D> {
         session: &Session,
         prev_graph_node_count: usize,
         encoder: FileEncoder,
-        record_graph: bool,
-        record_stats: bool,
         previous: Arc<SerializedDepGraph>,
     ) -> Self {
         let mut stable_hasher = StableHasher::new();
@@ -1211,14 +1192,7 @@ impl<D: Deps> CurrentDepGraph<D> {
             session.opts.unstable_opts.incremental_verify_ich || cfg!(debug_assertions);
 
         CurrentDepGraph {
-            encoder: GraphEncoder::new(
-                encoder,
-                prev_graph_node_count,
-                record_graph,
-                record_stats,
-                &session.prof,
-                previous,
-            ),
+            encoder: GraphEncoder::new(session, encoder, prev_graph_node_count, previous),
             anon_node_to_index: ShardedHashMap::with_capacity(
                 // FIXME: The count estimate is off as anon nodes are only a portion of the nodes.
                 new_node_count_estimate / sharded::shards(),
@@ -1345,6 +1319,7 @@ impl Default for TaskDeps {
 // array, using one u32 per entry.
 pub(super) struct DepNodeColorMap {
     values: IndexVec<SerializedDepNodeIndex, AtomicU32>,
+    sync: bool,
 }
 
 const COMPRESSED_NONE: u32 = u32::MAX;
@@ -1353,7 +1328,10 @@ const COMPRESSED_RED: u32 = u32::MAX - 1;
 impl DepNodeColorMap {
     fn new(size: usize) -> DepNodeColorMap {
         debug_assert!(COMPRESSED_RED > DepNodeIndex::MAX_AS_U32);
-        DepNodeColorMap { values: (0..size).map(|_| AtomicU32::new(COMPRESSED_NONE)).collect() }
+        DepNodeColorMap {
+            values: (0..size).map(|_| AtomicU32::new(COMPRESSED_NONE)).collect(),
+            sync: is_dyn_thread_safe(),
+        }
     }
 
     #[inline]
@@ -1362,6 +1340,37 @@ impl DepNodeColorMap {
         if value <= DepNodeIndex::MAX_AS_U32 { Some(DepNodeIndex::from_u32(value)) } else { None }
     }
 
+    /// This tries to atomically mark a node green and assign `index` as the new
+    /// index. This returns `Ok` if `index` gets assigned, otherwise it returns
+    /// the alreadly allocated index in `Err`.
+    #[inline]
+    pub(super) fn try_mark_green(
+        &self,
+        prev_index: SerializedDepNodeIndex,
+        index: DepNodeIndex,
+    ) -> Result<(), DepNodeIndex> {
+        let value = &self.values[prev_index];
+        if self.sync {
+            match value.compare_exchange(
+                COMPRESSED_NONE,
+                index.as_u32(),
+                Ordering::Relaxed,
+                Ordering::Relaxed,
+            ) {
+                Ok(_) => Ok(()),
+                Err(v) => Err(DepNodeIndex::from_u32(v)),
+            }
+        } else {
+            let v = value.load(Ordering::Relaxed);
+            if v == COMPRESSED_NONE {
+                value.store(index.as_u32(), Ordering::Relaxed);
+                Ok(())
+            } else {
+                Err(DepNodeIndex::from_u32(v))
+            }
+        }
+    }
+
     #[inline]
     pub(super) fn get(&self, index: SerializedDepNodeIndex) -> Option<DepNodeColor> {
         match self.values[index].load(Ordering::Acquire) {
diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs
index 3a80835afad..89d1db87809 100644
--- a/compiler/rustc_query_system/src/dep_graph/mod.rs
+++ b/compiler/rustc_query_system/src/dep_graph/mod.rs
@@ -12,6 +12,7 @@ pub(crate) use graph::DepGraphData;
 pub use graph::{DepGraph, DepNodeIndex, TaskDepsRef, WorkProduct, WorkProductMap, hash_result};
 pub use query::DepGraphQuery;
 use rustc_data_structures::profiling::SelfProfilerRef;
+use rustc_data_structures::sync::DynSync;
 use rustc_session::Session;
 pub use serialized::{SerializedDepGraph, SerializedDepNodeIndex};
 use tracing::instrument;
@@ -89,7 +90,7 @@ pub trait DepContext: Copy {
     }
 }
 
-pub trait Deps {
+pub trait Deps: DynSync {
     /// Execute the operation with provided dependencies.
     fn with_deps<OP, R>(deps: TaskDepsRef<'_>, op: OP) -> R
     where
diff --git a/compiler/rustc_query_system/src/dep_graph/query.rs b/compiler/rustc_query_system/src/dep_graph/query.rs
index 624f4e4578e..724a01327ab 100644
--- a/compiler/rustc_query_system/src/dep_graph/query.rs
+++ b/compiler/rustc_query_system/src/dep_graph/query.rs
@@ -1,11 +1,11 @@
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::graph::implementation::{Direction, Graph, INCOMING, NodeIndex};
+use rustc_data_structures::graph::linked_graph::{Direction, INCOMING, LinkedGraph, NodeIndex};
 use rustc_index::IndexVec;
 
 use super::{DepNode, DepNodeIndex};
 
 pub struct DepGraphQuery {
-    pub graph: Graph<DepNode, ()>,
+    pub graph: LinkedGraph<DepNode, ()>,
     pub indices: FxHashMap<DepNode, NodeIndex>,
     pub dep_index_to_index: IndexVec<DepNodeIndex, Option<NodeIndex>>,
 }
@@ -15,7 +15,7 @@ impl DepGraphQuery {
         let node_count = prev_node_count + prev_node_count / 4;
         let edge_count = 6 * node_count;
 
-        let graph = Graph::with_capacity(node_count, edge_count);
+        let graph = LinkedGraph::with_capacity(node_count, edge_count);
         let indices = FxHashMap::default();
         let dep_index_to_index = IndexVec::new();
 
diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs
index d2bcde14383..f1b609a3ca9 100644
--- a/compiler/rustc_query_system/src/dep_graph/serialized.rs
+++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs
@@ -12,7 +12,7 @@
 //! node and edge count are stored at the end of the file, all the arrays can be
 //! pre-allocated with the right length.
 //!
-//! The encoding of the de-pgraph is generally designed around the fact that fixed-size
+//! The encoding of the dep-graph is generally designed around the fact that fixed-size
 //! reads of encoded data are generally faster than variable-sized reads. Ergo we adopt
 //! essentially the same varint encoding scheme used in the rmeta format; the edge lists
 //! for each node on the graph store a 2-bit integer which is the number of bytes per edge
@@ -34,24 +34,32 @@
 //! [`DepKind`], number of edges, and bytes per edge are all bit-packed together, if they fit.
 //! If the number of edges in this node does not fit in the bits available in the header, we
 //! store it directly after the header with leb128.
+//!
+//! Dep-graph indices are bulk allocated to threads inside `LocalEncoderState`. Having threads
+//! own these indices helps avoid races when they are conditionally used when marking nodes green.
+//! It also reduces congestion on the shared index count.
 
-use std::iter;
+use std::cell::RefCell;
+use std::cmp::max;
 use std::marker::PhantomData;
 use std::sync::Arc;
+use std::sync::atomic::Ordering;
+use std::{iter, mem, u64};
 
 use rustc_data_structures::fingerprint::{Fingerprint, PackedFingerprint};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::outline;
 use rustc_data_structures::profiling::SelfProfilerRef;
-use rustc_data_structures::sync::Lock;
+use rustc_data_structures::sync::{AtomicU64, Lock, WorkerLocal, broadcast};
 use rustc_data_structures::unhash::UnhashMap;
-use rustc_index::{Idx, IndexVec};
+use rustc_index::IndexVec;
 use rustc_serialize::opaque::mem_encoder::MemEncoder;
 use rustc_serialize::opaque::{FileEncodeResult, FileEncoder, IntEncodedWithFixedSize, MemDecoder};
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
+use rustc_session::Session;
 use tracing::{debug, instrument};
 
-use super::graph::{DepNodeColor, DepNodeColorMap};
+use super::graph::{CurrentDepGraph, DepNodeColor, DepNodeColorMap};
 use super::query::DepGraphQuery;
 use super::{DepKind, DepNode, DepNodeIndex, Deps};
 use crate::dep_graph::edges::EdgesVec;
@@ -76,6 +84,9 @@ const DEP_NODE_PAD: usize = DEP_NODE_SIZE - 1;
 const DEP_NODE_WIDTH_BITS: usize = DEP_NODE_SIZE / 2;
 
 /// Data for use when recompiling the **current crate**.
+///
+/// There may be unused indices with DEP_KIND_NULL in this graph due to batch allocation of
+/// indices to threads.
 #[derive(Debug, Default)]
 pub struct SerializedDepGraph {
     /// The set of all DepNodes in the graph
@@ -184,26 +195,30 @@ impl SerializedDepGraph {
     pub fn decode<D: Deps>(d: &mut MemDecoder<'_>, deps: &D) -> Arc<SerializedDepGraph> {
         // The last 16 bytes are the node count and edge count.
         debug!("position: {:?}", d.position());
-        let (node_count, edge_count) =
-            d.with_position(d.len() - 2 * IntEncodedWithFixedSize::ENCODED_SIZE, |d| {
+
+        // `node_max` is the number of indices including empty nodes while `node_count`
+        // is the number of actually encoded nodes.
+        let (node_max, node_count, edge_count) =
+            d.with_position(d.len() - 3 * IntEncodedWithFixedSize::ENCODED_SIZE, |d| {
                 debug!("position: {:?}", d.position());
+                let node_max = IntEncodedWithFixedSize::decode(d).0 as usize;
                 let node_count = IntEncodedWithFixedSize::decode(d).0 as usize;
                 let edge_count = IntEncodedWithFixedSize::decode(d).0 as usize;
-                (node_count, edge_count)
+                (node_max, node_count, edge_count)
             });
         debug!("position: {:?}", d.position());
 
         debug!(?node_count, ?edge_count);
 
-        let graph_bytes = d.len() - (2 * IntEncodedWithFixedSize::ENCODED_SIZE) - d.position();
+        let graph_bytes = d.len() - (3 * IntEncodedWithFixedSize::ENCODED_SIZE) - d.position();
 
         let mut nodes = IndexVec::from_elem_n(
             DepNode { kind: D::DEP_KIND_NULL, hash: PackedFingerprint::from(Fingerprint::ZERO) },
-            node_count,
+            node_max,
         );
-        let mut fingerprints = IndexVec::from_elem_n(Fingerprint::ZERO, node_count);
+        let mut fingerprints = IndexVec::from_elem_n(Fingerprint::ZERO, node_max);
         let mut edge_list_indices =
-            IndexVec::from_elem_n(EdgeHeader { repr: 0, num_edges: 0 }, node_count);
+            IndexVec::from_elem_n(EdgeHeader { repr: 0, num_edges: 0 }, node_max);
 
         // This estimation assumes that all of the encoded bytes are for the edge lists or for the
         // fixed-size node headers. But that's not necessarily true; if any edge list has a length
@@ -217,7 +232,7 @@ impl SerializedDepGraph {
         let mut edge_list_data =
             Vec::with_capacity(graph_bytes - node_count * size_of::<SerializedNodeHeader<D>>());
 
-        for _index in 0..node_count {
+        for _ in 0..node_count {
             // Decode the header for this edge; the header packs together as many of the fixed-size
             // fields as possible to limit the number of times we update decoder state.
             let node_header =
@@ -263,8 +278,8 @@ impl SerializedDepGraph {
 
         for (idx, node) in nodes.iter_enumerated() {
             if index[node.kind.as_usize()].insert(node.hash, idx).is_some() {
-                // Side effect nodes can have duplicates
-                if node.kind != D::DEP_KIND_SIDE_EFFECT {
+                // Empty nodes and side effect nodes can have duplicates
+                if node.kind != D::DEP_KIND_NULL && node.kind != D::DEP_KIND_SIDE_EFFECT {
                     let name = deps.name(node.kind);
                     panic!(
                     "Error: A dep graph node ({name}) does not have an unique index. \
@@ -508,17 +523,32 @@ struct Stat {
     edge_counter: u64,
 }
 
-struct EncoderState<D: Deps> {
-    previous: Arc<SerializedDepGraph>,
-    encoder: FileEncoder,
-    total_node_count: usize,
-    total_edge_count: usize,
-    stats: Option<FxHashMap<DepKind, Stat>>,
+struct LocalEncoderState {
+    next_node_index: u32,
+    remaining_node_index: u32,
+    encoder: MemEncoder,
+    node_count: usize,
+    edge_count: usize,
 
-    mem_encoder: MemEncoder,
+    /// Stores the number of times we've encoded each dep kind.
+    kind_stats: Vec<u32>,
+}
+
+struct LocalEncoderResult {
+    node_max: u32,
+    node_count: usize,
+    edge_count: usize,
 
     /// Stores the number of times we've encoded each dep kind.
     kind_stats: Vec<u32>,
+}
+
+struct EncoderState<D: Deps> {
+    next_node_index: AtomicU64,
+    previous: Arc<SerializedDepGraph>,
+    file: Lock<Option<FileEncoder>>,
+    local: WorkerLocal<RefCell<LocalEncoderState>>,
+    stats: Option<Lock<FxHashMap<DepKind, Stat>>>,
     marker: PhantomData<D>,
 }
 
@@ -526,34 +556,63 @@ impl<D: Deps> EncoderState<D> {
     fn new(encoder: FileEncoder, record_stats: bool, previous: Arc<SerializedDepGraph>) -> Self {
         Self {
             previous,
-            encoder,
-            total_edge_count: 0,
-            total_node_count: 0,
-            stats: record_stats.then(FxHashMap::default),
-            mem_encoder: MemEncoder::new(),
-            kind_stats: iter::repeat(0).take(D::DEP_KIND_MAX as usize + 1).collect(),
+            next_node_index: AtomicU64::new(0),
+            stats: record_stats.then(|| Lock::new(FxHashMap::default())),
+            file: Lock::new(Some(encoder)),
+            local: WorkerLocal::new(|_| {
+                RefCell::new(LocalEncoderState {
+                    next_node_index: 0,
+                    remaining_node_index: 0,
+                    edge_count: 0,
+                    node_count: 0,
+                    encoder: MemEncoder::new(),
+                    kind_stats: iter::repeat(0).take(D::DEP_KIND_MAX as usize + 1).collect(),
+                })
+            }),
             marker: PhantomData,
         }
     }
 
     #[inline]
-    fn alloc_index(&mut self) -> DepNodeIndex {
-        let index = DepNodeIndex::new(self.total_node_count);
-        self.total_node_count += 1;
-        index
+    fn next_index(&self, local: &mut LocalEncoderState) -> DepNodeIndex {
+        if local.remaining_node_index == 0 {
+            const COUNT: u32 = 256;
+
+            // We assume that there won't be enough active threads to overflow `u64` from `u32::MAX` here.
+            // This can exceed u32::MAX by at most `N` * `COUNT` where `N` is the thread pool count since
+            // `try_into().unwrap()` will make threads panic when `self.next_node_index` exceeds u32::MAX.
+            local.next_node_index =
+                self.next_node_index.fetch_add(COUNT as u64, Ordering::Relaxed).try_into().unwrap();
+
+            // Check that we'll stay within `u32`
+            local.next_node_index.checked_add(COUNT).unwrap();
+
+            local.remaining_node_index = COUNT;
+        }
+
+        DepNodeIndex::from_u32(local.next_node_index)
+    }
+
+    /// Marks the index previously returned by `next_index` as used.
+    #[inline]
+    fn bump_index(&self, local: &mut LocalEncoderState) {
+        local.remaining_node_index -= 1;
+        local.next_node_index += 1;
+        local.node_count += 1;
     }
 
     #[inline]
     fn record(
-        &mut self,
+        &self,
         node: DepNode,
         index: DepNodeIndex,
         edge_count: usize,
-        edges: impl FnOnce(&mut Self) -> Vec<DepNodeIndex>,
+        edges: impl FnOnce(&Self) -> Vec<DepNodeIndex>,
         record_graph: &Option<Lock<DepGraphQuery>>,
-    ) -> DepNodeIndex {
-        self.kind_stats[node.kind.as_usize()] += 1;
-        self.total_edge_count += edge_count;
+        local: &mut LocalEncoderState,
+    ) {
+        local.kind_stats[node.kind.as_usize()] += 1;
+        local.edge_count += edge_count;
 
         if let Some(record_graph) = &record_graph {
             // Call `edges` before the outlined code to allow the closure to be optimized out.
@@ -568,40 +627,47 @@ impl<D: Deps> EncoderState<D> {
             });
         }
 
-        if let Some(stats) = &mut self.stats {
+        if let Some(stats) = &self.stats {
             let kind = node.kind;
 
             // Outline the stats code as it's typically disabled and cold.
             outline(move || {
+                let mut stats = stats.lock();
                 let stat =
                     stats.entry(kind).or_insert(Stat { kind, node_counter: 0, edge_counter: 0 });
                 stat.node_counter += 1;
                 stat.edge_counter += edge_count as u64;
             });
         }
-
-        index
     }
 
     #[inline]
-    fn flush_mem_encoder(&mut self) {
-        let data = &mut self.mem_encoder.data;
+    fn flush_mem_encoder(&self, local: &mut LocalEncoderState) {
+        let data = &mut local.encoder.data;
         if data.len() > 64 * 1024 {
-            self.encoder.emit_raw_bytes(&data[..]);
+            self.file.lock().as_mut().unwrap().emit_raw_bytes(&data[..]);
             data.clear();
         }
     }
 
     /// Encodes a node to the current graph.
     fn encode_node(
-        &mut self,
+        &self,
+        index: DepNodeIndex,
         node: &NodeInfo,
         record_graph: &Option<Lock<DepGraphQuery>>,
-    ) -> DepNodeIndex {
-        let index = self.alloc_index();
-        node.encode::<D>(&mut self.mem_encoder, index);
-        self.flush_mem_encoder();
-        self.record(node.node, index, node.edges.len(), |_| node.edges[..].to_vec(), record_graph)
+        local: &mut LocalEncoderState,
+    ) {
+        node.encode::<D>(&mut local.encoder, index);
+        self.flush_mem_encoder(&mut *local);
+        self.record(
+            node.node,
+            index,
+            node.edges.len(),
+            |_| node.edges[..].to_vec(),
+            record_graph,
+            &mut *local,
+        );
     }
 
     /// Encodes a node that was promoted from the previous graph. It reads the information directly from
@@ -612,16 +678,17 @@ impl<D: Deps> EncoderState<D> {
     /// It expects all edges to already have a new dep node index assigned.
     #[inline]
     fn encode_promoted_node(
-        &mut self,
+        &self,
+        index: DepNodeIndex,
         prev_index: SerializedDepNodeIndex,
         record_graph: &Option<Lock<DepGraphQuery>>,
         colors: &DepNodeColorMap,
-    ) -> DepNodeIndex {
-        let index = self.alloc_index();
+        local: &mut LocalEncoderState,
+    ) {
         let node = self.previous.index_to_node(prev_index);
         let fingerprint = self.previous.fingerprint_by_index(prev_index);
         let edge_count = NodeInfo::encode_promoted::<D>(
-            &mut self.mem_encoder,
+            &mut local.encoder,
             node,
             index,
             fingerprint,
@@ -629,7 +696,7 @@ impl<D: Deps> EncoderState<D> {
             colors,
             &self.previous,
         );
-        self.flush_mem_encoder();
+        self.flush_mem_encoder(&mut *local);
         self.record(
             node,
             index,
@@ -641,38 +708,60 @@ impl<D: Deps> EncoderState<D> {
                     .collect()
             },
             record_graph,
+            &mut *local,
         );
-        index
     }
 
-    fn finish(self, profiler: &SelfProfilerRef) -> FileEncodeResult {
-        let Self {
-            mut encoder,
-            mem_encoder,
-            total_node_count,
-            total_edge_count,
-            stats: _,
-            kind_stats,
-            marker: _,
-            previous,
-        } = self;
+    fn finish(&self, profiler: &SelfProfilerRef, current: &CurrentDepGraph<D>) -> FileEncodeResult {
+        // Prevent more indices from being allocated.
+        self.next_node_index.store(u32::MAX as u64 + 1, Ordering::SeqCst);
+
+        let results = broadcast(|_| {
+            let mut local = self.local.borrow_mut();
+
+            // Prevent more indices from being allocated on this thread.
+            local.remaining_node_index = 0;
+
+            let data = mem::replace(&mut local.encoder.data, Vec::new());
+            self.file.lock().as_mut().unwrap().emit_raw_bytes(&data);
 
-        encoder.emit_raw_bytes(&mem_encoder.data);
+            LocalEncoderResult {
+                kind_stats: local.kind_stats.clone(),
+                node_max: local.next_node_index,
+                node_count: local.node_count,
+                edge_count: local.edge_count,
+            }
+        });
+
+        let mut encoder = self.file.lock().take().unwrap();
+
+        let mut kind_stats: Vec<u32> = iter::repeat(0).take(D::DEP_KIND_MAX as usize + 1).collect();
 
-        let node_count = total_node_count.try_into().unwrap();
-        let edge_count = total_edge_count.try_into().unwrap();
+        let mut node_max = 0;
+        let mut node_count = 0;
+        let mut edge_count = 0;
+
+        for result in results {
+            node_max = max(node_max, result.node_max);
+            node_count += result.node_count;
+            edge_count += result.edge_count;
+            for (i, stat) in result.kind_stats.iter().enumerate() {
+                kind_stats[i] += stat;
+            }
+        }
 
         // Encode the number of each dep kind encountered
         for count in kind_stats.iter() {
             count.encode(&mut encoder);
         }
 
-        previous.session_count.checked_add(1).unwrap().encode(&mut encoder);
+        self.previous.session_count.checked_add(1).unwrap().encode(&mut encoder);
 
-        debug!(?node_count, ?edge_count);
+        debug!(?node_max, ?node_count, ?edge_count);
         debug!("position: {:?}", encoder.position());
-        IntEncodedWithFixedSize(node_count).encode(&mut encoder);
-        IntEncodedWithFixedSize(edge_count).encode(&mut encoder);
+        IntEncodedWithFixedSize(node_max.try_into().unwrap()).encode(&mut encoder);
+        IntEncodedWithFixedSize(node_count.try_into().unwrap()).encode(&mut encoder);
+        IntEncodedWithFixedSize(edge_count.try_into().unwrap()).encode(&mut encoder);
         debug!("position: {:?}", encoder.position());
         // Drop the encoder so that nothing is written after the counts.
         let result = encoder.finish();
@@ -681,44 +770,20 @@ impl<D: Deps> EncoderState<D> {
             // don't need a dependency on rustc_incremental just for that.
             profiler.artifact_size("dep_graph", "dep-graph.bin", position as u64);
         }
-        result
-    }
-}
 
-pub(crate) struct GraphEncoder<D: Deps> {
-    profiler: SelfProfilerRef,
-    status: Lock<Option<EncoderState<D>>>,
-    record_graph: Option<Lock<DepGraphQuery>>,
-}
+        self.print_incremental_info(current, node_count, edge_count);
 
-impl<D: Deps> GraphEncoder<D> {
-    pub(crate) fn new(
-        encoder: FileEncoder,
-        prev_node_count: usize,
-        record_graph: bool,
-        record_stats: bool,
-        profiler: &SelfProfilerRef,
-        previous: Arc<SerializedDepGraph>,
-    ) -> Self {
-        let record_graph = record_graph.then(|| Lock::new(DepGraphQuery::new(prev_node_count)));
-        let status = Lock::new(Some(EncoderState::new(encoder, record_stats, previous)));
-        GraphEncoder { status, record_graph, profiler: profiler.clone() }
-    }
-
-    pub(crate) fn with_query(&self, f: impl Fn(&DepGraphQuery)) {
-        if let Some(record_graph) = &self.record_graph {
-            f(&record_graph.lock())
-        }
+        result
     }
 
-    pub(crate) fn print_incremental_info(
+    fn print_incremental_info(
         &self,
-        total_read_count: u64,
-        total_duplicate_read_count: u64,
+        current: &CurrentDepGraph<D>,
+        total_node_count: usize,
+        total_edge_count: usize,
     ) {
-        let mut status = self.status.lock();
-        let status = status.as_mut().unwrap();
-        if let Some(record_stats) = &status.stats {
+        if let Some(record_stats) = &self.stats {
+            let record_stats = record_stats.lock();
             let mut stats: Vec<_> = record_stats.values().collect();
             stats.sort_by_key(|s| -(s.node_counter as i64));
 
@@ -730,10 +795,13 @@ impl<D: Deps> GraphEncoder<D> {
             eprintln!("[incremental] DepGraph Statistics");
             eprintln!("{SEPARATOR}");
             eprintln!("[incremental]");
-            eprintln!("[incremental] Total Node Count: {}", status.total_node_count);
-            eprintln!("[incremental] Total Edge Count: {}", status.total_edge_count);
+            eprintln!("[incremental] Total Node Count: {}", total_node_count);
+            eprintln!("[incremental] Total Edge Count: {}", total_edge_count);
 
             if cfg!(debug_assertions) {
+                let total_read_count = current.total_read_count.load(Ordering::Relaxed);
+                let total_duplicate_read_count =
+                    current.total_duplicate_read_count.load(Ordering::Relaxed);
                 eprintln!("[incremental] Total Edge Reads: {total_read_count}");
                 eprintln!("[incremental] Total Duplicate Edge Reads: {total_duplicate_read_count}");
             }
@@ -747,7 +815,7 @@ impl<D: Deps> GraphEncoder<D> {
 
             for stat in stats {
                 let node_kind_ratio =
-                    (100.0 * (stat.node_counter as f64)) / (status.total_node_count as f64);
+                    (100.0 * (stat.node_counter as f64)) / (total_node_count as f64);
                 let node_kind_avg_edges = (stat.edge_counter as f64) / (stat.node_counter as f64);
 
                 eprintln!(
@@ -763,6 +831,35 @@ impl<D: Deps> GraphEncoder<D> {
             eprintln!("[incremental]");
         }
     }
+}
+
+pub(crate) struct GraphEncoder<D: Deps> {
+    profiler: SelfProfilerRef,
+    status: EncoderState<D>,
+    record_graph: Option<Lock<DepGraphQuery>>,
+}
+
+impl<D: Deps> GraphEncoder<D> {
+    pub(crate) fn new(
+        sess: &Session,
+        encoder: FileEncoder,
+        prev_node_count: usize,
+        previous: Arc<SerializedDepGraph>,
+    ) -> Self {
+        let record_graph = sess
+            .opts
+            .unstable_opts
+            .query_dep_graph
+            .then(|| Lock::new(DepGraphQuery::new(prev_node_count)));
+        let status = EncoderState::new(encoder, sess.opts.unstable_opts.incremental_info, previous);
+        GraphEncoder { status, record_graph, profiler: sess.prof.clone() }
+    }
+
+    pub(crate) fn with_query(&self, f: impl Fn(&DepGraphQuery)) {
+        if let Some(record_graph) = &self.record_graph {
+            f(&record_graph.lock())
+        }
+    }
 
     /// Encodes a node that does not exists in the previous graph.
     pub(crate) fn send_new(
@@ -773,7 +870,11 @@ impl<D: Deps> GraphEncoder<D> {
     ) -> DepNodeIndex {
         let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph");
         let node = NodeInfo { node, fingerprint, edges };
-        self.status.lock().as_mut().unwrap().encode_node(&node, &self.record_graph)
+        let mut local = self.status.local.borrow_mut();
+        let index = self.status.next_index(&mut *local);
+        self.status.bump_index(&mut *local);
+        self.status.encode_node(index, &node, &self.record_graph, &mut *local);
+        index
     }
 
     /// Encodes a node that exists in the previous graph, but was re-executed.
@@ -791,23 +892,24 @@ impl<D: Deps> GraphEncoder<D> {
         let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph");
         let node = NodeInfo { node, fingerprint, edges };
 
-        let mut status = self.status.lock();
-        let status = status.as_mut().unwrap();
+        let mut local = self.status.local.borrow_mut();
 
-        // Check colors inside the lock to avoid racing when `send_promoted` is called concurrently
-        // on the same index.
-        match colors.get(prev_index) {
-            None => {
-                let dep_node_index = status.encode_node(&node, &self.record_graph);
-                colors.insert(
-                    prev_index,
-                    if is_green { DepNodeColor::Green(dep_node_index) } else { DepNodeColor::Red },
-                );
-                dep_node_index
+        let index = self.status.next_index(&mut *local);
+
+        if is_green {
+            // Use `try_mark_green` to avoid racing when `send_promoted` is called concurrently
+            // on the same index.
+            match colors.try_mark_green(prev_index, index) {
+                Ok(()) => (),
+                Err(dep_node_index) => return dep_node_index,
             }
-            Some(DepNodeColor::Green(dep_node_index)) => dep_node_index,
-            Some(DepNodeColor::Red) => panic!(),
+        } else {
+            colors.insert(prev_index, DepNodeColor::Red);
         }
+
+        self.status.bump_index(&mut *local);
+        self.status.encode_node(index, &node, &self.record_graph, &mut *local);
+        index
     }
 
     /// Encodes a node that was promoted from the previous graph. It reads the information directly from
@@ -822,26 +924,30 @@ impl<D: Deps> GraphEncoder<D> {
     ) -> DepNodeIndex {
         let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph");
 
-        let mut status = self.status.lock();
-        let status = status.as_mut().unwrap();
+        let mut local = self.status.local.borrow_mut();
+        let index = self.status.next_index(&mut *local);
 
-        // Check colors inside the lock to avoid racing when `send_promoted` or `send_and_color`
+        // Use `try_mark_green` to avoid racing when `send_promoted` or `send_and_color`
         // is called concurrently on the same index.
-        match colors.get(prev_index) {
-            None => {
-                let dep_node_index =
-                    status.encode_promoted_node(prev_index, &self.record_graph, colors);
-                colors.insert(prev_index, DepNodeColor::Green(dep_node_index));
-                dep_node_index
+        match colors.try_mark_green(prev_index, index) {
+            Ok(()) => {
+                self.status.bump_index(&mut *local);
+                self.status.encode_promoted_node(
+                    index,
+                    prev_index,
+                    &self.record_graph,
+                    colors,
+                    &mut *local,
+                );
+                index
             }
-            Some(DepNodeColor::Green(dep_node_index)) => dep_node_index,
-            Some(DepNodeColor::Red) => panic!(),
+            Err(dep_node_index) => dep_node_index,
         }
     }
 
-    pub(crate) fn finish(&self) -> FileEncodeResult {
+    pub(crate) fn finish(&self, current: &CurrentDepGraph<D>) -> FileEncodeResult {
         let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph_finish");
 
-        self.status.lock().take().unwrap().finish(&self.profiler)
+        self.status.finish(&self.profiler, current)
     }
 }
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl
index 558a01713dc..38cdfa72a14 100644
--- a/compiler/rustc_resolve/messages.ftl
+++ b/compiler/rustc_resolve/messages.ftl
@@ -218,10 +218,6 @@ resolve_invalid_asm_sym =
     .label = is a local variable
     .help = `sym` operands must refer to either a function or a static
 
-resolve_is_not_directly_importable =
-    `{$target}` is not directly importable
-    .label = cannot be imported directly
-
 resolve_is_private =
     {$ident_descr} `{$ident}` is private
     .label = private {$ident_descr}
@@ -231,9 +227,6 @@ resolve_item_was_behind_feature =
 
 resolve_item_was_cfg_out = the item is gated here
 
-resolve_items_in_traits_are_not_importable =
-    items in traits are not importable
-
 resolve_label_with_similar_name_reachable =
     a label with a similar name is reachable
 
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index cb328022c76..3460c53782f 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -549,7 +549,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                         source = module_path.pop().unwrap();
                         if rename.is_none() {
                             // Keep the span of `self`, but the name of `foo`
-                            ident = Ident { name: source.ident.name, span: self_span };
+                            ident = Ident::new(source.ident.name, self_span);
                         }
                     }
                 } else {
@@ -597,7 +597,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                         if let Some(crate_name) = crate_name {
                             // `crate_name` should not be interpreted as relative.
                             module_path.push(Segment::from_ident_and_id(
-                                Ident { name: kw::PathRoot, span: source.ident.span },
+                                Ident::new(kw::PathRoot, source.ident.span),
                                 self.r.next_node_id(),
                             ));
                             source.ident.name = crate_name;
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 363a75911ad..74daad08394 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1181,11 +1181,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         } {
             let in_module_is_extern = !in_module.def_id().is_local();
             in_module.for_each_child(self, |this, ident, ns, name_binding| {
-                // avoid non-importable candidates
-                if !name_binding.is_importable()
-                    // FIXME(import_trait_associated_functions): remove this when `import_trait_associated_functions` is stable
-                    || name_binding.is_assoc_const_or_fn()
-                        && !this.tcx.features().import_trait_associated_functions()
+                // Avoid non-importable candidates.
+                if name_binding.is_assoc_item()
+                    && !this.tcx.features().import_trait_associated_functions()
                 {
                     return;
                 }
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index e26b300f13e..7fe74378b67 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -781,22 +781,6 @@ pub(crate) struct CannotGlobImportAllCrates {
     pub(crate) span: Span,
 }
 
-#[derive(Diagnostic)]
-#[diag(resolve_items_in_traits_are_not_importable)]
-pub(crate) struct ItemsInTraitsAreNotImportable {
-    #[primary_span]
-    pub(crate) span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(resolve_is_not_directly_importable, code = E0253)]
-pub(crate) struct IsNotDirectlyImportable {
-    #[primary_span]
-    #[label]
-    pub(crate) span: Span,
-    pub(crate) target: Ident,
-}
-
 #[derive(Subdiagnostic)]
 #[suggestion(
     resolve_unexpected_res_change_ty_to_const_param_sugg,
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 762e08b2be5..816efd0d5fa 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -30,8 +30,7 @@ use crate::diagnostics::{DiagMode, Suggestion, import_candidates};
 use crate::errors::{
     CannotBeReexportedCratePublic, CannotBeReexportedCratePublicNS, CannotBeReexportedPrivate,
     CannotBeReexportedPrivateNS, CannotDetermineImportResolution, CannotGlobImportAllCrates,
-    ConsiderAddingMacroExport, ConsiderMarkingAsPub, IsNotDirectlyImportable,
-    ItemsInTraitsAreNotImportable,
+    ConsiderAddingMacroExport, ConsiderMarkingAsPub,
 };
 use crate::{
     AmbiguityError, AmbiguityKind, BindingKey, Finalize, ImportSuggestion, Module,
@@ -835,11 +834,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
 
                 let parent = import.parent_scope.module;
                 match source_bindings[ns].get() {
-                    Err(Undetermined) => indeterminate_count += 1,
-                    // Don't update the resolution, because it was never added.
-                    Err(Determined) if target.name == kw::Underscore => {}
-                    Ok(binding) if binding.is_importable() => {
-                        if binding.is_assoc_const_or_fn()
+                    Ok(binding) => {
+                        if binding.is_assoc_item()
                             && !this.tcx.features().import_trait_associated_functions()
                         {
                             feature_err(
@@ -850,21 +846,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                             )
                             .emit();
                         }
+
                         let imported_binding = this.import(binding, import);
                         target_bindings[ns].set(Some(imported_binding));
                         this.define(parent, target, ns, imported_binding);
                     }
-                    source_binding @ (Ok(..) | Err(Determined)) => {
-                        if source_binding.is_ok() {
-                            this.dcx()
-                                .create_err(IsNotDirectlyImportable { span: import.span, target })
-                                .emit();
+                    Err(Determined) => {
+                        // Don't update the resolution for underscores, because it was never added.
+                        if target.name != kw::Underscore {
+                            let key = BindingKey::new(target, ns);
+                            this.update_resolution(parent, key, false, |_, resolution| {
+                                resolution.single_imports.swap_remove(&import);
+                            });
                         }
-                        let key = BindingKey::new(target, ns);
-                        this.update_resolution(parent, key, false, |_, resolution| {
-                            resolution.single_imports.swap_remove(&import);
-                        });
                     }
+                    Err(Undetermined) => indeterminate_count += 1,
                 }
             }
         });
@@ -1428,10 +1424,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             return;
         };
 
-        if module.is_trait() {
-            self.dcx().emit_err(ItemsInTraitsAreNotImportable { span: import.span });
-            return;
-        } else if module == import.parent_scope.module {
+        if module.is_trait() && !self.tcx.features().import_trait_associated_functions() {
+            feature_err(
+                self.tcx.sess,
+                sym::import_trait_associated_functions,
+                import.span,
+                "`use` associated items of traits is unstable",
+            )
+            .emit();
+        }
+
+        if module == import.parent_scope.module {
             return;
         } else if is_prelude {
             self.prelude = Some(module);
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index d2da3ac7d86..4c47e9ed699 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -56,6 +56,7 @@ use rustc_hir::def::{
     self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS,
 };
 use rustc_hir::def_id::{CRATE_DEF_ID, CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap};
+use rustc_hir::definitions::DisambiguatorState;
 use rustc_hir::{PrimTy, TraitCandidate};
 use rustc_metadata::creader::{CStore, CrateLoader};
 use rustc_middle::metadata::ModChild;
@@ -949,14 +950,8 @@ impl<'ra> NameBindingData<'ra> {
         }
     }
 
-    fn is_importable(&self) -> bool {
-        !matches!(self.res(), Res::Def(DefKind::AssocTy, _))
-    }
-
-    // FIXME(import_trait_associated_functions): associate `const` or `fn` are not importable unless
-    // the feature `import_trait_associated_functions` is enable
-    fn is_assoc_const_or_fn(&self) -> bool {
-        matches!(self.res(), Res::Def(DefKind::AssocConst | DefKind::AssocFn, _))
+    fn is_assoc_item(&self) -> bool {
+        matches!(self.res(), Res::Def(DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy, _))
     }
 
     fn macro_kind(&self) -> Option<MacroKind> {
@@ -1104,7 +1099,7 @@ pub struct Resolver<'ra, 'tcx> {
     underscore_disambiguator: u32,
 
     /// Maps glob imports to the names of items actually imported.
-    glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
+    glob_map: FxIndexMap<LocalDefId, FxIndexSet<Symbol>>,
     glob_error: Option<ErrorGuaranteed>,
     visibilities_for_hashing: Vec<(LocalDefId, ty::Visibility)>,
     used_imports: FxHashSet<NodeId>,
@@ -1185,6 +1180,8 @@ pub struct Resolver<'ra, 'tcx> {
 
     node_id_to_def_id: NodeMap<Feed<'tcx, LocalDefId>>,
 
+    disambiguator: DisambiguatorState,
+
     /// Indices of unnamed struct or variant fields with unresolved attributes.
     placeholder_field_indices: FxHashMap<NodeId, usize>,
     /// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId`
@@ -1348,7 +1345,7 @@ impl<'tcx> Resolver<'_, 'tcx> {
         );
 
         // FIXME: remove `def_span` body, pass in the right spans here and call `tcx.at().create_def()`
-        let feed = self.tcx.create_def(parent, name, def_kind);
+        let feed = self.tcx.create_def(parent, name, def_kind, None, &mut self.disambiguator);
         let def_id = feed.def_id();
 
         // Create the definition.
@@ -1562,6 +1559,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             lint_buffer: LintBuffer::default(),
             next_node_id: CRATE_NODE_ID,
             node_id_to_def_id,
+            disambiguator: DisambiguatorState::new(),
             placeholder_field_indices: Default::default(),
             invocation_parents,
             legacy_const_generic_args: Default::default(),
@@ -1691,6 +1689,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                 .into_items()
                 .map(|(k, f)| (k, f.key()))
                 .collect(),
+            disambiguator: self.disambiguator,
             trait_map: self.trait_map,
             lifetime_elision_allowed: self.lifetime_elision_allowed,
             lint_buffer: Steal::new(self.lint_buffer),
@@ -2158,13 +2157,24 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         ns: Namespace,
         parent_scope: ParentScope<'ra>,
     ) -> Option<Res> {
-        let mut segments =
-            Vec::from_iter(path_str.split("::").map(Ident::from_str).map(Segment::from_ident));
-        if let Some(segment) = segments.first_mut() {
-            if segment.ident.name == kw::Empty {
-                segment.ident.name = kw::PathRoot;
-            }
-        }
+        let segments: Result<Vec<_>, ()> = path_str
+            .split("::")
+            .enumerate()
+            .map(|(i, s)| {
+                let sym = if s.is_empty() {
+                    if i == 0 {
+                        // For a path like `::a::b`, use `kw::PathRoot` as the leading segment.
+                        kw::PathRoot
+                    } else {
+                        return Err(()); // occurs in cases like `String::`
+                    }
+                } else {
+                    Symbol::intern(s)
+                };
+                Ok(Segment::from_ident(Ident::with_dummy_span(sym)))
+            })
+            .collect();
+        let Ok(segments) = segments else { return None };
 
         match self.maybe_resolve_path(&segments, Some(ns), &parent_scope, None) {
             PathResult::Module(ModuleOrUniformRoot::Module(module)) => Some(module.res().unwrap()),
diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
index 4b1b3903e40..47831f2f418 100644
--- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
+++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
@@ -717,12 +717,14 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String {
             hir::definitions::DefPathData::AnonConst => "k",
             hir::definitions::DefPathData::OpaqueTy => "i",
             hir::definitions::DefPathData::SyntheticCoroutineBody => "s",
+            hir::definitions::DefPathData::NestedStatic => "n",
             hir::definitions::DefPathData::CrateRoot
             | hir::definitions::DefPathData::Use
             | hir::definitions::DefPathData::GlobalAsm
             | hir::definitions::DefPathData::MacroNs(..)
+            | hir::definitions::DefPathData::OpaqueLifetime(..)
             | hir::definitions::DefPathData::LifetimeNs(..)
-            | hir::definitions::DefPathData::AnonAssocTy => {
+            | hir::definitions::DefPathData::AnonAssocTy(..) => {
                 bug!("encode_ty_name: unexpected `{:?}`", disambiguated_data.data);
             }
         });
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index e2d36f6a4e2..60e1b465ba9 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -24,7 +24,8 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_span::edition::{DEFAULT_EDITION, EDITION_NAME_LIST, Edition, LATEST_STABLE_EDITION};
 use rustc_span::source_map::FilePathMapping;
 use rustc_span::{
-    FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm, Symbol, sym,
+    FileName, FileNameDisplayPreference, FileNameEmbeddablePreference, RealFileName,
+    SourceFileHashAlgorithm, Symbol, sym,
 };
 use rustc_target::spec::{
     FramePointer, LinkSelfContainedComponents, LinkerFeatures, SplitDebuginfo, Target, TargetTuple,
@@ -1169,6 +1170,10 @@ impl OutputFilenames {
             .unwrap_or_else(|| OutFileName::Real(self.output_path(flavor)))
     }
 
+    pub fn interface_path(&self) -> PathBuf {
+        self.out_directory.join(format!("lib{}.rs", self.crate_stem))
+    }
+
     /// Gets the output path where a compilation artifact of the given type
     /// should be placed on disk.
     fn output_path(&self, flavor: OutputType) -> PathBuf {
@@ -1316,6 +1321,11 @@ fn file_path_mapping(
         } else {
             FileNameDisplayPreference::Local
         },
+        if unstable_opts.remap_path_scope.is_all() {
+            FileNameEmbeddablePreference::RemappedOnly
+        } else {
+            FileNameEmbeddablePreference::LocalAndRemapped
+        },
     )
 }
 
@@ -1452,13 +1462,17 @@ pub enum CrateType {
     Staticlib,
     Cdylib,
     ProcMacro,
+    Sdylib,
 }
 
 impl CrateType {
     pub fn has_metadata(self) -> bool {
         match self {
             CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
-            CrateType::Executable | CrateType::Cdylib | CrateType::Staticlib => false,
+            CrateType::Executable
+            | CrateType::Cdylib
+            | CrateType::Staticlib
+            | CrateType::Sdylib => false,
         }
     }
 }
@@ -2818,6 +2832,7 @@ pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateTy
                 "cdylib" => CrateType::Cdylib,
                 "bin" => CrateType::Executable,
                 "proc-macro" => CrateType::ProcMacro,
+                "sdylib" => CrateType::Sdylib,
                 _ => {
                     return Err(format!(
                         "unknown crate type: `{part}`, expected one of: \
@@ -2915,6 +2930,7 @@ impl fmt::Display for CrateType {
             CrateType::Staticlib => "staticlib".fmt(f),
             CrateType::Cdylib => "cdylib".fmt(f),
             CrateType::ProcMacro => "proc-macro".fmt(f),
+            CrateType::Sdylib => "sdylib".fmt(f),
         }
     }
 }
diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs
index c8a5c22ad12..4cfc745dec2 100644
--- a/compiler/rustc_session/src/cstore.rs
+++ b/compiler/rustc_session/src/cstore.rs
@@ -27,6 +27,7 @@ pub struct CrateSource {
     pub dylib: Option<(PathBuf, PathKind)>,
     pub rlib: Option<(PathBuf, PathKind)>,
     pub rmeta: Option<(PathBuf, PathKind)>,
+    pub sdylib_interface: Option<(PathBuf, PathKind)>,
 }
 
 impl CrateSource {
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 5f4695fb184..b95ebfbe89f 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -2113,6 +2113,8 @@ options! {
         "emit noalias metadata for box (default: yes)"),
     branch_protection: Option<BranchProtection> = (None, parse_branch_protection, [TRACKED],
         "set options for branch target identification and pointer authentication on AArch64"),
+    build_sdylib_interface: bool = (false, parse_bool, [UNTRACKED],
+        "whether the stable interface is being built"),
     cf_protection: CFProtection = (CFProtection::None, parse_cfprotection, [TRACKED],
         "instrument control-flow architecture protection"),
     check_cfg_all_expected: bool = (false, parse_bool, [UNTRACKED],
@@ -2208,7 +2210,7 @@ options! {
     fewer_names: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \
         (default: no)"),
-    fixed_x18: bool = (false, parse_bool, [TRACKED],
+    fixed_x18: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER],
         "make the x18 register reserved on AArch64 (default: no)"),
     flatten_format_args: bool = (true, parse_bool, [TRACKED],
         "flatten nested format_args!() and literals into a simplified format_args!() call \
diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs
index 46dae9144cd..cba70b5bd5d 100644
--- a/compiler/rustc_session/src/output.rs
+++ b/compiler/rustc_session/src/output.rs
@@ -98,7 +98,7 @@ pub fn filename_for_input(
         CrateType::Rlib => {
             OutFileName::Real(outputs.out_directory.join(&format!("lib{libname}.rlib")))
         }
-        CrateType::Cdylib | CrateType::ProcMacro | CrateType::Dylib => {
+        CrateType::Cdylib | CrateType::ProcMacro | CrateType::Dylib | CrateType::Sdylib => {
             let (prefix, suffix) = (&sess.target.dll_prefix, &sess.target.dll_suffix);
             OutFileName::Real(outputs.out_directory.join(&format!("{prefix}{libname}{suffix}")))
         }
@@ -167,6 +167,7 @@ pub const CRATE_TYPES: &[(Symbol, CrateType)] = &[
     (sym::staticlib, CrateType::Staticlib),
     (sym::proc_dash_macro, CrateType::ProcMacro),
     (sym::bin, CrateType::Executable),
+    (sym::sdylib, CrateType::Sdylib),
 ];
 
 pub fn categorize_crate_type(s: Symbol) -> Option<CrateType> {
@@ -187,6 +188,11 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<C
         return vec![CrateType::Executable];
     }
 
+    // Shadow `sdylib` crate type in interface build.
+    if session.opts.unstable_opts.build_sdylib_interface {
+        return vec![CrateType::Rlib];
+    }
+
     // Only check command line flags if present. If no types are specified by
     // command line, then reuse the empty `base` Vec to hold the types that
     // will be found in crate attributes.
diff --git a/compiler/rustc_smir/src/rustc_smir/builder.rs b/compiler/rustc_smir/src/rustc_smir/builder.rs
index 64763b71d30..40e6d21c063 100644
--- a/compiler/rustc_smir/src/rustc_smir/builder.rs
+++ b/compiler/rustc_smir/src/rustc_smir/builder.rs
@@ -22,7 +22,7 @@ impl<'tcx> BodyBuilder<'tcx> {
     pub(crate) fn new(tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>) -> Self {
         let instance = match instance.def {
             // To get the fallback body of an intrinsic, we need to convert it to an item.
-            ty::InstanceKind::Intrinsic(def_id) => ty::Instance::new(def_id, instance.args),
+            ty::InstanceKind::Intrinsic(def_id) => ty::Instance::new_raw(def_id, instance.args),
             _ => instance,
         };
         BodyBuilder { tcx, instance }
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index ab0a802dc7f..b621920d62b 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -41,6 +41,7 @@ use tracing::{debug, trace};
 
 use crate::def_id::{CRATE_DEF_ID, CrateNum, DefId, LOCAL_CRATE, StableCrateId};
 use crate::edition::Edition;
+use crate::source_map::SourceMap;
 use crate::symbol::{Symbol, kw, sym};
 use crate::{DUMMY_SP, HashStableContext, Span, SpanDecoder, SpanEncoder, with_session_globals};
 
@@ -907,6 +908,30 @@ impl SyntaxContext {
     pub fn edition(self) -> Edition {
         HygieneData::with(|data| data.expn_data(data.outer_expn(self)).edition)
     }
+
+    /// Returns whether this context originates in a foreign crate's external macro.
+    ///
+    /// This is used to test whether a lint should not even begin to figure out whether it should
+    /// be reported on the current node.
+    pub fn in_external_macro(self, sm: &SourceMap) -> bool {
+        let expn_data = self.outer_expn_data();
+        match expn_data.kind {
+            ExpnKind::Root
+            | ExpnKind::Desugaring(
+                DesugaringKind::ForLoop
+                | DesugaringKind::WhileLoop
+                | DesugaringKind::OpaqueTy
+                | DesugaringKind::Async
+                | DesugaringKind::Await,
+            ) => false,
+            ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external"
+            ExpnKind::Macro(MacroKind::Bang, _) => {
+                // Dummy span for the `def_site` means it's an external macro.
+                expn_data.def_site.is_dummy() || sm.is_imported(expn_data.def_site)
+            }
+            ExpnKind::Macro { .. } => true, // definitely a plugin
+        }
+    }
 }
 
 impl fmt::Debug for SyntaxContext {
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 9722031f209..61c96e67c17 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -224,7 +224,7 @@ pub fn with_metavar_spans<R>(f: impl FnOnce(&MetavarSpansMap) -> R) -> R {
 
 // FIXME: We should use this enum or something like it to get rid of the
 // use of magic `/rust/1.x/...` paths across the board.
-#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Decodable)]
+#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Decodable, Encodable)]
 pub enum RealFileName {
     LocalPath(PathBuf),
     /// For remapped paths (namely paths into libstd that have been mapped
@@ -250,28 +250,6 @@ impl Hash for RealFileName {
     }
 }
 
-// This is functionally identical to #[derive(Encodable)], with the exception of
-// an added assert statement
-impl<S: Encoder> Encodable<S> for RealFileName {
-    fn encode(&self, encoder: &mut S) {
-        match *self {
-            RealFileName::LocalPath(ref local_path) => {
-                encoder.emit_u8(0);
-                local_path.encode(encoder);
-            }
-
-            RealFileName::Remapped { ref local_path, ref virtual_name } => {
-                encoder.emit_u8(1);
-                // For privacy and build reproducibility, we must not embed host-dependant path
-                // in artifacts if they have been remapped by --remap-path-prefix
-                assert!(local_path.is_none());
-                local_path.encode(encoder);
-                virtual_name.encode(encoder);
-            }
-        }
-    }
-}
-
 impl RealFileName {
     /// Returns the path suitable for reading from the file system on the local host,
     /// if this information exists.
@@ -369,6 +347,16 @@ impl From<PathBuf> for FileName {
 }
 
 #[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
+pub enum FileNameEmbeddablePreference {
+    /// If a remapped path is available, only embed the `virtual_path` and omit the `local_path`.
+    ///
+    /// Otherwise embed the local-path into the `virtual_path`.
+    RemappedOnly,
+    /// Embed the original path as well as its remapped `virtual_path` component if available.
+    LocalAndRemapped,
+}
+
+#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
 pub enum FileNameDisplayPreference {
     /// Display the path after the application of rewrite rules provided via `--remap-path-prefix`.
     /// This is appropriate for paths that get embedded into files produced by the compiler.
@@ -606,28 +594,13 @@ impl Span {
         !self.is_dummy() && sm.is_span_accessible(self)
     }
 
-    /// Returns whether `span` originates in a foreign crate's external macro.
+    /// Returns whether this span originates in a foreign crate's external macro.
     ///
     /// This is used to test whether a lint should not even begin to figure out whether it should
     /// be reported on the current node.
+    #[inline]
     pub fn in_external_macro(self, sm: &SourceMap) -> bool {
-        let expn_data = self.ctxt().outer_expn_data();
-        match expn_data.kind {
-            ExpnKind::Root
-            | ExpnKind::Desugaring(
-                DesugaringKind::ForLoop
-                | DesugaringKind::WhileLoop
-                | DesugaringKind::OpaqueTy
-                | DesugaringKind::Async
-                | DesugaringKind::Await,
-            ) => false,
-            ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external"
-            ExpnKind::Macro(MacroKind::Bang, _) => {
-                // Dummy span for the `def_site` means it's an external macro.
-                expn_data.def_site.is_dummy() || sm.is_imported(expn_data.def_site)
-            }
-            ExpnKind::Macro { .. } => true, // definitely a plugin
-        }
+        self.ctxt().in_external_macro(sm)
     }
 
     /// Returns `true` if `span` originates in a derive-macro's expansion.
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index 0273bb040f4..8a3644163ca 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -1108,18 +1108,28 @@ pub fn get_source_map() -> Option<Arc<SourceMap>> {
 pub struct FilePathMapping {
     mapping: Vec<(PathBuf, PathBuf)>,
     filename_display_for_diagnostics: FileNameDisplayPreference,
+    filename_embeddable_preference: FileNameEmbeddablePreference,
 }
 
 impl FilePathMapping {
     pub fn empty() -> FilePathMapping {
-        FilePathMapping::new(Vec::new(), FileNameDisplayPreference::Local)
+        FilePathMapping::new(
+            Vec::new(),
+            FileNameDisplayPreference::Local,
+            FileNameEmbeddablePreference::RemappedOnly,
+        )
     }
 
     pub fn new(
         mapping: Vec<(PathBuf, PathBuf)>,
         filename_display_for_diagnostics: FileNameDisplayPreference,
+        filename_embeddable_preference: FileNameEmbeddablePreference,
     ) -> FilePathMapping {
-        FilePathMapping { mapping, filename_display_for_diagnostics }
+        FilePathMapping {
+            mapping,
+            filename_display_for_diagnostics,
+            filename_embeddable_preference,
+        }
     }
 
     /// Applies any path prefix substitution as defined by the mapping.
@@ -1217,11 +1227,13 @@ impl FilePathMapping {
     ) -> RealFileName {
         match file_path {
             // Anything that's already remapped we don't modify, except for erasing
-            // the `local_path` portion.
-            RealFileName::Remapped { local_path: _, virtual_name } => {
+            // the `local_path` portion (if desired).
+            RealFileName::Remapped { local_path, virtual_name } => {
                 RealFileName::Remapped {
-                    // We do not want any local path to be exported into metadata
-                    local_path: None,
+                    local_path: match self.filename_embeddable_preference {
+                        FileNameEmbeddablePreference::RemappedOnly => None,
+                        FileNameEmbeddablePreference::LocalAndRemapped => local_path,
+                    },
                     // We use the remapped name verbatim, even if it looks like a relative
                     // path. The assumption is that the user doesn't want us to further
                     // process paths that have gone through remapping.
@@ -1231,12 +1243,18 @@ impl FilePathMapping {
 
             RealFileName::LocalPath(unmapped_file_path) => {
                 // If no remapping has been applied yet, try to do so
-                let (new_path, was_remapped) = self.map_prefix(unmapped_file_path);
+                let (new_path, was_remapped) = self.map_prefix(&unmapped_file_path);
                 if was_remapped {
                     // It was remapped, so don't modify further
                     return RealFileName::Remapped {
-                        local_path: None,
                         virtual_name: new_path.into_owned(),
+                        // But still provide the local path if desired
+                        local_path: match self.filename_embeddable_preference {
+                            FileNameEmbeddablePreference::RemappedOnly => None,
+                            FileNameEmbeddablePreference::LocalAndRemapped => {
+                                Some(unmapped_file_path)
+                            }
+                        },
                     };
                 }
 
@@ -1252,17 +1270,23 @@ impl FilePathMapping {
 
                 match working_directory {
                     RealFileName::LocalPath(unmapped_working_dir_abs) => {
-                        let file_path_abs = unmapped_working_dir_abs.join(unmapped_file_path_rel);
+                        let unmapped_file_path_abs =
+                            unmapped_working_dir_abs.join(unmapped_file_path_rel);
 
                         // Although neither `working_directory` nor the file name were subject
                         // to path remapping, the concatenation between the two may be. Hence
                         // we need to do a remapping here.
-                        let (file_path_abs, was_remapped) = self.map_prefix(file_path_abs);
+                        let (file_path_abs, was_remapped) =
+                            self.map_prefix(&unmapped_file_path_abs);
                         if was_remapped {
                             RealFileName::Remapped {
-                                // Erase the actual path
-                                local_path: None,
                                 virtual_name: file_path_abs.into_owned(),
+                                local_path: match self.filename_embeddable_preference {
+                                    FileNameEmbeddablePreference::RemappedOnly => None,
+                                    FileNameEmbeddablePreference::LocalAndRemapped => {
+                                        Some(unmapped_file_path_abs)
+                                    }
+                                },
                             }
                         } else {
                             // No kind of remapping applied to this path, so
@@ -1271,15 +1295,20 @@ impl FilePathMapping {
                         }
                     }
                     RealFileName::Remapped {
-                        local_path: _,
+                        local_path,
                         virtual_name: remapped_working_dir_abs,
                     } => {
                         // If working_directory has been remapped, then we emit
                         // Remapped variant as the expanded path won't be valid
                         RealFileName::Remapped {
-                            local_path: None,
                             virtual_name: Path::new(remapped_working_dir_abs)
-                                .join(unmapped_file_path_rel),
+                                .join(&unmapped_file_path_rel),
+                            local_path: match self.filename_embeddable_preference {
+                                FileNameEmbeddablePreference::RemappedOnly => None,
+                                FileNameEmbeddablePreference::LocalAndRemapped => local_path
+                                    .as_ref()
+                                    .map(|local_path| local_path.join(unmapped_file_path_rel)),
+                            },
                         }
                     }
                 }
@@ -1287,27 +1316,6 @@ impl FilePathMapping {
         }
     }
 
-    /// Expand a relative path to an absolute path **without** remapping taken into account.
-    ///
-    /// The resulting `RealFileName` will have its `virtual_path` portion erased if
-    /// possible (i.e. if there's also a remapped path).
-    pub fn to_local_embeddable_absolute_path(
-        &self,
-        file_path: RealFileName,
-        working_directory: &RealFileName,
-    ) -> RealFileName {
-        let file_path = file_path.local_path_if_available();
-        if file_path.is_absolute() {
-            // No remapping has applied to this path and it is absolute,
-            // so the working directory cannot influence it either, so
-            // we are done.
-            return RealFileName::LocalPath(file_path.to_path_buf());
-        }
-        debug_assert!(file_path.is_relative());
-        let working_directory = working_directory.local_path_if_available();
-        RealFileName::LocalPath(Path::new(working_directory).join(file_path))
-    }
-
     /// Attempts to (heuristically) reverse a prefix mapping.
     ///
     /// Returns [`Some`] if there is exactly one mapping where the "to" part is
diff --git a/compiler/rustc_span/src/source_map/tests.rs b/compiler/rustc_span/src/source_map/tests.rs
index 957f55e3913..589c2a36354 100644
--- a/compiler/rustc_span/src/source_map/tests.rs
+++ b/compiler/rustc_span/src/source_map/tests.rs
@@ -305,6 +305,7 @@ fn path_prefix_remapping() {
         let mapping = &FilePathMapping::new(
             vec![(path("abc/def"), path("foo"))],
             FileNameDisplayPreference::Remapped,
+            FileNameEmbeddablePreference::RemappedOnly,
         );
 
         assert_eq!(map_path_prefix(mapping, "abc/def/src/main.rs"), path_str("foo/src/main.rs"));
@@ -316,6 +317,7 @@ fn path_prefix_remapping() {
         let mapping = &FilePathMapping::new(
             vec![(path("abc/def"), path("/foo"))],
             FileNameDisplayPreference::Remapped,
+            FileNameEmbeddablePreference::RemappedOnly,
         );
 
         assert_eq!(map_path_prefix(mapping, "abc/def/src/main.rs"), path_str("/foo/src/main.rs"));
@@ -327,6 +329,7 @@ fn path_prefix_remapping() {
         let mapping = &FilePathMapping::new(
             vec![(path("/abc/def"), path("foo"))],
             FileNameDisplayPreference::Remapped,
+            FileNameEmbeddablePreference::RemappedOnly,
         );
 
         assert_eq!(map_path_prefix(mapping, "/abc/def/src/main.rs"), path_str("foo/src/main.rs"));
@@ -338,6 +341,7 @@ fn path_prefix_remapping() {
         let mapping = &FilePathMapping::new(
             vec![(path("/abc/def"), path("/foo"))],
             FileNameDisplayPreference::Remapped,
+            FileNameEmbeddablePreference::RemappedOnly,
         );
 
         assert_eq!(map_path_prefix(mapping, "/abc/def/src/main.rs"), path_str("/foo/src/main.rs"));
@@ -351,6 +355,7 @@ fn path_prefix_remapping_expand_to_absolute() {
     let mapping = &FilePathMapping::new(
         vec![(path("/foo"), path("FOO")), (path("/bar"), path("BAR"))],
         FileNameDisplayPreference::Remapped,
+        FileNameEmbeddablePreference::RemappedOnly,
     );
     let working_directory = path("/foo");
     let working_directory = RealFileName::Remapped {
@@ -449,12 +454,78 @@ fn path_prefix_remapping_expand_to_absolute() {
 }
 
 #[test]
+fn path_prefix_remapping_expand_to_absolute_and_local() {
+    // "virtual" working directory is relative path
+    let mapping = &FilePathMapping::new(
+        vec![(path("/foo"), path("FOO")), (path("/bar"), path("BAR"))],
+        FileNameDisplayPreference::Remapped,
+        FileNameEmbeddablePreference::LocalAndRemapped,
+    );
+    let working_directory = path("/foo");
+    let working_directory = RealFileName::Remapped {
+        local_path: Some(working_directory.clone()),
+        virtual_name: mapping.map_prefix(working_directory).0.into_owned(),
+    };
+
+    assert_eq!(working_directory.remapped_path_if_available(), path("FOO"));
+
+    // Unmapped absolute path
+    assert_eq!(
+        mapping.to_embeddable_absolute_path(
+            RealFileName::LocalPath(path("/foo/src/main.rs")),
+            &working_directory
+        ),
+        RealFileName::Remapped {
+            local_path: Some(path("/foo/src/main.rs")),
+            virtual_name: path("FOO/src/main.rs")
+        }
+    );
+
+    // Unmapped absolute path with unrelated working directory
+    assert_eq!(
+        mapping.to_embeddable_absolute_path(
+            RealFileName::LocalPath(path("/bar/src/main.rs")),
+            &working_directory
+        ),
+        RealFileName::Remapped {
+            local_path: Some(path("/bar/src/main.rs")),
+            virtual_name: path("BAR/src/main.rs")
+        }
+    );
+
+    // Already remapped absolute path, with unrelated working directory
+    assert_eq!(
+        mapping.to_embeddable_absolute_path(
+            RealFileName::Remapped {
+                local_path: Some(path("/bar/src/main.rs")),
+                virtual_name: path("BAR/src/main.rs"),
+            },
+            &working_directory
+        ),
+        RealFileName::Remapped {
+            local_path: Some(path("/bar/src/main.rs")),
+            virtual_name: path("BAR/src/main.rs")
+        }
+    );
+
+    // Already remapped relative path
+    assert_eq!(
+        mapping.to_embeddable_absolute_path(
+            RealFileName::Remapped { local_path: None, virtual_name: path("XYZ/src/main.rs") },
+            &working_directory
+        ),
+        RealFileName::Remapped { local_path: None, virtual_name: path("XYZ/src/main.rs") }
+    );
+}
+
+#[test]
 fn path_prefix_remapping_reverse() {
     // Ignores options without alphanumeric chars.
     {
         let mapping = &FilePathMapping::new(
             vec![(path("abc"), path("/")), (path("def"), path("."))],
             FileNameDisplayPreference::Remapped,
+            FileNameEmbeddablePreference::RemappedOnly,
         );
 
         assert_eq!(reverse_map_prefix(mapping, "/hello.rs"), None);
@@ -466,6 +537,7 @@ fn path_prefix_remapping_reverse() {
         let mapping = &FilePathMapping::new(
             vec![(path("abc"), path("/redacted")), (path("def"), path("/redacted"))],
             FileNameDisplayPreference::Remapped,
+            FileNameEmbeddablePreference::RemappedOnly,
         );
 
         assert_eq!(reverse_map_prefix(mapping, "/redacted/hello.rs"), None);
@@ -476,6 +548,7 @@ fn path_prefix_remapping_reverse() {
         let mapping = &FilePathMapping::new(
             vec![(path("abc"), path("/redacted")), (path("def/ghi"), path("/fake/dir"))],
             FileNameDisplayPreference::Remapped,
+            FileNameEmbeddablePreference::RemappedOnly,
         );
 
         assert_eq!(
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 7a1fb36324b..b6cb6113f9f 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -459,6 +459,7 @@ symbols! {
         anonymous_lifetime_in_impl_trait,
         any,
         append_const_msg,
+        apx_target_feature,
         arbitrary_enum_discriminant,
         arbitrary_self_types,
         arbitrary_self_types_pointers,
@@ -531,6 +532,7 @@ symbols! {
         autodiff,
         automatically_derived,
         avx,
+        avx10_target_feature,
         avx512_target_feature,
         avx512bw,
         avx512f,
@@ -913,6 +915,7 @@ symbols! {
         explicit_generic_args_with_impl_trait,
         explicit_tail_calls,
         export_name,
+        export_stable,
         expr,
         expr_2021,
         expr_fragment_specifier_2024,
@@ -1047,6 +1050,7 @@ symbols! {
         from_u16,
         from_usize,
         from_yeet,
+        frontmatter,
         fs_create_dir,
         fsub_algebraic,
         fsub_fast,
@@ -1877,6 +1881,7 @@ symbols! {
         saturating_add,
         saturating_div,
         saturating_sub,
+        sdylib,
         search_unbox,
         select_unpredictable,
         self_in_typedefs,
@@ -2094,7 +2099,6 @@ symbols! {
         three_way_compare,
         thumb2,
         thumb_mode: "thumb-mode",
-        time,
         tmm_reg,
         to_owned_method,
         to_string,
@@ -2337,6 +2341,9 @@ pub const STDLIB_STABLE_CRATES: &[Symbol] = &[sym::std, sym::core, sym::alloc, s
 
 #[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
 pub struct Ident {
+    // `name` should never be the empty symbol. If you are considering that,
+    // you are probably conflating "empty identifer with "no identifier" and
+    // you should use `Option<Ident>` instead.
     pub name: Symbol,
     pub span: Span,
 }
@@ -2344,28 +2351,21 @@ pub struct Ident {
 impl Ident {
     #[inline]
     /// Constructs a new identifier from a symbol and a span.
-    pub const fn new(name: Symbol, span: Span) -> Ident {
+    pub fn new(name: Symbol, span: Span) -> Ident {
+        assert_ne!(name, kw::Empty);
         Ident { name, span }
     }
 
     /// Constructs a new identifier with a dummy span.
     #[inline]
-    pub const fn with_dummy_span(name: Symbol) -> Ident {
+    pub fn with_dummy_span(name: Symbol) -> Ident {
         Ident::new(name, DUMMY_SP)
     }
 
-    /// This is best avoided, because it blurs the lines between "empty
-    /// identifier" and "no identifier". Using `Option<Ident>` is preferable,
-    /// where possible, because that is unambiguous.
-    #[inline]
-    pub fn empty() -> Ident {
-        Ident::with_dummy_span(kw::Empty)
-    }
-
     // For dummy identifiers that are never used and absolutely must be
-    // present, it's better to use `Ident::dummy` than `Ident::Empty`, because
-    // it's clearer that it's intended as a dummy value, and more likely to be
-    // detected if it accidentally does get used.
+    // present. Note that this does *not* use the empty symbol; `sym::dummy`
+    // makes it clear that it's intended as a dummy value, and is more likely
+    // to be detected if it accidentally does get used.
     #[inline]
     pub fn dummy() -> Ident {
         Ident::with_dummy_span(sym::dummy)
diff --git a/compiler/rustc_symbol_mangling/src/export.rs b/compiler/rustc_symbol_mangling/src/export.rs
new file mode 100644
index 00000000000..770401fc8cf
--- /dev/null
+++ b/compiler/rustc_symbol_mangling/src/export.rs
@@ -0,0 +1,181 @@
+use std::assert_matches::debug_assert_matches;
+
+use rustc_abi::IntegerType;
+use rustc_data_structures::stable_hasher::StableHasher;
+use rustc_hashes::Hash128;
+use rustc_hir::def::DefKind;
+use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
+use rustc_span::symbol::{Symbol, sym};
+
+trait AbiHashStable<'tcx> {
+    fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher);
+}
+macro_rules! default_hash_impl {
+    ($($t:ty,)+) => {
+        $(impl<'tcx> AbiHashStable<'tcx> for $t {
+            #[inline]
+            fn abi_hash(&self, _tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
+                ::std::hash::Hash::hash(self, hasher);
+            }
+        })*
+    };
+}
+
+default_hash_impl! { i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, }
+
+impl<'tcx> AbiHashStable<'tcx> for bool {
+    #[inline]
+    fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
+        (if *self { 1u8 } else { 0u8 }).abi_hash(tcx, hasher);
+    }
+}
+
+impl<'tcx> AbiHashStable<'tcx> for str {
+    #[inline]
+    fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
+        self.as_bytes().abi_hash(tcx, hasher);
+    }
+}
+
+impl<'tcx> AbiHashStable<'tcx> for String {
+    #[inline]
+    fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
+        self[..].abi_hash(tcx, hasher);
+    }
+}
+
+impl<'tcx> AbiHashStable<'tcx> for Symbol {
+    #[inline]
+    fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
+        self.as_str().abi_hash(tcx, hasher);
+    }
+}
+
+impl<'tcx, T: AbiHashStable<'tcx>> AbiHashStable<'tcx> for [T] {
+    fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
+        self.len().abi_hash(tcx, hasher);
+        for item in self {
+            item.abi_hash(tcx, hasher);
+        }
+    }
+}
+
+impl<'tcx> AbiHashStable<'tcx> for Ty<'tcx> {
+    fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
+        match self.kind() {
+            ty::Bool => sym::bool.abi_hash(tcx, hasher),
+            ty::Char => sym::char.abi_hash(tcx, hasher),
+            ty::Int(int_ty) => int_ty.name_str().abi_hash(tcx, hasher),
+            ty::Uint(uint_ty) => uint_ty.name_str().abi_hash(tcx, hasher),
+            ty::Float(float_ty) => float_ty.name_str().abi_hash(tcx, hasher),
+
+            ty::Adt(adt_def, args) => {
+                adt_def.is_struct().abi_hash(tcx, hasher);
+                adt_def.is_enum().abi_hash(tcx, hasher);
+                adt_def.is_union().abi_hash(tcx, hasher);
+
+                if let Some(align) = adt_def.repr().align {
+                    align.bits().abi_hash(tcx, hasher);
+                }
+
+                if let Some(integer) = adt_def.repr().int {
+                    match integer {
+                        IntegerType::Pointer(sign) => sign.abi_hash(tcx, hasher),
+                        IntegerType::Fixed(integer, sign) => {
+                            integer.int_ty_str().abi_hash(tcx, hasher);
+                            sign.abi_hash(tcx, hasher);
+                        }
+                    }
+                }
+
+                if let Some(pack) = adt_def.repr().pack {
+                    pack.bits().abi_hash(tcx, hasher);
+                }
+
+                adt_def.repr().c().abi_hash(tcx, hasher);
+
+                for variant in adt_def.variants() {
+                    variant.name.abi_hash(tcx, hasher);
+                    for field in &variant.fields {
+                        field.name.abi_hash(tcx, hasher);
+                        let field_ty = tcx.type_of(field.did).instantiate_identity();
+                        field_ty.abi_hash(tcx, hasher);
+                    }
+                }
+                args.abi_hash(tcx, hasher);
+            }
+
+            ty::Tuple(args) if args.len() == 0 => {}
+
+            // FIXME: Not yet supported.
+            ty::Foreign(_)
+            | ty::Ref(_, _, _)
+            | ty::Str
+            | ty::Array(_, _)
+            | ty::Pat(_, _)
+            | ty::Slice(_)
+            | ty::RawPtr(_, _)
+            | ty::FnDef(_, _)
+            | ty::FnPtr(_, _)
+            | ty::Dynamic(_, _, _)
+            | ty::Closure(_, _)
+            | ty::CoroutineClosure(_, _)
+            | ty::Coroutine(_, _)
+            | ty::CoroutineWitness(_, _)
+            | ty::Never
+            | ty::Tuple(_)
+            | ty::Alias(_, _)
+            | ty::Param(_)
+            | ty::Bound(_, _)
+            | ty::Placeholder(_)
+            | ty::Infer(_)
+            | ty::UnsafeBinder(_) => unreachable!(),
+
+            ty::Error(_) => {}
+        }
+    }
+}
+
+impl<'tcx> AbiHashStable<'tcx> for ty::FnSig<'tcx> {
+    fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
+        for ty in self.inputs_and_output {
+            ty.abi_hash(tcx, hasher);
+        }
+        self.safety.is_safe().abi_hash(tcx, hasher);
+    }
+}
+
+impl<'tcx> AbiHashStable<'tcx> for ty::GenericArg<'tcx> {
+    fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
+        self.unpack().abi_hash(tcx, hasher);
+    }
+}
+
+impl<'tcx> AbiHashStable<'tcx> for ty::GenericArgKind<'tcx> {
+    fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
+        match self {
+            ty::GenericArgKind::Type(t) => t.abi_hash(tcx, hasher),
+            ty::GenericArgKind::Lifetime(_) | ty::GenericArgKind::Const(_) => unimplemented!(),
+        }
+    }
+}
+
+pub(crate) fn compute_hash_of_export_fn<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    instance: Instance<'tcx>,
+) -> String {
+    let def_id = instance.def_id();
+    debug_assert_matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn);
+
+    let args = instance.args;
+    let sig_ty = tcx.fn_sig(def_id).instantiate(tcx, args);
+    let sig_ty = tcx.instantiate_bound_regions_with_erased(sig_ty);
+
+    let hash = {
+        let mut hasher = StableHasher::new();
+        sig_ty.abi_hash(tcx, &mut hasher);
+        hasher.finish::<Hash128>()
+    };
+
+    hash.as_u128().to_string()
+}
diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs
index ca8918e06aa..a51d7da878a 100644
--- a/compiler/rustc_symbol_mangling/src/lib.rs
+++ b/compiler/rustc_symbol_mangling/src/lib.rs
@@ -92,6 +92,7 @@
 #![cfg_attr(bootstrap, feature(let_chains))]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
+#![feature(assert_matches)]
 #![feature(rustdoc_internals)]
 // tidy-alphabetical-end
 
@@ -104,6 +105,7 @@ use rustc_middle::ty::{self, Instance, TyCtxt};
 use rustc_session::config::SymbolManglingVersion;
 use tracing::debug;
 
+mod export;
 mod hashed;
 mod legacy;
 mod v0;
@@ -296,12 +298,21 @@ fn compute_symbol_name<'tcx>(
         tcx.symbol_mangling_version(mangling_version_crate)
     };
 
-    let symbol = match mangling_version {
-        SymbolManglingVersion::Legacy => legacy::mangle(tcx, instance, instantiating_crate),
-        SymbolManglingVersion::V0 => v0::mangle(tcx, instance, instantiating_crate),
-        SymbolManglingVersion::Hashed => hashed::mangle(tcx, instance, instantiating_crate, || {
-            v0::mangle(tcx, instance, instantiating_crate)
-        }),
+    let symbol = match tcx.is_exportable(def_id) {
+        true => format!(
+            "{}.{}",
+            v0::mangle(tcx, instance, instantiating_crate, true),
+            export::compute_hash_of_export_fn(tcx, instance)
+        ),
+        false => match mangling_version {
+            SymbolManglingVersion::Legacy => legacy::mangle(tcx, instance, instantiating_crate),
+            SymbolManglingVersion::V0 => v0::mangle(tcx, instance, instantiating_crate, false),
+            SymbolManglingVersion::Hashed => {
+                hashed::mangle(tcx, instance, instantiating_crate, || {
+                    v0::mangle(tcx, instance, instantiating_crate, false)
+                })
+            }
+        },
     };
 
     debug_assert!(
diff --git a/compiler/rustc_symbol_mangling/src/test.rs b/compiler/rustc_symbol_mangling/src/test.rs
index ddeeadff13d..0c6d1495e39 100644
--- a/compiler/rustc_symbol_mangling/src/test.rs
+++ b/compiler/rustc_symbol_mangling/src/test.rs
@@ -56,7 +56,7 @@ impl SymbolNamesTest<'_> {
         // some subset.
         for attr in tcx.get_attrs(def_id, SYMBOL_NAME) {
             let def_id = def_id.to_def_id();
-            let instance = Instance::new(
+            let instance = Instance::new_raw(
                 def_id,
                 tcx.erase_regions(GenericArgs::identity_for_item(tcx, def_id)),
             );
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index f8f2714ee42..4a99ce09b39 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -26,6 +26,7 @@ pub(super) fn mangle<'tcx>(
     tcx: TyCtxt<'tcx>,
     instance: Instance<'tcx>,
     instantiating_crate: Option<CrateNum>,
+    is_exportable: bool,
 ) -> String {
     let def_id = instance.def_id();
     // FIXME(eddyb) this should ideally not be needed.
@@ -35,6 +36,7 @@ pub(super) fn mangle<'tcx>(
     let mut cx: SymbolMangler<'_> = SymbolMangler {
         tcx,
         start_offset: prefix.len(),
+        is_exportable,
         paths: FxHashMap::default(),
         types: FxHashMap::default(),
         consts: FxHashMap::default(),
@@ -93,6 +95,7 @@ pub fn mangle_internal_symbol<'tcx>(tcx: TyCtxt<'tcx>, item_name: &str) -> Strin
     let mut cx: SymbolMangler<'_> = SymbolMangler {
         tcx,
         start_offset: prefix.len(),
+        is_exportable: false,
         paths: FxHashMap::default(),
         types: FxHashMap::default(),
         consts: FxHashMap::default(),
@@ -135,6 +138,7 @@ pub(super) fn mangle_typeid_for_trait_ref<'tcx>(
     let mut cx = SymbolMangler {
         tcx,
         start_offset: 0,
+        is_exportable: false,
         paths: FxHashMap::default(),
         types: FxHashMap::default(),
         consts: FxHashMap::default(),
@@ -163,6 +167,7 @@ struct SymbolMangler<'tcx> {
     tcx: TyCtxt<'tcx>,
     binders: Vec<BinderLevel>,
     out: String,
+    is_exportable: bool,
 
     /// The length of the prefix in `out` (e.g. 2 for `_R`).
     start_offset: usize,
@@ -376,7 +381,14 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
                 args,
             )?;
         } else {
-            self.push_disambiguator(key.disambiguated_data.disambiguator as u64);
+            let exported_impl_order = self.tcx.stable_order_of_exportable_impls(impl_def_id.krate);
+            let disambiguator = match self.is_exportable {
+                true => exported_impl_order[&impl_def_id] as u64,
+                false => {
+                    exported_impl_order.len() as u64 + key.disambiguated_data.disambiguator as u64
+                }
+            };
+            self.push_disambiguator(disambiguator);
             self.print_def_path(parent_def_id, &[])?;
         }
 
@@ -818,8 +830,10 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
 
     fn path_crate(&mut self, cnum: CrateNum) -> Result<(), PrintError> {
         self.push("C");
-        let stable_crate_id = self.tcx.def_path_hash(cnum.as_def_id()).stable_crate_id();
-        self.push_disambiguator(stable_crate_id.as_u64());
+        if !self.is_exportable {
+            let stable_crate_id = self.tcx.def_path_hash(cnum.as_def_id()).stable_crate_id();
+            self.push_disambiguator(stable_crate_id.as_u64());
+        }
         let name = self.tcx.crate_name(cnum);
         self.push_ident(name.as_str());
         Ok(())
@@ -867,6 +881,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
             DefPathData::AnonConst => 'k',
             DefPathData::OpaqueTy => 'i',
             DefPathData::SyntheticCoroutineBody => 's',
+            DefPathData::NestedStatic => 'n',
 
             // These should never show up as `path_append` arguments.
             DefPathData::CrateRoot
@@ -875,7 +890,8 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
             | DefPathData::Impl
             | DefPathData::MacroNs(_)
             | DefPathData::LifetimeNs(_)
-            | DefPathData::AnonAssocTy => {
+            | DefPathData::OpaqueLifetime(_)
+            | DefPathData::AnonAssocTy(..) => {
                 bug!("symbol_names: unexpected DefPathData: {:?}", disambiguated_data.data)
             }
         };
diff --git a/compiler/rustc_target/src/spec/base/msvc.rs b/compiler/rustc_target/src/spec/base/msvc.rs
index 486d7158723..bd59678d236 100644
--- a/compiler/rustc_target/src/spec/base/msvc.rs
+++ b/compiler/rustc_target/src/spec/base/msvc.rs
@@ -5,7 +5,19 @@ use crate::spec::{BinaryFormat, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo
 pub(crate) fn opts() -> TargetOptions {
     // Suppress the verbose logo and authorship debugging output, which would needlessly
     // clog any log files.
-    let pre_link_args = TargetOptions::link_args(LinkerFlavor::Msvc(Lld::No), &["/NOLOGO"]);
+    let pre_link_args = TargetOptions::link_args(
+        LinkerFlavor::Msvc(Lld::No),
+        &[
+            "/NOLOGO",
+            // "Symbol is marked as dllimport, but defined in an object file"
+            // Harmless warning that flags a potential performance improvement: marking a symbol as
+            // dllimport indirects usage via the `__imp_` symbol, which isn't required if the symbol
+            // is in the current binary. This is tripped by __rust_no_alloc_shim_is_unstable as it
+            // is generated by the compiler, but marked as a foreign item (hence the dllimport) in
+            // the standard library.
+            "/IGNORE:4286",
+        ],
+    );
 
     TargetOptions {
         linker_flavor: LinkerFlavor::Msvc(Lld::No),
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 37ea0d6e7b5..303be54a6d7 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -3567,7 +3567,19 @@ impl Target {
             "x86" => (Architecture::I386, None),
             "s390x" => (Architecture::S390x, None),
             "mips" | "mips32r6" => (Architecture::Mips, None),
-            "mips64" | "mips64r6" => (Architecture::Mips64, None),
+            "mips64" | "mips64r6" => (
+                // While there are currently no builtin targets
+                // using the N32 ABI, it is possible to specify
+                // it using a custom target specification. N32
+                // is an ILP32 ABI like the Aarch64_Ilp32
+                // and X86_64_X32 cases above and below this one.
+                if self.options.llvm_abiname.as_ref() == "n32" {
+                    Architecture::Mips64_N32
+                } else {
+                    Architecture::Mips64
+                },
+                None,
+            ),
             "x86_64" => (
                 if self.pointer_width == 32 {
                     Architecture::X86_64_X32
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs
index 98d78520c98..c5704c57448 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs
@@ -1,10 +1,21 @@
-use crate::spec::{Target, TargetMetadata, base};
+use crate::spec::{FramePointer, LinkerFlavor, Lld, Target, TargetMetadata, base};
 
 pub(crate) fn target() -> Target {
     let mut base = base::windows_msvc::opts();
     base.max_atomic_width = Some(128);
     base.features = "+v8a,+neon,+fp-armv8".into();
 
+    // Microsoft recommends enabling frame pointers on Arm64 Windows.
+    // From https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#integer-registers
+    // "The frame pointer (x29) is required for compatibility with fast stack walking used by ETW
+    // and other services. It must point to the previous {x29, x30} pair on the stack."
+    base.frame_pointer = FramePointer::NonLeaf;
+
+    // MSVC emits a warning about code that may trip "Cortex-A53 MPCore processor bug #843419" (see
+    // https://developer.arm.com/documentation/epm048406/latest) which is sometimes emitted by LLVM.
+    // Since Arm64 Windows 10+ isn't supported on that processor, it's safe to disable the warning.
+    base.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &["/arm64hazardfree"]);
+
     Target {
         llvm_target: "aarch64-pc-windows-msvc".into(),
         metadata: TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs
index bb3e3e544cb..8f93523909e 100644
--- a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs
@@ -1,4 +1,4 @@
-use crate::spec::{LinkerFlavor, Lld, Target, TargetMetadata, add_link_args, base};
+use crate::spec::{FramePointer, LinkerFlavor, Lld, Target, TargetMetadata, add_link_args, base};
 
 pub(crate) fn target() -> Target {
     let mut base = base::windows_msvc::opts();
@@ -10,6 +10,12 @@ pub(crate) fn target() -> Target {
         &["/machine:arm64ec", "softintrin.lib"],
     );
 
+    // Microsoft recommends enabling frame pointers on Arm64 Windows.
+    // From https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#integer-registers
+    // "The frame pointer (x29) is required for compatibility with fast stack walking used by ETW
+    // and other services. It must point to the previous {x29, x30} pair on the stack."
+    base.frame_pointer = FramePointer::NonLeaf;
+
     Target {
         llvm_target: "arm64ec-pc-windows-msvc".into(),
         metadata: TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs
index 71b3fbe00b2..508abc01018 100644
--- a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs
@@ -27,6 +27,7 @@ pub(crate) fn target() -> Target {
             abi: "abi64".into(),
             endian: Endian::Big,
             mcount: "_mcount".into(),
+            llvm_abiname: "n64".into(),
             ..base
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs
index b130ca29c7f..a26350ff225 100644
--- a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs
@@ -22,6 +22,7 @@ pub(crate) fn target() -> Target {
             features: "+mips64r2,+xgot".into(),
             max_atomic_width: Some(64),
             mcount: "_mcount".into(),
+            llvm_abiname: "n64".into(),
 
             ..base::linux_gnu::opts()
         },
diff --git a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs
index 4ea7c7bff44..fd509503053 100644
--- a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs
+++ b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs
@@ -25,6 +25,7 @@ pub(crate) fn target() -> Target {
             mcount: "_mcount".into(),
             // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
             crt_static_default: true,
+            llvm_abiname: "n64".into(),
             ..base
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs
index a9afea27ef3..19bceadc622 100644
--- a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs
@@ -19,6 +19,7 @@ pub(crate) fn target() -> Target {
             features: "+mips64r2,+xgot".into(),
             max_atomic_width: Some(64),
             mcount: "_mcount".into(),
+            llvm_abiname: "n64".into(),
 
             ..base::linux_gnu::opts()
         },
diff --git a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs
index 7bdd9edda70..aa087b1a35a 100644
--- a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs
+++ b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs
@@ -19,6 +19,11 @@ pub(crate) fn target() -> Target {
         pointer_width: 64,
         data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(),
         arch: "mips64".into(),
-        options: TargetOptions { abi: "abi64".into(), mcount: "_mcount".into(), ..base },
+        options: TargetOptions {
+            abi: "abi64".into(),
+            mcount: "_mcount".into(),
+            llvm_abiname: "n64".into(),
+            ..base
+        },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs
index 3eefa27ea04..cdd5f6b8436 100644
--- a/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs
@@ -22,6 +22,7 @@ pub(crate) fn target() -> Target {
             features: "+mips64r6".into(),
             max_atomic_width: Some(64),
             mcount: "_mcount".into(),
+            llvm_abiname: "n64".into(),
 
             ..base::linux_gnu::opts()
         },
diff --git a/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs
index 0887180791c..88879a25818 100644
--- a/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs
@@ -19,6 +19,7 @@ pub(crate) fn target() -> Target {
             features: "+mips64r6".into(),
             max_atomic_width: Some(64),
             mcount: "_mcount".into(),
+            llvm_abiname: "n64".into(),
 
             ..base::linux_gnu::opts()
         },
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index f856d3efc1c..5a21925ba04 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -393,7 +393,28 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("amx-tf32", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
     ("amx-tile", Unstable(sym::x86_amx_intrinsics), &[]),
     ("amx-transpose", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
+    ("apxf", Unstable(sym::apx_target_feature), &[]),
     ("avx", Stable, &["sse4.2"]),
+    (
+        "avx10.1",
+        Unstable(sym::avx10_target_feature),
+        &[
+            "avx512bf16",
+            "avx512bitalg",
+            "avx512bw",
+            "avx512cd",
+            "avx512dq",
+            "avx512f",
+            "avx512fp16",
+            "avx512ifma",
+            "avx512vbmi",
+            "avx512vbmi2",
+            "avx512vl",
+            "avx512vnni",
+            "avx512vpopcntdq",
+        ],
+    ),
+    ("avx10.2", Unstable(sym::avx10_target_feature), &["avx10.1"]),
     ("avx2", Stable, &["avx"]),
     ("avx512bf16", Unstable(sym::avx512_target_feature), &["avx512bw"]),
     ("avx512bitalg", Unstable(sym::avx512_target_feature), &["avx512bw"]),
diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml
index a5cc8d9ea01..1071105522d 100644
--- a/compiler/rustc_trait_selection/Cargo.toml
+++ b/compiler/rustc_trait_selection/Cargo.toml
@@ -8,7 +8,6 @@ edition = "2024"
 itertools = "0.12"
 rustc_abi = { path = "../rustc_abi" }
 rustc_ast = { path = "../rustc_ast" }
-rustc_attr_parsing = { path = "../rustc_attr_parsing" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_errors = { path = "../rustc_errors" }
 rustc_fluent_macro = { path = "../rustc_fluent_macro" }
diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl
index 74e38f525c8..00922c6038e 100644
--- a/compiler/rustc_trait_selection/messages.ftl
+++ b/compiler/rustc_trait_selection/messages.ftl
@@ -148,9 +148,6 @@ trait_selection_dtcs_has_req_note = the used `impl` has a `'static` requirement
 trait_selection_dtcs_introduces_requirement = calling this method introduces the `impl`'s `'static` requirement
 trait_selection_dtcs_suggestion = consider relaxing the implicit `'static` requirement
 
-trait_selection_empty_on_clause_in_rustc_on_unimplemented = empty `on`-clause in `#[rustc_on_unimplemented]`
-    .label = empty on-clause here
-
 trait_selection_explicit_lifetime_required_sugg_with_ident = add explicit lifetime `{$named}` to the type of `{$simple_ident}`
 
 trait_selection_explicit_lifetime_required_sugg_with_param_type = add explicit lifetime `{$named}` to type
@@ -187,9 +184,6 @@ trait_selection_inherent_projection_normalization_overflow = overflow evaluating
 trait_selection_invalid_format_specifier = invalid format specifier
     .help = no format specifier are supported in this position
 
-trait_selection_invalid_on_clause_in_rustc_on_unimplemented = invalid `on`-clause in `#[rustc_on_unimplemented]`
-    .label = invalid on-clause here
-
 trait_selection_label_bad = {$bad_kind ->
     *[other] cannot infer type
     [more_info] cannot infer {$prefix_kind ->
@@ -237,10 +231,6 @@ trait_selection_negative_positive_conflict = found both positive and negative im
     .positive_implementation_here = positive implementation here
     .positive_implementation_in_crate = positive implementation in crate `{$positive_impl_cname}`
 
-trait_selection_no_value_in_rustc_on_unimplemented = this attribute must have a valid value
-    .label = expected value here
-    .note = eg `#[rustc_on_unimplemented(message="foo")]`
-
 trait_selection_nothing = {""}
 
 trait_selection_oc_cant_coerce_force_inline =
@@ -339,6 +329,22 @@ trait_selection_ril_introduced_by = requirement introduced by this return type
 trait_selection_ril_introduced_here = `'static` requirement introduced here
 trait_selection_ril_static_introduced_by = "`'static` lifetime requirement introduced by the return type
 
+trait_selection_rustc_on_unimplemented_empty_on_clause = empty `on`-clause in `#[rustc_on_unimplemented]`
+    .label = empty `on`-clause here
+trait_selection_rustc_on_unimplemented_expected_identifier = expected an identifier inside this `on`-clause
+    .label = expected an identifier here, not `{$path}`
+trait_selection_rustc_on_unimplemented_expected_one_predicate_in_not = expected a single predicate in `not(..)`
+    .label = unexpected quantity of predicates here
+trait_selection_rustc_on_unimplemented_invalid_flag = invalid flag in `on`-clause
+    .label = expected one of the `crate_local`, `direct` or `from_desugaring` flags, not `{$invalid_flag}`
+trait_selection_rustc_on_unimplemented_invalid_predicate = this predicate is invalid
+    .label = expected one of `any`, `all` or `not` here, not `{$invalid_pred}`
+trait_selection_rustc_on_unimplemented_missing_value = this attribute must have a value
+    .label = expected value here
+    .note = e.g. `#[rustc_on_unimplemented(message="foo")]`
+trait_selection_rustc_on_unimplemented_unsupported_literal_in_on = literals inside `on`-clauses are not supported
+    .label = unexpected literal here
+
 trait_selection_source_kind_closure_return =
     try giving this closure an explicit return type
 
@@ -446,8 +452,6 @@ trait_selection_type_annotations_needed = {$source_kind ->
 }
     .label = type must be known at this point
 
-trait_selection_type_annotations_needed_error_time = this is an inference error on crate `time` caused by an API change in Rust 1.80.0; update `time` to version `>=0.3.35` by calling `cargo update`
-
 trait_selection_types_declared_different = these two types are declared with different lifetimes...
 
 trait_selection_unable_to_construct_constant_value = unable to construct a constant value for the unevaluated constant {$unevaluated}
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
index de9a50f1962..cb1c9c75369 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
@@ -6,7 +6,7 @@ use rustc_errors::codes::*;
 use rustc_errors::{Diag, IntoDiagArg};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
-use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
+use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, LetStmt, LocalSource};
 use rustc_middle::bug;
@@ -17,7 +17,7 @@ use rustc_middle::ty::{
     self, GenericArg, GenericArgKind, GenericArgsRef, InferConst, IsSuggestable, Term, TermKind,
     Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, TypeckResults,
 };
-use rustc_span::{BytePos, DUMMY_SP, FileName, Ident, Span, sym};
+use rustc_span::{BytePos, DUMMY_SP, Ident, Span, sym};
 use tracing::{debug, instrument, warn};
 
 use super::nice_region_error::placeholder_error::Highlighted;
@@ -438,7 +438,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 bad_label,
                 was_written: false,
                 path: Default::default(),
-                time_version: false,
             }),
             TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
                 span,
@@ -630,10 +629,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 }
             }
         }
-
-        let time_version =
-            self.detect_old_time_crate_version(failure_span, &kind, &mut infer_subdiags);
-
         match error_code {
             TypeAnnotationNeeded::E0282 => self.dcx().create_err(AnnotationRequired {
                 span,
@@ -645,7 +640,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 bad_label: None,
                 was_written: path.is_some(),
                 path: path.unwrap_or_default(),
-                time_version,
             }),
             TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
                 span,
@@ -671,42 +665,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             }),
         }
     }
-
-    /// Detect the inference regression on crate `time` <= 0.3.35 and emit a more targeted error.
-    /// <https://github.com/rust-lang/rust/issues/127343>
-    // FIXME: we should figure out a more generic version of doing this, ideally in cargo itself.
-    fn detect_old_time_crate_version(
-        &self,
-        span: Option<Span>,
-        kind: &InferSourceKind<'_>,
-        // We will clear the non-actionable suggestion from the error to reduce noise.
-        infer_subdiags: &mut Vec<SourceKindSubdiag<'_>>,
-    ) -> bool {
-        // FIXME(#129461): We are time-boxing this code in the compiler. It'll start failing
-        // compilation once we promote 1.89 to beta, which will happen in 9 months from now.
-        #[cfg(not(version("1.89")))]
-        const fn version_check() {}
-        #[cfg(version("1.89"))]
-        const fn version_check() {
-            panic!("remove this check as presumably the ecosystem has moved from needing it");
-        }
-        const { version_check() };
-        // Only relevant when building the `time` crate.
-        if self.infcx.tcx.crate_name(LOCAL_CRATE) == sym::time
-            && let Some(span) = span
-            && let InferSourceKind::LetBinding { pattern_name, .. } = kind
-            && let Some(name) = pattern_name
-            && name.as_str() == "items"
-            && let FileName::Real(file) = self.infcx.tcx.sess.source_map().span_to_filename(span)
-        {
-            let path = file.local_path_if_available().to_string_lossy();
-            if path.contains("format_description") && path.contains("parse") {
-                infer_subdiags.clear();
-                return true;
-            }
-        }
-        false
-    }
 }
 
 #[derive(Debug)]
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
index 4c4491269b7..d5ee6e2123a 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
@@ -4,6 +4,7 @@ use std::path::PathBuf;
 use rustc_ast::{LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit};
 use rustc_errors::codes::*;
 use rustc_errors::{ErrorGuaranteed, struct_span_code_err};
+use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::{AttrArgs, Attribute};
 use rustc_macros::LintDiagnostic;
@@ -13,17 +14,16 @@ use rustc_middle::ty::{self, GenericArgsRef, GenericParamDef, GenericParamDefKin
 use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES;
 use rustc_span::{Span, Symbol, sym};
 use tracing::{debug, info};
-use {rustc_attr_parsing as attr, rustc_hir as hir};
 
 use super::{ObligationCauseCode, PredicateObligation};
 use crate::error_reporting::TypeErrCtxt;
-use crate::error_reporting::traits::on_unimplemented_condition::{Condition, ConditionOptions};
+use crate::error_reporting::traits::on_unimplemented_condition::{
+    ConditionOptions, OnUnimplementedCondition,
+};
 use crate::error_reporting::traits::on_unimplemented_format::{
     Ctx, FormatArgs, FormatString, FormatWarning,
 };
-use crate::errors::{
-    EmptyOnClauseInOnUnimplemented, InvalidOnClauseInOnUnimplemented, NoValueInOnUnimplemented,
-};
+use crate::errors::{InvalidOnClause, NoValueInOnUnimplemented};
 use crate::infer::InferCtxtExt;
 
 impl<'tcx> TypeErrCtxt<'_, 'tcx> {
@@ -306,21 +306,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
 #[derive(Clone, Debug)]
 pub struct OnUnimplementedFormatString {
     /// Symbol of the format string, i.e. `"content"`
-    pub symbol: Symbol,
+    symbol: Symbol,
     ///The span of the format string, i.e. `"content"`
-    pub span: Span,
-    pub is_diagnostic_namespace_variant: bool,
+    span: Span,
+    is_diagnostic_namespace_variant: bool,
 }
 
 #[derive(Debug)]
 pub struct OnUnimplementedDirective {
-    pub condition: Option<Condition>,
-    pub subcommands: Vec<OnUnimplementedDirective>,
-    pub message: Option<(Span, OnUnimplementedFormatString)>,
-    pub label: Option<(Span, OnUnimplementedFormatString)>,
-    pub notes: Vec<OnUnimplementedFormatString>,
-    pub parent_label: Option<OnUnimplementedFormatString>,
-    pub append_const_msg: Option<AppendConstMessage>,
+    condition: Option<OnUnimplementedCondition>,
+    subcommands: Vec<OnUnimplementedDirective>,
+    message: Option<(Span, OnUnimplementedFormatString)>,
+    label: Option<(Span, OnUnimplementedFormatString)>,
+    notes: Vec<OnUnimplementedFormatString>,
+    parent_label: Option<OnUnimplementedFormatString>,
+    append_const_msg: Option<AppendConstMessage>,
 }
 
 /// For the `#[rustc_on_unimplemented]` attribute
@@ -427,18 +427,12 @@ impl<'tcx> OnUnimplementedDirective {
         } else {
             let cond = item_iter
                 .next()
-                .ok_or_else(|| tcx.dcx().emit_err(EmptyOnClauseInOnUnimplemented { span }))?
-                .meta_item_or_bool()
-                .ok_or_else(|| tcx.dcx().emit_err(InvalidOnClauseInOnUnimplemented { span }))?;
-            attr::eval_condition(cond, &tcx.sess, Some(tcx.features()), &mut |cfg| {
-                if let Some(value) = cfg.value
-                    && let Err(guar) = parse_value(value, cfg.span)
-                {
-                    errored = Some(guar);
-                }
-                true
-            });
-            Some(Condition { inner: cond.clone() })
+                .ok_or_else(|| tcx.dcx().emit_err(InvalidOnClause::Empty { span }))?;
+
+            match OnUnimplementedCondition::parse(cond) {
+                Ok(condition) => Some(condition),
+                Err(e) => return Err(tcx.dcx().emit_err(e)),
+            }
         };
 
         let mut message = None;
@@ -724,7 +718,7 @@ impl<'tcx> OnUnimplementedDirective {
         result
     }
 
-    pub fn evaluate(
+    pub(crate) fn evaluate(
         &self,
         tcx: TyCtxt<'tcx>,
         trait_ref: ty::TraitRef<'tcx>,
@@ -744,7 +738,7 @@ impl<'tcx> OnUnimplementedDirective {
         for command in self.subcommands.iter().chain(Some(self)).rev() {
             debug!(?command);
             if let Some(ref condition) = command.condition
-                && !condition.matches_predicate(tcx, condition_options)
+                && !condition.matches_predicate(condition_options)
             {
                 debug!("evaluate: skipping {:?} due to condition", command);
                 continue;
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_condition.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_condition.rs
index 116cfb01cb6..13753761f09 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_condition.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_condition.rs
@@ -1,52 +1,251 @@
-use rustc_ast::MetaItemInner;
-use rustc_attr_parsing as attr;
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_ast::{MetaItemInner, MetaItemKind, MetaItemLit};
 use rustc_parse_format::{ParseMode, Parser, Piece, Position};
-use rustc_span::{DesugaringKind, Span, Symbol, kw, sym};
+use rustc_span::{DesugaringKind, Ident, Span, Symbol, kw, sym};
 
-/// A predicate in an attribute using on, all, any,
-/// similar to a cfg predicate.
+use crate::errors::InvalidOnClause;
+
+/// Represents the `on` filter in `#[rustc_on_unimplemented]`.
 #[derive(Debug)]
-pub struct Condition {
-    pub inner: MetaItemInner,
+pub(crate) struct OnUnimplementedCondition {
+    span: Span,
+    pred: Predicate,
 }
 
-impl Condition {
-    pub fn span(&self) -> Span {
-        self.inner.span()
+impl OnUnimplementedCondition {
+    pub(crate) fn span(&self) -> Span {
+        self.span
+    }
+
+    pub(crate) fn matches_predicate(&self, options: &ConditionOptions) -> bool {
+        self.pred.eval(&mut |p| match p {
+            FlagOrNv::Flag(b) => options.has_flag(*b),
+            FlagOrNv::NameValue(NameValue { name, value }) => {
+                let value = value.format(&options.generic_args);
+                options.contains(*name, value)
+            }
+        })
+    }
+
+    pub(crate) fn parse(input: &MetaItemInner) -> Result<Self, InvalidOnClause> {
+        let span = input.span();
+        let pred = Predicate::parse(input)?;
+        Ok(OnUnimplementedCondition { span, pred })
     }
+}
 
-    pub fn matches_predicate<'tcx>(&self, tcx: TyCtxt<'tcx>, options: &ConditionOptions) -> bool {
-        attr::eval_condition(&self.inner, tcx.sess, Some(tcx.features()), &mut |cfg| {
-            let value = cfg.value.map(|v| {
-                // `with_no_visible_paths` is also used when generating the options,
-                // so we need to match it here.
-                ty::print::with_no_visible_paths!({
-                    Parser::new(v.as_str(), None, None, false, ParseMode::Format)
-                        .map(|p| match p {
-                            Piece::Lit(s) => s.to_owned(),
-                            Piece::NextArgument(a) => match a.position {
-                                Position::ArgumentNamed(arg) => {
-                                    let s = Symbol::intern(arg);
-                                    match options.generic_args.iter().find(|(k, _)| *k == s) {
-                                        Some((_, val)) => val.to_string(),
-                                        None => format!("{{{arg}}}"),
-                                    }
-                                }
-                                Position::ArgumentImplicitlyIs(_) => String::from("{}"),
-                                Position::ArgumentIs(idx) => format!("{{{idx}}}"),
-                            },
-                        })
-                        .collect()
-                })
+/// Predicate(s) in `#[rustc_on_unimplemented]`'s `on` filter. See [`OnUnimplementedCondition`].
+///
+/// It is similar to the predicate in the `cfg` attribute,
+/// and may contain nested predicates.
+#[derive(Debug)]
+enum Predicate {
+    /// A condition like `on(crate_local)`.
+    Flag(Flag),
+    /// A match, like `on(Rhs = "Whatever")`.
+    Match(NameValue),
+    /// Negation, like `on(not($pred))`.
+    Not(Box<Predicate>),
+    /// True if all predicates are true, like `on(all($a, $b, $c))`.
+    All(Vec<Predicate>),
+    /// True if any predicate is true, like `on(any($a, $b, $c))`.
+    Any(Vec<Predicate>),
+}
+
+impl Predicate {
+    fn parse(input: &MetaItemInner) -> Result<Self, InvalidOnClause> {
+        let meta_item = match input {
+            MetaItemInner::MetaItem(meta_item) => meta_item,
+            MetaItemInner::Lit(lit) => {
+                return Err(InvalidOnClause::UnsupportedLiteral { span: lit.span });
+            }
+        };
+
+        let Some(predicate) = meta_item.ident() else {
+            return Err(InvalidOnClause::ExpectedIdentifier {
+                span: meta_item.path.span,
+                path: meta_item.path.clone(),
             });
+        };
 
-            options.contains(cfg.name, &value)
-        })
+        match meta_item.kind {
+            MetaItemKind::List(ref mis) => match predicate.name {
+                sym::any => Ok(Predicate::Any(Predicate::parse_sequence(mis)?)),
+                sym::all => Ok(Predicate::All(Predicate::parse_sequence(mis)?)),
+                sym::not => match &**mis {
+                    [one] => Ok(Predicate::Not(Box::new(Predicate::parse(one)?))),
+                    [first, .., last] => Err(InvalidOnClause::ExpectedOnePredInNot {
+                        span: first.span().to(last.span()),
+                    }),
+                    [] => Err(InvalidOnClause::ExpectedOnePredInNot { span: meta_item.span }),
+                },
+                invalid_pred => {
+                    Err(InvalidOnClause::InvalidPredicate { span: predicate.span, invalid_pred })
+                }
+            },
+            MetaItemKind::NameValue(MetaItemLit { symbol, .. }) => {
+                let name = Name::parse(predicate);
+                let value = FilterFormatString::parse(symbol);
+                let kv = NameValue { name, value };
+                Ok(Predicate::Match(kv))
+            }
+            MetaItemKind::Word => {
+                let flag = Flag::parse(predicate)?;
+                Ok(Predicate::Flag(flag))
+            }
+        }
+    }
+
+    fn parse_sequence(sequence: &[MetaItemInner]) -> Result<Vec<Self>, InvalidOnClause> {
+        sequence.iter().map(Predicate::parse).collect()
+    }
+
+    fn eval(&self, eval: &mut impl FnMut(FlagOrNv<'_>) -> bool) -> bool {
+        match self {
+            Predicate::Flag(flag) => eval(FlagOrNv::Flag(flag)),
+            Predicate::Match(nv) => eval(FlagOrNv::NameValue(nv)),
+            Predicate::Not(not) => !not.eval(eval),
+            Predicate::All(preds) => preds.into_iter().all(|pred| pred.eval(eval)),
+            Predicate::Any(preds) => preds.into_iter().any(|pred| pred.eval(eval)),
+        }
     }
 }
 
-/// Used with `Condition::matches_predicate` to test whether the condition applies
+/// Represents a `MetaWord` in an `on`-filter.
+#[derive(Debug, Clone, Copy)]
+enum Flag {
+    /// Whether the code causing the trait bound to not be fulfilled
+    /// is part of the user's crate.
+    CrateLocal,
+    /// Whether the obligation is user-specified rather than derived.
+    Direct,
+    /// Whether we are in some kind of desugaring like
+    /// `?` or `try { .. }`.
+    FromDesugaring,
+}
+
+impl Flag {
+    fn parse(Ident { name, span }: Ident) -> Result<Self, InvalidOnClause> {
+        match name {
+            sym::crate_local => Ok(Flag::CrateLocal),
+            sym::direct => Ok(Flag::Direct),
+            sym::from_desugaring => Ok(Flag::FromDesugaring),
+            invalid_flag => Err(InvalidOnClause::InvalidFlag { invalid_flag, span }),
+        }
+    }
+}
+
+/// A `MetaNameValueStr` in an `on`-filter.
+///
+/// For example, `#[rustc_on_unimplemented(on(name = "value", message = "hello"))]`.
+#[derive(Debug, Clone)]
+struct NameValue {
+    name: Name,
+    /// Something like `"&str"` or `"alloc::string::String"`,
+    /// in which case it just contains a single string piece.
+    /// But if it is something like `"&[{A}]"` then it must be formatted later.
+    value: FilterFormatString,
+}
+
+/// The valid names of the `on` filter.
+#[derive(Debug, Clone, Copy)]
+enum Name {
+    Cause,
+    FromDesugaring,
+    SelfUpper,
+    GenericArg(Symbol),
+}
+
+impl Name {
+    fn parse(Ident { name, .. }: Ident) -> Self {
+        match name {
+            sym::_Self | kw::SelfUpper => Name::SelfUpper,
+            sym::from_desugaring => Name::FromDesugaring,
+            sym::cause => Name::Cause,
+            // FIXME(mejrs) Perhaps we should start checking that
+            // this actually is a valid generic parameter?
+            generic => Name::GenericArg(generic),
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+enum FlagOrNv<'p> {
+    Flag(&'p Flag),
+    NameValue(&'p NameValue),
+}
+
+/// Represents a value inside an `on` filter.
+///
+/// For example, `#[rustc_on_unimplemented(on(name = "value", message = "hello"))]`.
+/// If it is a simple literal like this then `pieces` will be `[LitOrArg::Lit("value")]`.
+/// The `Arg` variant is used when it contains formatting like
+/// `#[rustc_on_unimplemented(on(Self = "&[{A}]", message = "hello"))]`.
+#[derive(Debug, Clone)]
+struct FilterFormatString {
+    pieces: Vec<LitOrArg>,
+}
+
+#[derive(Debug, Clone)]
+enum LitOrArg {
+    Lit(String),
+    Arg(String),
+}
+
+impl FilterFormatString {
+    fn parse(input: Symbol) -> Self {
+        let pieces = Parser::new(input.as_str(), None, None, false, ParseMode::Format)
+            .map(|p| match p {
+                Piece::Lit(s) => LitOrArg::Lit(s.to_owned()),
+                // We just ignore formatspecs here
+                Piece::NextArgument(a) => match a.position {
+                    // In `TypeErrCtxt::on_unimplemented_note` we substitute `"{integral}"` even
+                    // if the integer type has been resolved, to allow targeting all integers.
+                    // `"{integer}"` and `"{float}"` come from numerics that haven't been inferred yet,
+                    // from the `Display` impl of `InferTy` to be precise.
+                    //
+                    // Don't try to format these later!
+                    Position::ArgumentNamed(arg @ "integer" | arg @ "integral" | arg @ "float") => {
+                        LitOrArg::Lit(format!("{{{arg}}}"))
+                    }
+
+                    // FIXME(mejrs) We should check if these correspond to a generic of the trait.
+                    Position::ArgumentNamed(arg) => LitOrArg::Arg(arg.to_owned()),
+
+                    // FIXME(mejrs) These should really be warnings/errors
+                    Position::ArgumentImplicitlyIs(_) => LitOrArg::Lit(String::from("{}")),
+                    Position::ArgumentIs(idx) => LitOrArg::Lit(format!("{{{idx}}}")),
+                },
+            })
+            .collect();
+        Self { pieces }
+    }
+
+    fn format(&self, generic_args: &[(Symbol, String)]) -> String {
+        let mut ret = String::new();
+
+        for piece in &self.pieces {
+            match piece {
+                LitOrArg::Lit(s) => ret.push_str(s),
+                LitOrArg::Arg(arg) => {
+                    let s = Symbol::intern(arg);
+                    match generic_args.iter().find(|(k, _)| *k == s) {
+                        Some((_, val)) => ret.push_str(val),
+                        None => {
+                            // FIXME(mejrs) If we start checking as mentioned in
+                            // FilterFormatString::parse then this shouldn't happen
+                            let _ = std::fmt::write(&mut ret, format_args!("{{{s}}}"));
+                        }
+                    }
+                }
+            }
+        }
+
+        ret
+    }
+}
+
+/// Used with `OnUnimplementedCondition::matches_predicate` to evaluate the
+/// [`OnUnimplementedCondition`].
 ///
 /// For example, given a
 /// ```rust,ignore (just an example)
@@ -85,36 +284,34 @@ impl Condition {
 /// }
 /// ```
 #[derive(Debug)]
-pub struct ConditionOptions {
+pub(crate) struct ConditionOptions {
     /// All the self types that may apply.
-    /// for example
-    pub self_types: Vec<String>,
+    pub(crate) self_types: Vec<String>,
     // The kind of compiler desugaring.
-    pub from_desugaring: Option<DesugaringKind>,
-    /// Match on a variant of [rustc_infer::traits::ObligationCauseCode]
-    pub cause: Option<String>,
-    pub crate_local: bool,
+    pub(crate) from_desugaring: Option<DesugaringKind>,
+    /// Match on a variant of [rustc_infer::traits::ObligationCauseCode].
+    pub(crate) cause: Option<String>,
+    pub(crate) crate_local: bool,
     /// Is the obligation "directly" user-specified, rather than derived?
-    pub direct: bool,
-    // A list of the generic arguments and their reified types
-    pub generic_args: Vec<(Symbol, String)>,
+    pub(crate) direct: bool,
+    // A list of the generic arguments and their reified types.
+    pub(crate) generic_args: Vec<(Symbol, String)>,
 }
 
 impl ConditionOptions {
-    pub fn contains(&self, key: Symbol, value: &Option<String>) -> bool {
-        match (key, value) {
-            (sym::_Self | kw::SelfUpper, Some(value)) => self.self_types.contains(&value),
-            // from_desugaring as a flag
-            (sym::from_desugaring, None) => self.from_desugaring.is_some(),
-            // from_desugaring as key == value
-            (sym::from_desugaring, Some(v)) if let Some(ds) = self.from_desugaring => ds.matches(v),
-            (sym::cause, Some(value)) => self.cause.as_deref() == Some(value),
-            (sym::crate_local, None) => self.crate_local,
-            (sym::direct, None) => self.direct,
-            (other, Some(value)) => {
-                self.generic_args.iter().any(|(k, v)| *k == other && v == value)
-            }
-            _ => false,
+    fn has_flag(&self, name: Flag) -> bool {
+        match name {
+            Flag::CrateLocal => self.crate_local,
+            Flag::Direct => self.direct,
+            Flag::FromDesugaring => self.from_desugaring.is_some(),
+        }
+    }
+    fn contains(&self, name: Name, value: String) -> bool {
+        match name {
+            Name::SelfUpper => self.self_types.contains(&value),
+            Name::FromDesugaring => self.from_desugaring.is_some_and(|ds| ds.matches(&value)),
+            Name::Cause => self.cause == Some(value),
+            Name::GenericArg(arg) => self.generic_args.contains(&(arg, value)),
         }
     }
 }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs
index f835406122b..d8b90844b7d 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs
@@ -1,11 +1,12 @@
 use std::fmt;
+use std::ops::Range;
 
 use errors::*;
 use rustc_middle::ty::TyCtxt;
 use rustc_middle::ty::print::TraitRefPrintSugared;
 use rustc_parse_format::{
-    Alignment, Argument, Count, FormatSpec, InnerSpan, ParseError, ParseMode, Parser,
-    Piece as RpfPiece, Position,
+    Alignment, Argument, Count, FormatSpec, ParseError, ParseMode, Parser, Piece as RpfPiece,
+    Position,
 };
 use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES;
 use rustc_span::def_id::DefId;
@@ -173,7 +174,7 @@ impl FormatString {
                     pieces.push(Piece::Lit(lit.into()));
                 }
                 RpfPiece::NextArgument(arg) => {
-                    warn_on_format_spec(arg.format, &mut warnings, span);
+                    warn_on_format_spec(arg.format.clone(), &mut warnings, span);
                     let arg = parse_arg(&arg, ctx, &mut warnings, span);
                     pieces.push(Piece::Arg(arg));
                 }
@@ -233,7 +234,7 @@ fn parse_arg<'tcx>(
     | Ctx::DiagnosticOnUnimplemented { tcx, trait_def_id }) = ctx;
     let trait_name = tcx.item_ident(*trait_def_id);
     let generics = tcx.generics_of(trait_def_id);
-    let span = slice_span(input_span, arg.position_span);
+    let span = slice_span(input_span, arg.position_span.clone());
 
     match arg.position {
         // Something like "hello {name}"
@@ -335,14 +336,12 @@ fn warn_on_format_spec(spec: FormatSpec<'_>, warnings: &mut Vec<FormatWarning>,
     }
 }
 
-/// Helper function because `Span` and `rustc_parse_format::InnerSpan` don't know about each other
-fn slice_span(input: Span, inner: InnerSpan) -> Span {
-    let InnerSpan { start, end } = inner;
+fn slice_span(input: Span, range: Range<usize>) -> Span {
     let span = input.data();
 
     Span::new(
-        span.lo + BytePos::from_usize(start),
-        span.lo + BytePos::from_usize(end),
+        span.lo + BytePos::from_usize(range.start),
+        span.lo + BytePos::from_usize(range.end),
         span.ctxt,
         span.parent,
     )
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index de251ae2893..8801397b775 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -1516,6 +1516,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 } else {
                     expr.span.with_hi(expr.span.lo() + BytePos(1))
                 };
+
+                match self.tcx.sess.source_map().span_to_snippet(span) {
+                    Ok(snippet) if snippet.starts_with("&") => {}
+                    _ => break 'outer,
+                }
+
                 suggestions.push((span, String::new()));
 
                 let ty::Ref(_, inner_ty, _) = suggested_ty.kind() else {
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index 1063115ed23..8ab4d795c45 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -1,5 +1,6 @@
 use std::path::PathBuf;
 
+use rustc_ast::Path;
 use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
 use rustc_errors::codes::*;
 use rustc_errors::{
@@ -31,23 +32,50 @@ pub struct UnableToConstructConstantValue<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(trait_selection_empty_on_clause_in_rustc_on_unimplemented, code = E0232)]
-pub struct EmptyOnClauseInOnUnimplemented {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(trait_selection_invalid_on_clause_in_rustc_on_unimplemented, code = E0232)]
-pub struct InvalidOnClauseInOnUnimplemented {
-    #[primary_span]
-    #[label]
-    pub span: Span,
+pub enum InvalidOnClause {
+    #[diag(trait_selection_rustc_on_unimplemented_empty_on_clause, code = E0232)]
+    Empty {
+        #[primary_span]
+        #[label]
+        span: Span,
+    },
+    #[diag(trait_selection_rustc_on_unimplemented_expected_one_predicate_in_not, code = E0232)]
+    ExpectedOnePredInNot {
+        #[primary_span]
+        #[label]
+        span: Span,
+    },
+    #[diag(trait_selection_rustc_on_unimplemented_unsupported_literal_in_on, code = E0232)]
+    UnsupportedLiteral {
+        #[primary_span]
+        #[label]
+        span: Span,
+    },
+    #[diag(trait_selection_rustc_on_unimplemented_expected_identifier, code = E0232)]
+    ExpectedIdentifier {
+        #[primary_span]
+        #[label]
+        span: Span,
+        path: Path,
+    },
+    #[diag(trait_selection_rustc_on_unimplemented_invalid_predicate, code = E0232)]
+    InvalidPredicate {
+        #[primary_span]
+        #[label]
+        span: Span,
+        invalid_pred: Symbol,
+    },
+    #[diag(trait_selection_rustc_on_unimplemented_invalid_flag, code = E0232)]
+    InvalidFlag {
+        #[primary_span]
+        #[label]
+        span: Span,
+        invalid_flag: Symbol,
+    },
 }
 
 #[derive(Diagnostic)]
-#[diag(trait_selection_no_value_in_rustc_on_unimplemented, code = E0232)]
+#[diag(trait_selection_rustc_on_unimplemented_missing_value, code = E0232)]
 #[note]
 pub struct NoValueInOnUnimplemented {
     #[primary_span]
@@ -191,8 +219,6 @@ pub struct AnnotationRequired<'a> {
     #[note(trait_selection_full_type_written)]
     pub was_written: bool,
     pub path: PathBuf,
-    #[note(trait_selection_type_annotations_needed_error_time)]
-    pub time_version: bool,
 }
 
 // Copy of `AnnotationRequired` for E0283
diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs
index cce67b066dd..332204a0c5f 100644
--- a/compiler/rustc_trait_selection/src/opaque_types.rs
+++ b/compiler/rustc_trait_selection/src/opaque_types.rs
@@ -13,6 +13,49 @@ use crate::errors::NonGenericOpaqueTypeParam;
 use crate::regions::OutlivesEnvironmentBuildExt;
 use crate::traits::ObligationCtxt;
 
+pub enum InvalidOpaqueTypeArgs<'tcx> {
+    AlreadyReported(ErrorGuaranteed),
+    NotAParam { opaque_type_key: OpaqueTypeKey<'tcx>, param_index: usize, span: Span },
+    DuplicateParam { opaque_type_key: OpaqueTypeKey<'tcx>, param_indices: Vec<usize>, span: Span },
+}
+impl From<ErrorGuaranteed> for InvalidOpaqueTypeArgs<'_> {
+    fn from(guar: ErrorGuaranteed) -> Self {
+        InvalidOpaqueTypeArgs::AlreadyReported(guar)
+    }
+}
+impl<'tcx> InvalidOpaqueTypeArgs<'tcx> {
+    pub fn report(self, infcx: &InferCtxt<'tcx>) -> ErrorGuaranteed {
+        let tcx = infcx.tcx;
+        match self {
+            InvalidOpaqueTypeArgs::AlreadyReported(guar) => guar,
+            InvalidOpaqueTypeArgs::NotAParam { opaque_type_key, param_index, span } => {
+                let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
+                let opaque_param = opaque_generics.param_at(param_index, tcx);
+                let kind = opaque_param.kind.descr();
+                infcx.dcx().emit_err(NonGenericOpaqueTypeParam {
+                    arg: opaque_type_key.args[param_index],
+                    kind,
+                    span,
+                    param_span: tcx.def_span(opaque_param.def_id),
+                })
+            }
+            InvalidOpaqueTypeArgs::DuplicateParam { opaque_type_key, param_indices, span } => {
+                let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
+                let descr = opaque_generics.param_at(param_indices[0], tcx).kind.descr();
+                let spans: Vec<_> = param_indices
+                    .into_iter()
+                    .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id))
+                    .collect();
+                infcx
+                    .dcx()
+                    .struct_span_err(span, "non-defining opaque type use in defining scope")
+                    .with_span_note(spans, format!("{descr} used multiple times"))
+                    .emit()
+            }
+        }
+    }
+}
+
 /// Opaque type parameter validity check as documented in the [rustc-dev-guide chapter].
 ///
 /// [rustc-dev-guide chapter]:
@@ -22,23 +65,19 @@ pub fn check_opaque_type_parameter_valid<'tcx>(
     opaque_type_key: OpaqueTypeKey<'tcx>,
     span: Span,
     defining_scope_kind: DefiningScopeKind,
-) -> Result<(), ErrorGuaranteed> {
+) -> Result<(), InvalidOpaqueTypeArgs<'tcx>> {
     let tcx = infcx.tcx;
-    let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
     let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id);
     let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default();
 
     // Avoid duplicate errors in case the opaque has already been malformed in
     // HIR typeck.
     if let DefiningScopeKind::MirBorrowck = defining_scope_kind {
-        if let Err(guar) = infcx
+        infcx
             .tcx
             .type_of_opaque_hir_typeck(opaque_type_key.def_id)
             .instantiate_identity()
-            .error_reported()
-        {
-            return Err(guar);
-        }
+            .error_reported()?;
     }
 
     for (i, arg) in opaque_type_key.iter_captured_args(tcx) {
@@ -64,32 +103,18 @@ pub fn check_opaque_type_parameter_valid<'tcx>(
             }
         } else {
             // Prevent `fn foo() -> Foo<u32>` from being defining.
-            let opaque_param = opaque_generics.param_at(i, tcx);
-            let kind = opaque_param.kind.descr();
-
             opaque_env.param_is_error(i)?;
-
-            return Err(infcx.dcx().emit_err(NonGenericOpaqueTypeParam {
-                arg,
-                kind,
-                span,
-                param_span: tcx.def_span(opaque_param.def_id),
-            }));
+            return Err(InvalidOpaqueTypeArgs::NotAParam { opaque_type_key, param_index: i, span });
         }
     }
 
-    for (_, indices) in seen_params {
-        if indices.len() > 1 {
-            let descr = opaque_generics.param_at(indices[0], tcx).kind.descr();
-            let spans: Vec<_> = indices
-                .into_iter()
-                .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id))
-                .collect();
-            return Err(infcx
-                .dcx()
-                .struct_span_err(span, "non-defining opaque type use in defining scope")
-                .with_span_note(spans, format!("{descr} used multiple times"))
-                .emit());
+    for (_, param_indices) in seen_params {
+        if param_indices.len() > 1 {
+            return Err(InvalidOpaqueTypeArgs::DuplicateParam {
+                opaque_type_key,
+                param_indices,
+                span,
+            });
         }
     }
 
diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs
index ef64da13189..3601c2cba9b 100644
--- a/compiler/rustc_trait_selection/src/solve/delegate.rs
+++ b/compiler/rustc_trait_selection/src/solve/delegate.rs
@@ -104,10 +104,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
         .map(|obligations| obligations.into_iter().map(|obligation| obligation.as_goal()).collect())
     }
 
-    fn clone_opaque_types_for_query_response(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
-        self.0.clone_opaque_types_for_query_response()
-    }
-
     fn make_deduplicated_outlives_constraints(
         &self,
     ) -> Vec<ty::OutlivesPredicate<'tcx, ty::GenericArg<'tcx>>> {
@@ -153,18 +149,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
         self.0.instantiate_canonical_var(span, cv_info, universe_map)
     }
 
-    fn register_hidden_type_in_storage(
-        &self,
-        opaque_type_key: ty::OpaqueTypeKey<'tcx>,
-        hidden_ty: <Self::Interner as ty::Interner>::Ty,
-        span: <Self::Interner as ty::Interner>::Span,
-    ) -> Option<<Self::Interner as ty::Interner>::Ty> {
-        self.0.register_hidden_type_in_storage(
-            opaque_type_key,
-            ty::OpaqueHiddenType { span, ty: hidden_ty },
-        )
-    }
-
     fn add_item_bounds_for_hidden_type(
         &self,
         def_id: DefId,
@@ -176,10 +160,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
         self.0.add_item_bounds_for_hidden_type(def_id, args, param_env, hidden_ty, goals);
     }
 
-    fn reset_opaque_types(&self) {
-        let _ = self.take_opaque_types();
-    }
-
     fn fetch_eligible_assoc_item(
         &self,
         goal_trait_ref: ty::TraitRef<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs
index 2d445dd0790..f64cd5ffebe 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs
@@ -99,7 +99,13 @@ pub(super) fn fulfillment_error_for_stalled<'tcx>(
             Ok((_, Certainty::Maybe(MaybeCause::Ambiguity))) => {
                 (FulfillmentErrorCode::Ambiguity { overflow: None }, true)
             }
-            Ok((_, Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit }))) => (
+            Ok((
+                _,
+                Certainty::Maybe(MaybeCause::Overflow {
+                    suggest_increasing_limit,
+                    keep_constraints: _,
+                }),
+            )) => (
                 FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) },
                 // Don't look into overflows because we treat overflows weirdly anyways.
                 // We discard the inference constraints from overflowing goals, so
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
index 24b87000e32..9795655e842 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
@@ -382,7 +382,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
             if let Some(term_hack) = normalizes_to_term_hack {
                 infcx
                     .probe(|_| term_hack.constrain(infcx, DUMMY_SP, uncanonicalized_goal.param_env))
-                    .map(|certainty| ok.value.certainty.unify_with(certainty))
+                    .map(|certainty| ok.value.certainty.and(certainty))
             } else {
                 Ok(ok.value.certainty)
             }
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 0987c5b42d8..5b938456e03 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -51,7 +51,7 @@ pub use self::dyn_compatibility::{
 pub use self::engine::{ObligationCtxt, TraitEngineExt};
 pub use self::fulfill::{FulfillmentContext, OldSolverError, PendingPredicateObligation};
 pub use self::normalize::NormalizeExt;
-pub use self::project::{normalize_inherent_projection, normalize_projection_ty};
+pub use self::project::{normalize_inherent_projection, normalize_projection_term};
 pub use self::select::{
     EvaluationCache, EvaluationResult, IntercrateAmbiguityCause, OverflowError, SelectionCache,
     SelectionContext,
diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs
index 5f0acd46f86..88a0c402702 100644
--- a/compiler/rustc_trait_selection/src/traits/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/normalize.rs
@@ -1,6 +1,7 @@
 //! Deeply normalize types using the old trait solver.
 
 use rustc_data_structures::stack::ensure_sufficient_stack;
+use rustc_hir::def::DefKind;
 use rustc_infer::infer::at::At;
 use rustc_infer::infer::{InferCtxt, InferOk};
 use rustc_infer::traits::{
@@ -10,15 +11,12 @@ use rustc_macros::extension;
 use rustc_middle::span_bug;
 use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
 use rustc_middle::ty::{
-    self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt,
-    TypingMode,
+    self, AliasTerm, Term, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable,
+    TypeVisitableExt, TypingMode,
 };
 use tracing::{debug, instrument};
 
-use super::{
-    BoundVarReplacer, PlaceholderReplacer, SelectionContext, project,
-    with_replaced_escaping_bound_vars,
-};
+use super::{BoundVarReplacer, PlaceholderReplacer, SelectionContext, project};
 use crate::error_reporting::InferCtxtErrorExt;
 use crate::error_reporting::traits::OverflowCause;
 use crate::solve::NextSolverError;
@@ -178,6 +176,163 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
 
         if !needs_normalization(self.selcx.infcx, &value) { value } else { value.fold_with(self) }
     }
+
+    // FIXME(mgca): While this supports constants, it is only used for types by default right now
+    #[instrument(level = "debug", skip(self), ret)]
+    fn normalize_trait_projection(&mut self, proj: AliasTerm<'tcx>) -> Term<'tcx> {
+        if !proj.has_escaping_bound_vars() {
+            // When we don't have escaping bound vars we can normalize ambig aliases
+            // to inference variables (done in `normalize_projection_ty`). This would
+            // be wrong if there were escaping bound vars as even if we instantiated
+            // the bound vars with placeholders, we wouldn't be able to map them back
+            // after normalization succeeded.
+            //
+            // Also, as an optimization: when we don't have escaping bound vars, we don't
+            // need to replace them with placeholders (see branch below).
+            let proj = proj.fold_with(self);
+            project::normalize_projection_term(
+                self.selcx,
+                self.param_env,
+                proj,
+                self.cause.clone(),
+                self.depth,
+                self.obligations,
+            )
+        } else {
+            // If there are escaping bound vars, we temporarily replace the
+            // bound vars with placeholders. Note though, that in the case
+            // that we still can't project for whatever reason (e.g. self
+            // type isn't known enough), we *can't* register an obligation
+            // and return an inference variable (since then that obligation
+            // would have bound vars and that's a can of worms). Instead,
+            // we just give up and fall back to pretending like we never tried!
+            //
+            // Note: this isn't necessarily the final approach here; we may
+            // want to figure out how to register obligations with escaping vars
+            // or handle this some other way.
+            let infcx = self.selcx.infcx;
+            let (proj, mapped_regions, mapped_types, mapped_consts) =
+                BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, proj);
+            let proj = proj.fold_with(self);
+            let normalized_term = project::opt_normalize_projection_term(
+                self.selcx,
+                self.param_env,
+                proj,
+                self.cause.clone(),
+                self.depth,
+                self.obligations,
+            )
+            .ok()
+            .flatten()
+            .unwrap_or(proj.to_term(infcx.tcx));
+
+            PlaceholderReplacer::replace_placeholders(
+                infcx,
+                mapped_regions,
+                mapped_types,
+                mapped_consts,
+                &self.universes,
+                normalized_term,
+            )
+        }
+    }
+
+    // FIXME(mgca): While this supports constants, it is only used for types by default right now
+    #[instrument(level = "debug", skip(self), ret)]
+    fn normalize_inherent_projection(&mut self, inherent: AliasTerm<'tcx>) -> Term<'tcx> {
+        if !inherent.has_escaping_bound_vars() {
+            // When we don't have escaping bound vars we can normalize ambig aliases
+            // to inference variables (done in `normalize_projection_ty`). This would
+            // be wrong if there were escaping bound vars as even if we instantiated
+            // the bound vars with placeholders, we wouldn't be able to map them back
+            // after normalization succeeded.
+            //
+            // Also, as an optimization: when we don't have escaping bound vars, we don't
+            // need to replace them with placeholders (see branch below).
+
+            let inherent = inherent.fold_with(self);
+            project::normalize_inherent_projection(
+                self.selcx,
+                self.param_env,
+                inherent,
+                self.cause.clone(),
+                self.depth,
+                self.obligations,
+            )
+        } else {
+            let infcx = self.selcx.infcx;
+            let (inherent, mapped_regions, mapped_types, mapped_consts) =
+                BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, inherent);
+            let inherent = inherent.fold_with(self);
+            let inherent = project::normalize_inherent_projection(
+                self.selcx,
+                self.param_env,
+                inherent,
+                self.cause.clone(),
+                self.depth,
+                self.obligations,
+            );
+
+            PlaceholderReplacer::replace_placeholders(
+                infcx,
+                mapped_regions,
+                mapped_types,
+                mapped_consts,
+                &self.universes,
+                inherent,
+            )
+        }
+    }
+
+    // FIXME(mgca): While this supports constants, it is only used for types by default right now
+    #[instrument(level = "debug", skip(self), ret)]
+    fn normalize_free_alias(&mut self, free: AliasTerm<'tcx>) -> Term<'tcx> {
+        let recursion_limit = self.cx().recursion_limit();
+        if !recursion_limit.value_within_limit(self.depth) {
+            self.selcx.infcx.err_ctxt().report_overflow_error(
+                OverflowCause::DeeplyNormalize(free.into()),
+                self.cause.span,
+                false,
+                |diag| {
+                    diag.note(crate::fluent_generated::trait_selection_ty_alias_overflow);
+                },
+            );
+        }
+
+        let infcx = self.selcx.infcx;
+        self.obligations.extend(
+            // FIXME(BoxyUwU):
+            // FIXME(lazy_type_alias):
+            // It seems suspicious to instantiate the predicates with arguments that might be bound vars,
+            // we might wind up instantiating one of these bound vars underneath a hrtb.
+            infcx.tcx.predicates_of(free.def_id).instantiate_own(infcx.tcx, free.args).map(
+                |(mut predicate, span)| {
+                    if free.has_escaping_bound_vars() {
+                        (predicate, ..) = BoundVarReplacer::replace_bound_vars(
+                            infcx,
+                            &mut self.universes,
+                            predicate,
+                        );
+                    }
+                    let mut cause = self.cause.clone();
+                    cause.map_code(|code| ObligationCauseCode::TypeAlias(code, span, free.def_id));
+                    Obligation::new(infcx.tcx, cause, self.param_env, predicate)
+                },
+            ),
+        );
+        self.depth += 1;
+        let res = if free.kind(infcx.tcx).is_type() {
+            infcx.tcx.type_of(free.def_id).instantiate(infcx.tcx, free.args).fold_with(self).into()
+        } else {
+            // FIXME(mgca): once const items are actual aliases defined as equal to type system consts
+            // this should instead use that rather than evaluating.
+            super::evaluate_const(infcx, free.to_term(infcx.tcx).expect_const(), self.param_env)
+                .super_fold_with(self)
+                .into()
+        };
+        self.depth -= 1;
+        res
+    }
 }
 
 impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx> {
@@ -259,186 +414,63 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
                 }
             }
 
-            ty::Projection if !data.has_escaping_bound_vars() => {
-                // When we don't have escaping bound vars we can normalize ambig aliases
-                // to inference variables (done in `normalize_projection_ty`). This would
-                // be wrong if there were escaping bound vars as even if we instantiated
-                // the bound vars with placeholders, we wouldn't be able to map them back
-                // after normalization succeeded.
-                //
-                // Also, as an optimization: when we don't have escaping bound vars, we don't
-                // need to replace them with placeholders (see branch below).
-                let data = data.fold_with(self);
-                let normalized_ty = project::normalize_projection_ty(
-                    self.selcx,
-                    self.param_env,
-                    data,
-                    self.cause.clone(),
-                    self.depth,
-                    self.obligations,
-                );
-                debug!(
-                    ?self.depth,
-                    ?ty,
-                    ?normalized_ty,
-                    obligations.len = ?self.obligations.len(),
-                    "AssocTypeNormalizer: normalized type"
-                );
-                normalized_ty.expect_type()
-            }
-
-            ty::Projection => {
-                // If there are escaping bound vars, we temporarily replace the
-                // bound vars with placeholders. Note though, that in the case
-                // that we still can't project for whatever reason (e.g. self
-                // type isn't known enough), we *can't* register an obligation
-                // and return an inference variable (since then that obligation
-                // would have bound vars and that's a can of worms). Instead,
-                // we just give up and fall back to pretending like we never tried!
-                //
-                // Note: this isn't necessarily the final approach here; we may
-                // want to figure out how to register obligations with escaping vars
-                // or handle this some other way.
-
-                let infcx = self.selcx.infcx;
-                let (data, mapped_regions, mapped_types, mapped_consts) =
-                    BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
-                let data = data.fold_with(self);
-                let normalized_ty = project::opt_normalize_projection_term(
-                    self.selcx,
-                    self.param_env,
-                    data.into(),
-                    self.cause.clone(),
-                    self.depth,
-                    self.obligations,
-                )
-                .ok()
-                .flatten()
-                .map(|term| term.expect_type())
-                .map(|normalized_ty| {
-                    PlaceholderReplacer::replace_placeholders(
-                        infcx,
-                        mapped_regions,
-                        mapped_types,
-                        mapped_consts,
-                        &self.universes,
-                        normalized_ty,
-                    )
-                })
-                .unwrap_or_else(|| ty.super_fold_with(self));
-
-                debug!(
-                    ?self.depth,
-                    ?ty,
-                    ?normalized_ty,
-                    obligations.len = ?self.obligations.len(),
-                    "AssocTypeNormalizer: normalized type"
-                );
-                normalized_ty
-            }
-            ty::Free => {
-                let recursion_limit = self.cx().recursion_limit();
-                if !recursion_limit.value_within_limit(self.depth) {
-                    self.selcx.infcx.err_ctxt().report_overflow_error(
-                        OverflowCause::DeeplyNormalize(data.into()),
-                        self.cause.span,
-                        false,
-                        |diag| {
-                            diag.note(crate::fluent_generated::trait_selection_ty_alias_overflow);
-                        },
-                    );
-                }
-
-                let infcx = self.selcx.infcx;
-                self.obligations.extend(
-                    infcx.tcx.predicates_of(data.def_id).instantiate_own(infcx.tcx, data.args).map(
-                        |(mut predicate, span)| {
-                            if data.has_escaping_bound_vars() {
-                                (predicate, ..) = BoundVarReplacer::replace_bound_vars(
-                                    infcx,
-                                    &mut self.universes,
-                                    predicate,
-                                );
-                            }
-                            let mut cause = self.cause.clone();
-                            cause.map_code(|code| {
-                                ObligationCauseCode::TypeAlias(code, span, data.def_id)
-                            });
-                            Obligation::new(infcx.tcx, cause, self.param_env, predicate)
-                        },
-                    ),
-                );
-                self.depth += 1;
-                let res = infcx
-                    .tcx
-                    .type_of(data.def_id)
-                    .instantiate(infcx.tcx, data.args)
-                    .fold_with(self);
-                self.depth -= 1;
-                res
-            }
-
-            ty::Inherent if !data.has_escaping_bound_vars() => {
-                // This branch is *mostly* just an optimization: when we don't
-                // have escaping bound vars, we don't need to replace them with
-                // placeholders (see branch below). *Also*, we know that we can
-                // register an obligation to *later* project, since we know
-                // there won't be bound vars there.
-
-                let data = data.fold_with(self);
-
-                project::normalize_inherent_projection(
-                    self.selcx,
-                    self.param_env,
-                    data,
-                    self.cause.clone(),
-                    self.depth,
-                    self.obligations,
-                )
-            }
-
-            ty::Inherent => {
-                let infcx = self.selcx.infcx;
-                let (data, mapped_regions, mapped_types, mapped_consts) =
-                    BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
-                let data = data.fold_with(self);
-                let ty = project::normalize_inherent_projection(
-                    self.selcx,
-                    self.param_env,
-                    data,
-                    self.cause.clone(),
-                    self.depth,
-                    self.obligations,
-                );
-
-                PlaceholderReplacer::replace_placeholders(
-                    infcx,
-                    mapped_regions,
-                    mapped_types,
-                    mapped_consts,
-                    &self.universes,
-                    ty,
-                )
-            }
+            ty::Projection => self.normalize_trait_projection(data.into()).expect_type(),
+            ty::Inherent => self.normalize_inherent_projection(data.into()).expect_type(),
+            ty::Free => self.normalize_free_alias(data.into()).expect_type(),
         }
     }
 
     #[instrument(skip(self), level = "debug")]
-    fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> {
+    fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
         let tcx = self.selcx.tcx();
-        if tcx.features().generic_const_exprs() || !needs_normalization(self.selcx.infcx, &constant)
-        {
-            constant
+        if tcx.features().generic_const_exprs() || !needs_normalization(self.selcx.infcx, &ct) {
+            return ct;
+        }
+
+        // Doing "proper" normalization of const aliases is inherently cyclic until const items
+        // are real aliases instead of having bodies. We gate proper const alias handling behind
+        // mgca to avoid breaking stable code, though this should become the "main" codepath long
+        // before mgca is stabilized.
+        //
+        // FIXME(BoxyUwU): Enabling this by default is blocked on a refactoring to how const items
+        // are represented.
+        if tcx.features().min_generic_const_args() {
+            let uv = match ct.kind() {
+                ty::ConstKind::Unevaluated(uv) => uv,
+                _ => return ct.super_fold_with(self),
+            };
+
+            let ct = match tcx.def_kind(uv.def) {
+                DefKind::AssocConst => match tcx.def_kind(tcx.parent(uv.def)) {
+                    DefKind::Trait => self.normalize_trait_projection(uv.into()),
+                    DefKind::Impl { of_trait: false } => {
+                        self.normalize_inherent_projection(uv.into())
+                    }
+                    kind => unreachable!(
+                        "unexpected `DefKind` for const alias' resolution's parent def: {:?}",
+                        kind
+                    ),
+                },
+                DefKind::Const | DefKind::AnonConst => self.normalize_free_alias(uv.into()),
+                kind => {
+                    unreachable!("unexpected `DefKind` for const alias to resolve to: {:?}", kind)
+                }
+            };
+
+            // We re-fold the normalized const as the `ty` field on `ConstKind::Value` may be
+            // unnormalized after const evaluation returns.
+            ct.expect_const().super_fold_with(self)
         } else {
-            let constant = constant.super_fold_with(self);
-            debug!(?constant, ?self.param_env);
-            with_replaced_escaping_bound_vars(
+            let ct = ct.super_fold_with(self);
+            return super::with_replaced_escaping_bound_vars(
                 self.selcx.infcx,
                 &mut self.universes,
-                constant,
-                |constant| super::evaluate_const(self.selcx.infcx, constant, self.param_env),
+                ct,
+                |ct| super::evaluate_const(self.selcx.infcx, ct, self.param_env),
             )
-            .super_fold_with(self)
+            .super_fold_with(self);
+            // We re-fold the normalized const as the `ty` field on `ConstKind::Value` may be
+            // unnormalized after const evaluation returns.
         }
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index dd868c9d40e..ca58da5ca6d 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -5,7 +5,6 @@ use std::ops::ControlFlow;
 use rustc_data_structures::sso::SsoHashSet;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::ErrorGuaranteed;
-use rustc_hir::def::DefKind;
 use rustc_hir::lang_items::LangItem;
 use rustc_infer::infer::DefineOpaqueTypes;
 use rustc_infer::infer::resolve::OpportunisticRegionResolver;
@@ -172,6 +171,7 @@ pub(super) enum ProjectAndUnifyResult<'tcx> {
 /// ```
 /// If successful, this may result in additional obligations. Also returns
 /// the projection cache key used to track these additional obligations.
+// FIXME(mgca): While this supports constants, it is only used for types by default right now
 #[instrument(level = "debug", skip(selcx))]
 pub(super) fn poly_project_and_unify_term<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
@@ -201,6 +201,7 @@ pub(super) fn poly_project_and_unify_term<'cx, 'tcx>(
 /// If successful, this may result in additional obligations.
 ///
 /// See [poly_project_and_unify_term] for an explanation of the return value.
+// FIXME(mgca): While this supports constants, it is only used for types by default right now
 #[instrument(level = "debug", skip(selcx))]
 fn project_and_unify_term<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
@@ -258,34 +259,28 @@ fn project_and_unify_term<'cx, 'tcx>(
 /// there are unresolved type variables in the projection, we will
 /// instantiate it with a fresh type variable `$X` and generate a new
 /// obligation `<T as Trait>::Item == $X` for later.
-pub fn normalize_projection_ty<'a, 'b, 'tcx>(
+// FIXME(mgca): While this supports constants, it is only used for types by default right now
+pub fn normalize_projection_term<'a, 'b, 'tcx>(
     selcx: &'a mut SelectionContext<'b, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
-    projection_ty: ty::AliasTy<'tcx>,
+    alias_term: ty::AliasTerm<'tcx>,
     cause: ObligationCause<'tcx>,
     depth: usize,
     obligations: &mut PredicateObligations<'tcx>,
 ) -> Term<'tcx> {
-    opt_normalize_projection_term(
-        selcx,
-        param_env,
-        projection_ty.into(),
-        cause.clone(),
-        depth,
-        obligations,
-    )
-    .ok()
-    .flatten()
-    .unwrap_or_else(move || {
-        // if we bottom out in ambiguity, create a type variable
-        // and a deferred predicate to resolve this when more type
-        // information is available.
-
-        selcx
-            .infcx
-            .projection_ty_to_infer(param_env, projection_ty, cause, depth + 1, obligations)
-            .into()
-    })
+    opt_normalize_projection_term(selcx, param_env, alias_term, cause.clone(), depth, obligations)
+        .ok()
+        .flatten()
+        .unwrap_or_else(move || {
+            // if we bottom out in ambiguity, create a type variable
+            // and a deferred predicate to resolve this when more type
+            // information is available.
+
+            selcx
+                .infcx
+                .projection_term_to_infer(param_env, alias_term, cause, depth + 1, obligations)
+                .into()
+        })
 }
 
 /// The guts of `normalize`: normalize a specific projection like `<T
@@ -298,6 +293,7 @@ pub fn normalize_projection_ty<'a, 'b, 'tcx>(
 /// often immediately appended to another obligations vector. So now this
 /// function takes an obligations vector and appends to it directly, which is
 /// slightly uglier but avoids the need for an extra short-lived allocation.
+// FIXME(mgca): While this supports constants, it is only used for types by default right now
 #[instrument(level = "debug", skip(selcx, param_env, cause, obligations))]
 pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>(
     selcx: &'a mut SelectionContext<'b, 'tcx>,
@@ -456,6 +452,7 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>(
 /// an error for this obligation, but we legitimately should not,
 /// because it contains `[type error]`. Yuck! (See issue #29857 for
 /// one case where this arose.)
+// FIXME(mgca): While this supports constants, it is only used for types by default right now
 fn normalize_to_error<'a, 'tcx>(
     selcx: &SelectionContext<'a, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
@@ -469,9 +466,10 @@ fn normalize_to_error<'a, 'tcx>(
         | ty::AliasTermKind::InherentTy
         | ty::AliasTermKind::OpaqueTy
         | ty::AliasTermKind::FreeTy => selcx.infcx.next_ty_var(cause.span).into(),
-        ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => {
-            selcx.infcx.next_const_var(cause.span).into()
-        }
+        ty::AliasTermKind::FreeConst
+        | ty::AliasTermKind::InherentConst
+        | ty::AliasTermKind::UnevaluatedConst
+        | ty::AliasTermKind::ProjectionConst => selcx.infcx.next_const_var(cause.span).into(),
     };
     let mut obligations = PredicateObligations::new();
     obligations.push(Obligation {
@@ -484,36 +482,37 @@ fn normalize_to_error<'a, 'tcx>(
 }
 
 /// Confirm and normalize the given inherent projection.
+// FIXME(mgca): While this supports constants, it is only used for types by default right now
 #[instrument(level = "debug", skip(selcx, param_env, cause, obligations))]
 pub fn normalize_inherent_projection<'a, 'b, 'tcx>(
     selcx: &'a mut SelectionContext<'b, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
-    alias_ty: ty::AliasTy<'tcx>,
+    alias_term: ty::AliasTerm<'tcx>,
     cause: ObligationCause<'tcx>,
     depth: usize,
     obligations: &mut PredicateObligations<'tcx>,
-) -> Ty<'tcx> {
+) -> ty::Term<'tcx> {
     let tcx = selcx.tcx();
 
     if !tcx.recursion_limit().value_within_limit(depth) {
         // Halt compilation because it is important that overflows never be masked.
         tcx.dcx().emit_fatal(InherentProjectionNormalizationOverflow {
             span: cause.span,
-            ty: alias_ty.to_string(),
+            ty: alias_term.to_string(),
         });
     }
 
-    let args = compute_inherent_assoc_ty_args(
+    let args = compute_inherent_assoc_term_args(
         selcx,
         param_env,
-        alias_ty,
+        alias_term,
         cause.clone(),
         depth,
         obligations,
     );
 
     // Register the obligations arising from the impl and from the associated type itself.
-    let predicates = tcx.predicates_of(alias_ty.def_id).instantiate(tcx, args);
+    let predicates = tcx.predicates_of(alias_term.def_id).instantiate(tcx, args);
     for (predicate, span) in predicates {
         let predicate = normalize_with_depth_to(
             selcx,
@@ -531,7 +530,7 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>(
             // cause code, inherent projections will be printed with identity instantiation in
             // diagnostics which is not ideal.
             // Consider creating separate cause codes for this specific situation.
-            ObligationCauseCode::WhereClause(alias_ty.def_id, span),
+            ObligationCauseCode::WhereClause(alias_term.def_id, span),
         );
 
         obligations.push(Obligation::with_depth(
@@ -543,27 +542,33 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>(
         ));
     }
 
-    let ty = tcx.type_of(alias_ty.def_id).instantiate(tcx, args);
+    let term: Term<'tcx> = if alias_term.kind(tcx).is_type() {
+        tcx.type_of(alias_term.def_id).instantiate(tcx, args).into()
+    } else {
+        get_associated_const_value(selcx, alias_term.to_term(tcx).expect_const(), param_env).into()
+    };
 
-    let mut ty = selcx.infcx.resolve_vars_if_possible(ty);
-    if ty.has_aliases() {
-        ty = normalize_with_depth_to(selcx, param_env, cause.clone(), depth + 1, ty, obligations);
+    let mut term = selcx.infcx.resolve_vars_if_possible(term);
+    if term.has_aliases() {
+        term =
+            normalize_with_depth_to(selcx, param_env, cause.clone(), depth + 1, term, obligations);
     }
 
-    ty
+    term
 }
 
-pub fn compute_inherent_assoc_ty_args<'a, 'b, 'tcx>(
+// FIXME(mgca): While this supports constants, it is only used for types by default right now
+pub fn compute_inherent_assoc_term_args<'a, 'b, 'tcx>(
     selcx: &'a mut SelectionContext<'b, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
-    alias_ty: ty::AliasTy<'tcx>,
+    alias_term: ty::AliasTerm<'tcx>,
     cause: ObligationCause<'tcx>,
     depth: usize,
     obligations: &mut PredicateObligations<'tcx>,
 ) -> ty::GenericArgsRef<'tcx> {
     let tcx = selcx.tcx();
 
-    let impl_def_id = tcx.parent(alias_ty.def_id);
+    let impl_def_id = tcx.parent(alias_term.def_id);
     let impl_args = selcx.infcx.fresh_args_for_item(cause.span, impl_def_id);
 
     let mut impl_ty = tcx.type_of(impl_def_id).instantiate(tcx, impl_args);
@@ -580,7 +585,7 @@ pub fn compute_inherent_assoc_ty_args<'a, 'b, 'tcx>(
 
     // Infer the generic parameters of the impl by unifying the
     // impl type with the self type of the projection.
-    let mut self_ty = alias_ty.self_ty();
+    let mut self_ty = alias_term.self_ty();
     if !selcx.infcx.next_trait_solver() {
         self_ty = normalize_with_depth_to(
             selcx,
@@ -602,7 +607,7 @@ pub fn compute_inherent_assoc_ty_args<'a, 'b, 'tcx>(
         }
     }
 
-    alias_ty.rebase_inherent_args_onto_impl(impl_args, tcx)
+    alias_term.rebase_inherent_args_onto_impl(impl_args, tcx)
 }
 
 enum Projected<'tcx> {
@@ -630,6 +635,7 @@ impl<'tcx> Progress<'tcx> {
 ///
 /// IMPORTANT:
 /// - `obligation` must be fully normalized
+// FIXME(mgca): While this supports constants, it is only used for types by default right now
 #[instrument(level = "info", skip(selcx))]
 fn project<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
@@ -896,7 +902,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
             ImplSource::UserDefined(impl_data) => {
                 // We have to be careful when projecting out of an
                 // impl because of specialization. If we are not in
-                // codegen (i.e., projection mode is not "any"), and the
+                // codegen (i.e., `TypingMode` is not `PostAnalysis`), and the
                 // impl's type is declared as default, then we disable
                 // projection (even if the trait ref is fully
                 // monomorphic). In the case where trait ref is not
@@ -1189,6 +1195,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
     });
 }
 
+// FIXME(mgca): While this supports constants, it is only used for types by default right now
 fn confirm_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTermObligation<'tcx>,
@@ -1222,6 +1229,7 @@ fn confirm_candidate<'cx, 'tcx>(
     result
 }
 
+// FIXME(mgca): While this supports constants, it is only used for types by default right now
 fn confirm_select_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTermObligation<'tcx>,
@@ -1873,6 +1881,7 @@ fn confirm_async_fn_kind_helper_candidate<'cx, 'tcx>(
         .with_addl_obligations(nested)
 }
 
+// FIXME(mgca): While this supports constants, it is only used for types by default right now
 fn confirm_param_env_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTermObligation<'tcx>,
@@ -1926,9 +1935,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
     ) {
         Ok(InferOk { value: _, obligations }) => {
             nested_obligations.extend(obligations);
-            assoc_ty_own_obligations(selcx, obligation, &mut nested_obligations);
-            // FIXME(associated_const_equality): Handle consts here as well? Maybe this progress type should just take
-            // a term instead.
+            assoc_term_own_obligations(selcx, obligation, &mut nested_obligations);
             Progress { term: cache_entry.term, obligations: nested_obligations }
         }
         Err(e) => {
@@ -1942,6 +1949,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
     }
 }
 
+// FIXME(mgca): While this supports constants, it is only used for types by default right now
 fn confirm_impl_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTermObligation<'tcx>,
@@ -1955,8 +1963,8 @@ fn confirm_impl_candidate<'cx, 'tcx>(
     let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap();
 
     let param_env = obligation.param_env;
-    let assoc_ty = match specialization_graph::assoc_def(tcx, impl_def_id, assoc_item_id) {
-        Ok(assoc_ty) => assoc_ty,
+    let assoc_term = match specialization_graph::assoc_def(tcx, impl_def_id, assoc_item_id) {
+        Ok(assoc_term) => assoc_term,
         Err(guar) => return Ok(Projected::Progress(Progress::error(tcx, guar))),
     };
 
@@ -1965,10 +1973,10 @@ fn confirm_impl_candidate<'cx, 'tcx>(
     // has impossible-to-satisfy predicates (since those were
     // allowed in <https://github.com/rust-lang/rust/pull/135480>),
     // or because the impl is literally missing the definition.
-    if !assoc_ty.item.defaultness(tcx).has_value() {
+    if !assoc_term.item.defaultness(tcx).has_value() {
         debug!(
             "confirm_impl_candidate: no associated type {:?} for {:?}",
-            assoc_ty.item.name(),
+            assoc_term.item.name(),
             obligation.predicate
         );
         if tcx.impl_self_is_guaranteed_unsized(impl_def_id) {
@@ -1979,7 +1987,11 @@ fn confirm_impl_candidate<'cx, 'tcx>(
             return Ok(Projected::NoProgress(obligation.predicate.to_term(tcx)));
         } else {
             return Ok(Projected::Progress(Progress {
-                term: Ty::new_misc_error(tcx).into(),
+                term: if obligation.predicate.kind(tcx).is_type() {
+                    Ty::new_misc_error(tcx).into()
+                } else {
+                    ty::Const::new_misc_error(tcx).into()
+                },
                 obligations: nested,
             }));
         }
@@ -1992,27 +2004,32 @@ fn confirm_impl_candidate<'cx, 'tcx>(
     // * `args` is `[u32]`
     // * `args` ends up as `[u32, S]`
     let args = obligation.predicate.args.rebase_onto(tcx, trait_def_id, args);
-    let args = translate_args(selcx.infcx, param_env, impl_def_id, args, assoc_ty.defining_node);
-    let is_const = matches!(tcx.def_kind(assoc_ty.item.def_id), DefKind::AssocConst);
-
-    let term: ty::EarlyBinder<'tcx, ty::Term<'tcx>> = if is_const {
-        let did = assoc_ty.item.def_id;
-        let identity_args = crate::traits::GenericArgs::identity_for_item(tcx, did);
-        let uv = ty::UnevaluatedConst::new(did, identity_args);
-        ty::EarlyBinder::bind(ty::Const::new_unevaluated(tcx, uv).into())
+    let args = translate_args(selcx.infcx, param_env, impl_def_id, args, assoc_term.defining_node);
+
+    let term = if obligation.predicate.kind(tcx).is_type() {
+        tcx.type_of(assoc_term.item.def_id).map_bound(|ty| ty.into())
     } else {
-        tcx.type_of(assoc_ty.item.def_id).map_bound(|ty| ty.into())
+        ty::EarlyBinder::bind(
+            get_associated_const_value(
+                selcx,
+                obligation.predicate.to_term(tcx).expect_const(),
+                param_env,
+            )
+            .into(),
+        )
     };
 
-    let progress = if !tcx.check_args_compatible(assoc_ty.item.def_id, args) {
-        let err = Ty::new_error_with_message(
-            tcx,
-            obligation.cause.span,
-            "impl item and trait item have different parameters",
-        );
-        Progress { term: err.into(), obligations: nested }
+    let progress = if !tcx.check_args_compatible(assoc_term.item.def_id, args) {
+        let msg = "impl item and trait item have different parameters";
+        let span = obligation.cause.span;
+        let err = if obligation.predicate.kind(tcx).is_type() {
+            Ty::new_error_with_message(tcx, span, msg).into()
+        } else {
+            ty::Const::new_error_with_message(tcx, span, msg).into()
+        };
+        Progress { term: err, obligations: nested }
     } else {
-        assoc_ty_own_obligations(selcx, obligation, &mut nested);
+        assoc_term_own_obligations(selcx, obligation, &mut nested);
         Progress { term: term.instantiate(tcx, args), obligations: nested }
     };
     Ok(Projected::Progress(progress))
@@ -2020,7 +2037,8 @@ fn confirm_impl_candidate<'cx, 'tcx>(
 
 // Get obligations corresponding to the predicates from the where-clause of the
 // associated type itself.
-fn assoc_ty_own_obligations<'cx, 'tcx>(
+// FIXME(mgca): While this supports constants, it is only used for types by default right now
+fn assoc_term_own_obligations<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTermObligation<'tcx>,
     nested: &mut PredicateObligations<'tcx>,
@@ -2090,3 +2108,15 @@ impl<'cx, 'tcx> ProjectionCacheKeyExt<'cx, 'tcx> for ProjectionCacheKey<'tcx> {
         })
     }
 }
+
+fn get_associated_const_value<'tcx>(
+    selcx: &mut SelectionContext<'_, 'tcx>,
+    alias_ct: ty::Const<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+) -> ty::Const<'tcx> {
+    // FIXME(mgca): We shouldn't be invoking ctfe here, instead const items should be aliases to type
+    // system consts that we can retrieve with some `query const_arg_of_alias` query. Evaluating the
+    // constant is "close enough" to getting the actual rhs of the const item for now even if it might
+    // lead to some cycles
+    super::evaluate_const(selcx.infcx, alias_ct, param_env)
+}
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index a54eb80fedc..eb34cb10c68 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -9,7 +9,7 @@ use rustc_macros::extension;
 pub use rustc_middle::traits::query::NormalizationResult;
 use rustc_middle::ty::{
     self, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable,
-    TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode,
+    TypeVisitableExt, TypeVisitor, TypingMode,
 };
 use rustc_span::DUMMY_SP;
 use tracing::{debug, info, instrument};
@@ -127,7 +127,7 @@ struct MaxEscapingBoundVarVisitor {
 }
 
 impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxEscapingBoundVarVisitor {
-    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
+    fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
         self.outer_index.shift_in(1);
         t.super_visit_with(self);
         self.outer_index.shift_out(1);
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 8008c7e4d34..94190cd3ae3 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -406,7 +406,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
 
         let mut assume = predicate.trait_ref.args.const_at(2);
-        // FIXME(mgca): We should shallowly normalize this.
         if self.tcx().features().generic_const_exprs() {
             assume = crate::traits::evaluate_const(self.infcx, assume, obligation.param_env)
         }
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 2e32cda7602..08d3b92e9b5 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -6,6 +6,7 @@
 use std::iter;
 
 use rustc_hir as hir;
+use rustc_hir::def::DefKind;
 use rustc_hir::lang_items::LangItem;
 use rustc_infer::traits::{ObligationCauseCode, PredicateObligations};
 use rustc_middle::bug;
@@ -486,7 +487,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
     /// Pushes the obligations required for an inherent alias to be WF
     /// into `self.out`.
     // FIXME(inherent_associated_types): Merge this function with `fn compute_alias`.
-    fn add_wf_preds_for_inherent_projection(&mut self, data: ty::AliasTy<'tcx>) {
+    fn add_wf_preds_for_inherent_projection(&mut self, data: ty::AliasTerm<'tcx>) {
         // An inherent projection is well-formed if
         //
         // (a) its predicates hold (*)
@@ -498,7 +499,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
         if !data.self_ty().has_escaping_bound_vars() {
             // FIXME(inherent_associated_types): Should this happen inside of a snapshot?
             // FIXME(inherent_associated_types): This is incompatible with the new solver and lazy norm!
-            let args = traits::project::compute_inherent_assoc_ty_args(
+            let args = traits::project::compute_inherent_assoc_term_args(
                 &mut traits::SelectionContext::new(self.infcx),
                 self.param_env,
                 data,
@@ -776,7 +777,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
                 self.out.extend(obligations);
             }
             ty::Alias(ty::Inherent, data) => {
-                self.add_wf_preds_for_inherent_projection(data);
+                self.add_wf_preds_for_inherent_projection(data.into());
                 return; // Subtree handled by compute_inherent_projection.
             }
 
@@ -961,9 +962,6 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
         match c.kind() {
             ty::ConstKind::Unevaluated(uv) => {
                 if !c.has_escaping_bound_vars() {
-                    let obligations = self.nominal_obligations(uv.def, uv.args);
-                    self.out.extend(obligations);
-
                     let predicate = ty::Binder::dummy(ty::PredicateKind::Clause(
                         ty::ClauseKind::ConstEvaluatable(c),
                     ));
@@ -975,6 +973,16 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
                         self.param_env,
                         predicate,
                     ));
+
+                    if tcx.def_kind(uv.def) == DefKind::AssocConst
+                        && tcx.def_kind(tcx.parent(uv.def)) == (DefKind::Impl { of_trait: false })
+                    {
+                        self.add_wf_preds_for_inherent_projection(uv.into());
+                        return; // Subtree is handled by above function
+                    } else {
+                        let obligations = self.nominal_obligations(uv.def, uv.args);
+                        self.out.extend(obligations);
+                    }
                 }
             }
             ty::ConstKind::Infer(_) => {
diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs
index 14a92ebb9f9..e52898cc6e2 100644
--- a/compiler/rustc_traits/src/normalize_projection_ty.rs
+++ b/compiler/rustc_traits/src/normalize_projection_ty.rs
@@ -32,8 +32,14 @@ fn normalize_canonicalized_projection_ty<'tcx>(
             let selcx = &mut SelectionContext::new(ocx.infcx);
             let cause = ObligationCause::dummy();
             let mut obligations = PredicateObligations::new();
-            let answer =
-                traits::normalize_projection_ty(selcx, param_env, goal, cause, 0, &mut obligations);
+            let answer = traits::normalize_projection_term(
+                selcx,
+                param_env,
+                goal.into(),
+                cause,
+                0,
+                &mut obligations,
+            );
             ocx.register_obligations(obligations);
             // #112047: With projections and opaques, we are able to create opaques that
             // are recursive (given some generic parameters of the opaque's type variables).
@@ -104,14 +110,14 @@ fn normalize_canonicalized_inherent_projection_ty<'tcx>(
             let answer = traits::normalize_inherent_projection(
                 selcx,
                 param_env,
-                goal,
+                goal.into(),
                 cause,
                 0,
                 &mut obligations,
             );
             ocx.register_obligations(obligations);
 
-            Ok(NormalizationResult { normalized_ty: answer })
+            Ok(NormalizationResult { normalized_ty: answer.expect_type() })
         },
     )
 }
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index 6cb9fdc6f93..f14a45aa1e3 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -1,6 +1,7 @@
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
+use rustc_hir::definitions::{DefPathData, DisambiguatorState};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{self as hir, AmbigArg};
 use rustc_middle::query::Providers;
@@ -159,6 +160,22 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A
         container: ty::AssocItemContainer::Impl,
     }
 }
+struct RPITVisitor {
+    rpits: FxIndexSet<LocalDefId>,
+}
+
+impl<'tcx> Visitor<'tcx> for RPITVisitor {
+    fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
+        if let hir::TyKind::OpaqueDef(opaq) = ty.kind
+            && self.rpits.insert(opaq.def_id)
+        {
+            for bound in opaq.bounds {
+                intravisit::walk_param_bound(self, bound);
+            }
+        }
+        intravisit::walk_ty(self, ty)
+    }
+}
 
 /// Given an `fn_def_id` of a trait or a trait implementation:
 ///
@@ -177,23 +194,6 @@ fn associated_types_for_impl_traits_in_associated_fn(
 
     match tcx.def_kind(parent_def_id) {
         DefKind::Trait => {
-            struct RPITVisitor {
-                rpits: FxIndexSet<LocalDefId>,
-            }
-
-            impl<'tcx> Visitor<'tcx> for RPITVisitor {
-                fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
-                    if let hir::TyKind::OpaqueDef(opaq) = ty.kind
-                        && self.rpits.insert(opaq.def_id)
-                    {
-                        for bound in opaq.bounds {
-                            intravisit::walk_param_bound(self, bound);
-                        }
-                    }
-                    intravisit::walk_ty(self, ty)
-                }
-            }
-
             let mut visitor = RPITVisitor { rpits: FxIndexSet::default() };
 
             if let Some(output) = tcx.hir_get_fn_output(fn_def_id) {
@@ -246,9 +246,23 @@ fn associated_type_for_impl_trait_in_trait(
     let trait_def_id = tcx.local_parent(fn_def_id);
     assert_eq!(tcx.def_kind(trait_def_id), DefKind::Trait);
 
+    // Collect all opaque types in return position for the method and use
+    // the index as the disambiguator to make an unique def path.
+    let mut visitor = RPITVisitor { rpits: FxIndexSet::default() };
+    visitor.visit_fn_ret_ty(tcx.hir_get_fn_output(fn_def_id).unwrap());
+    let disambiguator = visitor.rpits.get_index_of(&opaque_ty_def_id).unwrap().try_into().unwrap();
+
     let span = tcx.def_span(opaque_ty_def_id);
-    // No name because this is an anonymous associated type.
-    let trait_assoc_ty = tcx.at(span).create_def(trait_def_id, None, DefKind::AssocTy);
+    // Also use the method name to create an unique def path.
+    let data = DefPathData::AnonAssocTy(tcx.item_name(fn_def_id.to_def_id()));
+    let trait_assoc_ty = tcx.at(span).create_def(
+        trait_def_id,
+        // No name because this is an anonymous associated type.
+        None,
+        DefKind::AssocTy,
+        Some(data),
+        &mut DisambiguatorState::with(trait_def_id, data, disambiguator),
+    );
 
     let local_def_id = trait_assoc_ty.def_id();
     let def_id = local_def_id.to_def_id();
@@ -299,8 +313,22 @@ fn associated_type_for_impl_trait_in_impl(
         hir::FnRetTy::DefaultReturn(_) => tcx.def_span(impl_fn_def_id),
         hir::FnRetTy::Return(ty) => ty.span,
     };
-    // No name because this is an anonymous associated type.
-    let impl_assoc_ty = tcx.at(span).create_def(impl_local_def_id, None, DefKind::AssocTy);
+
+    // Use the same disambiguator and method name as the anon associated type in the trait.
+    let disambiguated_data = tcx.def_key(trait_assoc_def_id).disambiguated_data;
+    let DefPathData::AnonAssocTy(name) = disambiguated_data.data else {
+        bug!("expected anon associated type")
+    };
+    let data = DefPathData::AnonAssocTy(name);
+
+    let impl_assoc_ty = tcx.at(span).create_def(
+        impl_local_def_id,
+        // No name because this is an anonymous associated type.
+        None,
+        DefKind::AssocTy,
+        Some(data),
+        &mut DisambiguatorState::with(impl_local_def_id, data, disambiguated_data.disambiguator),
+    );
 
     let local_def_id = impl_assoc_ty.def_id();
     let def_id = local_def_id.to_def_id();
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index da83566dad0..166e8f19342 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -235,7 +235,7 @@ fn resolve_associated_item<'tcx>(
                 tcx.ensure_ok().compare_impl_item(leaf_def_item)?;
             }
 
-            Some(ty::Instance::new(leaf_def.item.def_id, args))
+            Some(ty::Instance::new_raw(leaf_def.item.def_id, args))
         }
         traits::ImplSource::Builtin(BuiltinImplSource::Object(_), _) => {
             let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_args);
@@ -280,7 +280,7 @@ fn resolve_associated_item<'tcx>(
 
                     // Use the default `fn clone_from` from `trait Clone`.
                     let args = tcx.erase_regions(rcvr_args);
-                    Some(ty::Instance::new(trait_item_id, args))
+                    Some(ty::Instance::new_raw(trait_item_id, args))
                 }
             } else if tcx.is_lang_item(trait_ref.def_id, LangItem::FnPtrTrait) {
                 if tcx.is_lang_item(trait_item_id, LangItem::FnPtrAddr) {
@@ -329,7 +329,7 @@ fn resolve_associated_item<'tcx>(
                         // sync with the built-in trait implementations (since all of the
                         // implementations return `FnOnce::Output`).
                         if ty::ClosureKind::FnOnce == args.as_coroutine_closure().kind() {
-                            Some(Instance::new(coroutine_closure_def_id, args))
+                            Some(Instance::new_raw(coroutine_closure_def_id, args))
                         } else {
                             Some(Instance {
                                 def: ty::InstanceKind::ConstructCoroutineInClosureShim {
@@ -362,7 +362,7 @@ fn resolve_associated_item<'tcx>(
                                 args,
                             })
                         } else {
-                            Some(Instance::new(coroutine_closure_def_id, args))
+                            Some(Instance::new_raw(coroutine_closure_def_id, args))
                         }
                     }
                     ty::Closure(closure_def_id, args) => {
@@ -381,7 +381,7 @@ fn resolve_associated_item<'tcx>(
                 let name = tcx.item_name(trait_item_id);
                 assert_eq!(name, sym::transmute);
                 let args = tcx.erase_regions(rcvr_args);
-                Some(ty::Instance::new(trait_item_id, args))
+                Some(ty::Instance::new_raw(trait_item_id, args))
             } else {
                 Instance::try_resolve_item_for_coroutine(tcx, trait_item_id, trait_id, rcvr_args)
             }
diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs
index ea0f6b8dfba..f79b6d44bfd 100644
--- a/compiler/rustc_ty_utils/src/lib.rs
+++ b/compiler/rustc_ty_utils/src/lib.rs
@@ -29,10 +29,10 @@ mod implied_bounds;
 mod instance;
 mod layout;
 mod needs_drop;
+mod nested_bodies;
 mod opaque_types;
 mod representability;
 pub mod sig_types;
-mod stalled_generators;
 mod structural_match;
 mod ty;
 
@@ -51,5 +51,5 @@ pub fn provide(providers: &mut Providers) {
     ty::provide(providers);
     instance::provide(providers);
     structural_match::provide(providers);
-    stalled_generators::provide(providers);
+    nested_bodies::provide(providers);
 }
diff --git a/compiler/rustc_ty_utils/src/nested_bodies.rs b/compiler/rustc_ty_utils/src/nested_bodies.rs
new file mode 100644
index 00000000000..7c74d8eb635
--- /dev/null
+++ b/compiler/rustc_ty_utils/src/nested_bodies.rs
@@ -0,0 +1,34 @@
+use rustc_hir as hir;
+use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::intravisit::Visitor;
+use rustc_middle::query::Providers;
+use rustc_middle::ty::{self, TyCtxt};
+
+fn nested_bodies_within<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx ty::List<LocalDefId> {
+    let body = tcx.hir_body_owned_by(item);
+    let mut collector =
+        NestedBodiesVisitor { tcx, root_def_id: item.to_def_id(), nested_bodies: vec![] };
+    collector.visit_body(body);
+    tcx.mk_local_def_ids(&collector.nested_bodies)
+}
+
+struct NestedBodiesVisitor<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    root_def_id: DefId,
+    nested_bodies: Vec<LocalDefId>,
+}
+
+impl<'tcx> Visitor<'tcx> for NestedBodiesVisitor<'tcx> {
+    fn visit_nested_body(&mut self, id: hir::BodyId) {
+        let body_def_id = self.tcx.hir_body_owner_def_id(id);
+        if self.tcx.typeck_root_def_id(body_def_id.to_def_id()) == self.root_def_id {
+            self.nested_bodies.push(body_def_id);
+            let body = self.tcx.hir_body(id);
+            self.visit_body(body);
+        }
+    }
+}
+
+pub(super) fn provide(providers: &mut Providers) {
+    *providers = Providers { nested_bodies_within, ..*providers };
+}
diff --git a/compiler/rustc_ty_utils/src/stalled_generators.rs b/compiler/rustc_ty_utils/src/stalled_generators.rs
deleted file mode 100644
index 8b45e8b0f6f..00000000000
--- a/compiler/rustc_ty_utils/src/stalled_generators.rs
+++ /dev/null
@@ -1,54 +0,0 @@
-use rustc_hir as hir;
-use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::intravisit;
-use rustc_hir::intravisit::Visitor;
-use rustc_middle::query::Providers;
-use rustc_middle::ty::{self, TyCtxt};
-
-fn stalled_generators_within<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    item: LocalDefId,
-) -> &'tcx ty::List<LocalDefId> {
-    if !tcx.next_trait_solver_globally() {
-        return ty::List::empty();
-    }
-
-    let body = tcx.hir_body_owned_by(item);
-    let mut collector =
-        StalledGeneratorVisitor { tcx, root_def_id: item.to_def_id(), stalled_coroutines: vec![] };
-    collector.visit_body(body);
-    tcx.mk_local_def_ids(&collector.stalled_coroutines)
-}
-
-struct StalledGeneratorVisitor<'tcx> {
-    tcx: TyCtxt<'tcx>,
-    root_def_id: DefId,
-    stalled_coroutines: Vec<LocalDefId>,
-}
-
-impl<'tcx> Visitor<'tcx> for StalledGeneratorVisitor<'tcx> {
-    fn visit_nested_body(&mut self, id: hir::BodyId) {
-        if self.tcx.typeck_root_def_id(self.tcx.hir_body_owner_def_id(id).to_def_id())
-            == self.root_def_id
-        {
-            let body = self.tcx.hir_body(id);
-            self.visit_body(body);
-        }
-    }
-
-    fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
-        if let hir::ExprKind::Closure(&hir::Closure {
-            def_id,
-            kind: hir::ClosureKind::Coroutine(_),
-            ..
-        }) = ex.kind
-        {
-            self.stalled_coroutines.push(def_id);
-        }
-        intravisit::walk_expr(self, ex);
-    }
-}
-
-pub(super) fn provide(providers: &mut Providers) {
-    *providers = Providers { stalled_generators_within, ..*providers };
-}
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 31d69eef5ec..0c49ddff39b 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -7,7 +7,8 @@ use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{
-    self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast, fold_regions,
+    self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast,
+    fold_regions,
 };
 use rustc_span::DUMMY_SP;
 use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
@@ -185,7 +186,7 @@ struct ImplTraitInTraitFinder<'a, 'tcx> {
 }
 
 impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
-    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, binder: &ty::Binder<'tcx, T>) {
+    fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, binder: &ty::Binder<'tcx, T>) {
         self.depth.shift_in(1);
         binder.super_visit_with(self);
         self.depth.shift_out(1);
diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs
index 27ea4e211fe..000cf1e1fd8 100644
--- a/compiler/rustc_type_ir/src/binder.rs
+++ b/compiler/rustc_type_ir/src/binder.rs
@@ -128,7 +128,7 @@ impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Binder<I, T> {
     }
 }
 
-impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Binder<I, T> {
+impl<I: Interner, T: TypeFoldable<I>> TypeVisitable<I> for Binder<I, T> {
     fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
         visitor.visit_binder(self)
     }
@@ -147,7 +147,7 @@ impl<I: Interner, T: TypeFoldable<I>> TypeSuperFoldable<I> for Binder<I, T> {
     }
 }
 
-impl<I: Interner, T: TypeVisitable<I>> TypeSuperVisitable<I> for Binder<I, T> {
+impl<I: Interner, T: TypeFoldable<I>> TypeSuperVisitable<I> for Binder<I, T> {
     fn super_visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
         self.as_ref().skip_binder().visit_with(visitor)
     }
@@ -292,7 +292,7 @@ impl<I: Interner> ValidateBoundVars<I> {
 impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
     type Result = ControlFlow<()>;
 
-    fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &Binder<I, T>) -> Self::Result {
+    fn visit_binder<T: TypeFoldable<I>>(&mut self, t: &Binder<I, T>) -> Self::Result {
         self.binder_index.shift_in(1);
         let result = t.super_visit_with(self);
         self.binder_index.shift_out(1);
diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs
index 8fa56c35999..c1490762117 100644
--- a/compiler/rustc_type_ir/src/infer_ctxt.rs
+++ b/compiler/rustc_type_ir/src/infer_ctxt.rs
@@ -1,3 +1,5 @@
+use std::fmt::Debug;
+
 use derive_where::derive_where;
 #[cfg(feature = "nightly")]
 use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
@@ -100,7 +102,7 @@ impl<I: Interner> TypingMode<I> {
     pub fn typeck_for_body(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> {
         TypingMode::Analysis {
             defining_opaque_types_and_generators: cx
-                .opaque_types_and_generators_defined_by(body_def_id),
+                .opaque_types_and_coroutines_defined_by(body_def_id),
         }
     }
 
@@ -245,4 +247,32 @@ pub trait InferCtxtLike: Sized {
         r: <Self::Interner as Interner>::Region,
         span: <Self::Interner as Interner>::Span,
     );
+
+    type OpaqueTypeStorageEntries: Debug + Copy + Default;
+    fn opaque_types_storage_num_entries(&self) -> Self::OpaqueTypeStorageEntries;
+    fn clone_opaque_types_lookup_table(
+        &self,
+    ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
+    fn clone_duplicate_opaque_types(
+        &self,
+    ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
+    fn clone_opaque_types_added_since(
+        &self,
+        prev_entries: Self::OpaqueTypeStorageEntries,
+    ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
+
+    fn register_hidden_type_in_storage(
+        &self,
+        opaque_type_key: ty::OpaqueTypeKey<Self::Interner>,
+        hidden_ty: <Self::Interner as Interner>::Ty,
+        span: <Self::Interner as Interner>::Span,
+    ) -> Option<<Self::Interner as Interner>::Ty>;
+    fn add_duplicate_opaque_type(
+        &self,
+        opaque_type_key: ty::OpaqueTypeKey<Self::Interner>,
+        hidden_ty: <Self::Interner as Interner>::Ty,
+        span: <Self::Interner as Interner>::Span,
+    );
+
+    fn reset_opaque_types(&self);
 }
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index 6410da1f740..0fd2d9f3ad3 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -341,7 +341,7 @@ pub trait Interner:
 
     fn opaque_types_defined_by(self, defining_anchor: Self::LocalDefId) -> Self::LocalDefIds;
 
-    fn opaque_types_and_generators_defined_by(
+    fn opaque_types_and_coroutines_defined_by(
         self,
         defining_anchor: Self::LocalDefId,
     ) -> Self::LocalDefIds;
diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs
index 0411c5c2325..b59495b93c8 100644
--- a/compiler/rustc_type_ir/src/predicate.rs
+++ b/compiler/rustc_type_ir/src/predicate.rs
@@ -474,10 +474,15 @@ pub enum AliasTermKind {
     /// Currently only used if the type alias references opaque types.
     /// Can always be normalized away.
     FreeTy,
-    /// An unevaluated const coming from a generic const expression.
+
+    /// An unevaluated anonymous constants.
     UnevaluatedConst,
     /// An unevaluated const coming from an associated const.
     ProjectionConst,
+    /// A top level const item not part of a trait or impl.
+    FreeConst,
+    /// An associated const in an inherent `impl`
+    InherentConst,
 }
 
 impl AliasTermKind {
@@ -486,11 +491,27 @@ impl AliasTermKind {
             AliasTermKind::ProjectionTy => "associated type",
             AliasTermKind::ProjectionConst => "associated const",
             AliasTermKind::InherentTy => "inherent associated type",
+            AliasTermKind::InherentConst => "inherent associated const",
             AliasTermKind::OpaqueTy => "opaque type",
             AliasTermKind::FreeTy => "type alias",
+            AliasTermKind::FreeConst => "unevaluated constant",
             AliasTermKind::UnevaluatedConst => "unevaluated constant",
         }
     }
+
+    pub fn is_type(self) -> bool {
+        match self {
+            AliasTermKind::ProjectionTy
+            | AliasTermKind::InherentTy
+            | AliasTermKind::OpaqueTy
+            | AliasTermKind::FreeTy => true,
+
+            AliasTermKind::UnevaluatedConst
+            | AliasTermKind::ProjectionConst
+            | AliasTermKind::InherentConst
+            | AliasTermKind::FreeConst => false,
+        }
+    }
 }
 
 impl From<ty::AliasTyKind> for AliasTermKind {
@@ -566,7 +587,10 @@ impl<I: Interner> AliasTerm<I> {
             | AliasTermKind::InherentTy
             | AliasTermKind::OpaqueTy
             | AliasTermKind::FreeTy => {}
-            AliasTermKind::UnevaluatedConst | AliasTermKind::ProjectionConst => {
+            AliasTermKind::InherentConst
+            | AliasTermKind::FreeConst
+            | AliasTermKind::UnevaluatedConst
+            | AliasTermKind::ProjectionConst => {
                 panic!("Cannot turn `UnevaluatedConst` into `AliasTy`")
             }
         }
@@ -603,18 +627,19 @@ impl<I: Interner> AliasTerm<I> {
                 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
             )
             .into(),
-            AliasTermKind::UnevaluatedConst | AliasTermKind::ProjectionConst => {
-                I::Const::new_unevaluated(
-                    interner,
-                    ty::UnevaluatedConst::new(self.def_id, self.args),
-                )
-                .into()
-            }
+            AliasTermKind::FreeConst
+            | AliasTermKind::InherentConst
+            | AliasTermKind::UnevaluatedConst
+            | AliasTermKind::ProjectionConst => I::Const::new_unevaluated(
+                interner,
+                ty::UnevaluatedConst::new(self.def_id, self.args),
+            )
+            .into(),
         }
     }
 }
 
-/// The following methods work only with (trait) associated type projections.
+/// The following methods work only with (trait) associated term projections.
 impl<I: Interner> AliasTerm<I> {
     pub fn self_ty(self) -> I::Ty {
         self.args.type_at(0)
@@ -659,6 +684,31 @@ impl<I: Interner> AliasTerm<I> {
     }
 }
 
+/// The following methods work only with inherent associated term projections.
+impl<I: Interner> AliasTerm<I> {
+    /// Transform the generic parameters to have the given `impl` args as the base and the GAT args on top of that.
+    ///
+    /// Does the following transformation:
+    ///
+    /// ```text
+    /// [Self, P_0...P_m] -> [I_0...I_n, P_0...P_m]
+    ///
+    ///     I_i impl args
+    ///     P_j GAT args
+    /// ```
+    pub fn rebase_inherent_args_onto_impl(
+        self,
+        impl_args: I::GenericArgs,
+        interner: I,
+    ) -> I::GenericArgs {
+        debug_assert!(matches!(
+            self.kind(interner),
+            AliasTermKind::InherentTy | AliasTermKind::InherentConst
+        ));
+        interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1)))
+    }
+}
+
 impl<I: Interner> From<ty::AliasTy<I>> for AliasTerm<I> {
     fn from(ty: ty::AliasTy<I>) -> Self {
         AliasTerm { args: ty.args, def_id: ty.def_id, _use_alias_term_new_instead: () }
diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs
index c80a567117c..e3c4a793b37 100644
--- a/compiler/rustc_type_ir/src/relate.rs
+++ b/compiler/rustc_type_ir/src/relate.rs
@@ -273,8 +273,10 @@ impl<I: Interner> Relate<I> for ty::AliasTerm<I> {
                     false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
                 )?,
                 ty::AliasTermKind::ProjectionTy
+                | ty::AliasTermKind::FreeConst
                 | ty::AliasTermKind::FreeTy
                 | ty::AliasTermKind::InherentTy
+                | ty::AliasTermKind::InherentConst
                 | ty::AliasTermKind::UnevaluatedConst
                 | ty::AliasTermKind::ProjectionConst => {
                     relate_args_invariantly(relation, a.args, b.args)?
diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs
index 4e9b87fdf74..2e05c23a645 100644
--- a/compiler/rustc_type_ir/src/solve/mod.rs
+++ b/compiler/rustc_type_ir/src/solve/mod.rs
@@ -147,9 +147,8 @@ pub enum CandidateSource<I: Interner> {
     /// For a list of all traits with builtin impls, check out the
     /// `EvalCtxt::assemble_builtin_impl_candidates` method.
     BuiltinImpl(BuiltinImplSource),
-    /// An assumption from the environment.
-    ///
-    /// More precisely we've used the `n-th` assumption in the `param_env`.
+    /// An assumption from the environment. Stores a [`ParamEnvSource`], since we
+    /// prefer non-global param-env candidates in candidate assembly.
     ///
     /// ## Examples
     ///
@@ -160,7 +159,7 @@ pub enum CandidateSource<I: Interner> {
     ///     (x.clone(), x)
     /// }
     /// ```
-    ParamEnv(usize),
+    ParamEnv(ParamEnvSource),
     /// If the self type is an alias type, e.g. an opaque type or a projection,
     /// we know the bounds on that alias to hold even without knowing its concrete
     /// underlying type.
@@ -190,6 +189,14 @@ pub enum CandidateSource<I: Interner> {
 }
 
 #[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
+pub enum ParamEnvSource {
+    /// Preferred eagerly.
+    NonGlobal,
+    // Not considered unless there are non-global param-env candidates too.
+    Global,
+}
+
+#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
 #[cfg_attr(
     feature = "nightly",
     derive(HashStable_NoContext, Encodable_NoContext, Decodable_NoContext)
@@ -266,17 +273,17 @@ impl Certainty {
     /// however matter for diagnostics. If `T: Foo` resulted in overflow and `T: Bar`
     /// in ambiguity without changing the inference state, we still want to tell the
     /// user that `T: Baz` results in overflow.
-    pub fn unify_with(self, other: Certainty) -> Certainty {
+    pub fn and(self, other: Certainty) -> Certainty {
         match (self, other) {
             (Certainty::Yes, Certainty::Yes) => Certainty::Yes,
             (Certainty::Yes, Certainty::Maybe(_)) => other,
             (Certainty::Maybe(_), Certainty::Yes) => self,
-            (Certainty::Maybe(a), Certainty::Maybe(b)) => Certainty::Maybe(a.unify_with(b)),
+            (Certainty::Maybe(a), Certainty::Maybe(b)) => Certainty::Maybe(a.and(b)),
         }
     }
 
     pub const fn overflow(suggest_increasing_limit: bool) -> Certainty {
-        Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit })
+        Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: false })
     }
 }
 
@@ -289,19 +296,58 @@ pub enum MaybeCause {
     /// or we hit a case where we just don't bother, e.g. `?x: Trait` goals.
     Ambiguity,
     /// We gave up due to an overflow, most often by hitting the recursion limit.
-    Overflow { suggest_increasing_limit: bool },
+    Overflow { suggest_increasing_limit: bool, keep_constraints: bool },
 }
 
 impl MaybeCause {
-    fn unify_with(self, other: MaybeCause) -> MaybeCause {
+    fn and(self, other: MaybeCause) -> MaybeCause {
         match (self, other) {
             (MaybeCause::Ambiguity, MaybeCause::Ambiguity) => MaybeCause::Ambiguity,
             (MaybeCause::Ambiguity, MaybeCause::Overflow { .. }) => other,
             (MaybeCause::Overflow { .. }, MaybeCause::Ambiguity) => self,
             (
-                MaybeCause::Overflow { suggest_increasing_limit: a },
-                MaybeCause::Overflow { suggest_increasing_limit: b },
-            ) => MaybeCause::Overflow { suggest_increasing_limit: a || b },
+                MaybeCause::Overflow {
+                    suggest_increasing_limit: limit_a,
+                    keep_constraints: keep_a,
+                },
+                MaybeCause::Overflow {
+                    suggest_increasing_limit: limit_b,
+                    keep_constraints: keep_b,
+                },
+            ) => MaybeCause::Overflow {
+                suggest_increasing_limit: limit_a && limit_b,
+                keep_constraints: keep_a && keep_b,
+            },
+        }
+    }
+
+    pub fn or(self, other: MaybeCause) -> MaybeCause {
+        match (self, other) {
+            (MaybeCause::Ambiguity, MaybeCause::Ambiguity) => MaybeCause::Ambiguity,
+
+            // When combining ambiguity + overflow, we can keep constraints.
+            (
+                MaybeCause::Ambiguity,
+                MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: _ },
+            ) => MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: true },
+            (
+                MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: _ },
+                MaybeCause::Ambiguity,
+            ) => MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: true },
+
+            (
+                MaybeCause::Overflow {
+                    suggest_increasing_limit: limit_a,
+                    keep_constraints: keep_a,
+                },
+                MaybeCause::Overflow {
+                    suggest_increasing_limit: limit_b,
+                    keep_constraints: keep_b,
+                },
+            ) => MaybeCause::Overflow {
+                suggest_increasing_limit: limit_a || limit_b,
+                keep_constraints: keep_a || keep_b,
+            },
         }
     }
 }
diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs
index 21adbffc027..cf2e4284d10 100644
--- a/compiler/rustc_type_ir/src/ty_kind.rs
+++ b/compiler/rustc_type_ir/src/ty_kind.rs
@@ -514,28 +514,6 @@ impl<I: Interner> AliasTy<I> {
     }
 }
 
-/// The following methods work only with inherent associated type projections.
-impl<I: Interner> AliasTy<I> {
-    /// Transform the generic parameters to have the given `impl` args as the base and the GAT args on top of that.
-    ///
-    /// Does the following transformation:
-    ///
-    /// ```text
-    /// [Self, P_0...P_m] -> [I_0...I_n, P_0...P_m]
-    ///
-    ///     I_i impl args
-    ///     P_j GAT args
-    /// ```
-    pub fn rebase_inherent_args_onto_impl(
-        self,
-        impl_args: I::GenericArgs,
-        interner: I,
-    ) -> I::GenericArgs {
-        debug_assert_eq!(self.kind(interner), AliasTyKind::Inherent);
-        interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1)))
-    }
-}
-
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[cfg_attr(
     feature = "nightly",
diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs
index d1ca9bdb7fb..8ba985d2d19 100644
--- a/compiler/rustc_type_ir/src/ty_kind/closure.rs
+++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs
@@ -342,7 +342,7 @@ struct HasRegionsBoundAt {
 // FIXME: Could be optimized to not walk into components with no escaping bound vars.
 impl<I: Interner> TypeVisitor<I> for HasRegionsBoundAt {
     type Result = ControlFlow<()>;
-    fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::Result {
+    fn visit_binder<T: TypeFoldable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::Result {
         self.binder.shift_in(1);
         t.super_visit_with(self)?;
         self.binder.shift_out(1);
diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs
index 2285e0e75de..ccb84e25911 100644
--- a/compiler/rustc_type_ir/src/visit.rs
+++ b/compiler/rustc_type_ir/src/visit.rs
@@ -52,7 +52,7 @@ use smallvec::SmallVec;
 use thin_vec::ThinVec;
 
 use crate::inherent::*;
-use crate::{self as ty, Interner, TypeFlags};
+use crate::{self as ty, Interner, TypeFlags, TypeFoldable};
 
 /// This trait is implemented for every type that can be visited,
 /// providing the skeleton of the traversal.
@@ -94,7 +94,7 @@ pub trait TypeVisitor<I: Interner>: Sized {
     #[cfg(not(feature = "nightly"))]
     type Result: VisitorResult;
 
-    fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::Result {
+    fn visit_binder<T: TypeFoldable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::Result {
         t.super_visit_with(self)
     }
 
@@ -401,7 +401,7 @@ impl std::fmt::Debug for HasTypeFlagsVisitor {
 impl<I: Interner> TypeVisitor<I> for HasTypeFlagsVisitor {
     type Result = ControlFlow<FoundFlags>;
 
-    fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::Result {
+    fn visit_binder<T: TypeFoldable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::Result {
         // If we're looking for the HAS_BINDER_VARS flag, check if the
         // binder has vars. This won't be present in the binder's bound
         // value, so we need to check here too.
@@ -510,7 +510,7 @@ struct HasEscapingVarsVisitor {
 impl<I: Interner> TypeVisitor<I> for HasEscapingVarsVisitor {
     type Result = ControlFlow<FoundEscapingVars>;
 
-    fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::Result {
+    fn visit_binder<T: TypeFoldable<I>>(&mut self, t: &ty::Binder<I, T>) -> Self::Result {
         self.outer_index.shift_in(1);
         let result = t.super_visit_with(self);
         self.outer_index.shift_out(1);
diff --git a/compiler/stable_mir/Cargo.toml b/compiler/stable_mir/Cargo.toml
index 3a01ee5783e..516c8e9c718 100644
--- a/compiler/stable_mir/Cargo.toml
+++ b/compiler/stable_mir/Cargo.toml
@@ -5,3 +5,9 @@ edition = "2024"
 
 [dependencies]
 rustc_smir = { path = "../rustc_smir" }
+
+[features]
+# Provides access to APIs that expose internals of the rust compiler.
+# APIs enabled by this feature are unstable. They can be removed or modified
+# at any point and they are not included in the crate's semantic versioning.
+rustc_internal = []
diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs
index cc0fb52433d..688f3936b26 100644
--- a/compiler/stable_mir/src/lib.rs
+++ b/compiler/stable_mir/src/lib.rs
@@ -4,4 +4,8 @@
 //! This is a transitional measure as described in [PR #139319](https://github.com/rust-lang/rust/pull/139319).
 //! Once the refactoring is complete, the `stable_mir` implementation will be moved back here.
 
+/// Export the rustc_internal APIs. Note that this module has no stability
+/// guarantees and it is not taken into account for semver.
+#[cfg(feature = "rustc_internal")]
+pub use rustc_smir::rustc_internal;
 pub use rustc_smir::stable_mir::*;
diff --git a/library/Cargo.lock b/library/Cargo.lock
index f5c04a3bf48..5100b4d8176 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -33,12 +33,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "allocator-api2"
-version = "0.2.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
-
-[[package]]
 name = "alloctests"
 version = "0.0.0"
 dependencies = [
@@ -67,9 +61,9 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.156"
+version = "0.1.158"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1ffbd2789fe5bb95b96a2e22cbe3128239dc46ff0374e0d38e9f102062d7055"
+checksum = "164cdc689e4c6d69417f77a5f48be240c291e84fbef0b1281755dc754b19c809"
 dependencies = [
  "cc",
  "rustc-std-workspace-core",
@@ -134,11 +128,10 @@ dependencies = [
 
 [[package]]
 name = "hashbrown"
-version = "0.15.2"
+version = "0.15.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
+checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
 dependencies = [
- "allocator-api2",
  "compiler_builtins",
  "rustc-std-workspace-alloc",
  "rustc-std-workspace-core",
@@ -222,15 +215,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "proc-macro2"
-version = "1.0.94"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
-dependencies = [
- "unicode-ident",
-]
-
-[[package]]
 name = "proc_macro"
 version = "0.0.0"
 dependencies = [
@@ -247,15 +231,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "quote"
-version = "1.0.40"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
 name = "r-efi"
 version = "5.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -278,12 +253,11 @@ dependencies = [
 
 [[package]]
 name = "rand"
-version = "0.9.0"
+version = "0.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
+checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97"
 dependencies = [
  "rand_core",
- "zerocopy",
 ]
 
 [[package]]
@@ -388,17 +362,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "syn"
-version = "2.0.100"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
-[[package]]
 name = "sysroot"
 version = "0.0.0"
 dependencies = [
@@ -419,12 +382,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "unicode-ident"
-version = "1.0.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
-
-[[package]]
 name = "unicode-width"
 version = "0.1.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -544,23 +501,3 @@ name = "windows_x86_64_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
-
-[[package]]
-name = "zerocopy"
-version = "0.8.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"
-dependencies = [
- "zerocopy-derive",
-]
-
-[[package]]
-name = "zerocopy-derive"
-version = "0.8.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index 994221de866..51ddc9bf9fc 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -16,7 +16,7 @@ bench = false
 
 [dependencies]
 core = { path = "../core", public = true }
-compiler_builtins = { version = "=0.1.156", features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "=0.1.158", features = ['rustc-dep-of-std'] }
 
 [features]
 compiler-builtins-mem = ['compiler_builtins/mem']
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index 78b7da9d6b3..5ca32ed741a 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -1917,14 +1917,13 @@ pub struct ExtractIf<
     V,
     F,
     #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global,
-> where
-    F: 'a + FnMut(&K, &mut V) -> bool,
-{
+> {
     pred: F,
     inner: ExtractIfInner<'a, K, V>,
     /// The BTreeMap will outlive this IntoIter so we don't care about drop order for `alloc`.
     alloc: A,
 }
+
 /// Most of the implementation of ExtractIf are generic over the type
 /// of the predicate, thus also serving for BTreeSet::ExtractIf.
 pub(super) struct ExtractIfInner<'a, K, V> {
@@ -1940,14 +1939,14 @@ pub(super) struct ExtractIfInner<'a, K, V> {
 }
 
 #[unstable(feature = "btree_extract_if", issue = "70530")]
-impl<K, V, F> fmt::Debug for ExtractIf<'_, K, V, F>
+impl<K, V, F, A> fmt::Debug for ExtractIf<'_, K, V, F, A>
 where
     K: fmt::Debug,
     V: fmt::Debug,
-    F: FnMut(&K, &mut V) -> bool,
+    A: Allocator + Clone,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_tuple("ExtractIf").field(&self.inner.peek()).finish()
+        f.debug_struct("ExtractIf").field("peek", &self.inner.peek()).finish_non_exhaustive()
     }
 }
 
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index 7ad9e59dfed..343934680b8 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -1556,10 +1556,7 @@ pub struct ExtractIf<
     T,
     F,
     #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global,
-> where
-    T: 'a,
-    F: 'a + FnMut(&T) -> bool,
-{
+> {
     pred: F,
     inner: super::map::ExtractIfInner<'a, T, SetValZST>,
     /// The BTreeMap will outlive this IntoIter so we don't care about drop order for `alloc`.
@@ -1567,13 +1564,15 @@ pub struct ExtractIf<
 }
 
 #[unstable(feature = "btree_extract_if", issue = "70530")]
-impl<T, F, A: Allocator + Clone> fmt::Debug for ExtractIf<'_, T, F, A>
+impl<T, F, A> fmt::Debug for ExtractIf<'_, T, F, A>
 where
     T: fmt::Debug,
-    F: FnMut(&T) -> bool,
+    A: Allocator + Clone,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_tuple("ExtractIf").field(&self.inner.peek().map(|(k, _)| k)).finish()
+        f.debug_struct("ExtractIf")
+            .field("peek", &self.inner.peek().map(|(k, _)| k))
+            .finish_non_exhaustive()
     }
 }
 
diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs
index cc42a120e4f..00e2805d11f 100644
--- a/library/alloc/src/collections/linked_list.rs
+++ b/library/alloc/src/collections/linked_list.rs
@@ -1976,9 +1976,14 @@ where
 }
 
 #[stable(feature = "extract_if", since = "1.87.0")]
-impl<T: fmt::Debug, F> fmt::Debug for ExtractIf<'_, T, F> {
+impl<T, F, A> fmt::Debug for ExtractIf<'_, T, F, A>
+where
+    T: fmt::Debug,
+    A: Allocator,
+{
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_tuple("ExtractIf").field(&self.list).finish()
+        let peek = self.it.map(|node| unsafe { &node.as_ref().element });
+        f.debug_struct("ExtractIf").field("peek", &peek).finish_non_exhaustive()
     }
 }
 
diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs
index f8844e2d3a5..712f38a76c0 100644
--- a/library/alloc/src/collections/vec_deque/mod.rs
+++ b/library/alloc/src/collections/vec_deque/mod.rs
@@ -1188,6 +1188,73 @@ impl<T, A: Allocator> VecDeque<T, A> {
         }
     }
 
+    /// Shortens the deque, keeping the last `len` elements and dropping
+    /// the rest.
+    ///
+    /// If `len` is greater or equal to the deque's current length, this has
+    /// no effect.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(vec_deque_truncate_front)]
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::new();
+    /// buf.push_front(5);
+    /// buf.push_front(10);
+    /// buf.push_front(15);
+    /// assert_eq!(buf, [15, 10, 5]);
+    /// assert_eq!(buf.as_slices(), (&[15, 10, 5][..], &[][..]));
+    /// buf.truncate_front(1);
+    /// assert_eq!(buf.as_slices(), (&[5][..], &[][..]));
+    /// ```
+    #[unstable(feature = "vec_deque_truncate_front", issue = "140667")]
+    pub fn truncate_front(&mut self, len: usize) {
+        /// Runs the destructor for all items in the slice when it gets dropped (normally or
+        /// during unwinding).
+        struct Dropper<'a, T>(&'a mut [T]);
+
+        impl<'a, T> Drop for Dropper<'a, T> {
+            fn drop(&mut self) {
+                unsafe {
+                    ptr::drop_in_place(self.0);
+                }
+            }
+        }
+
+        unsafe {
+            if len >= self.len {
+                // No action is taken
+                return;
+            }
+
+            let (front, back) = self.as_mut_slices();
+            if len > back.len() {
+                // The 'back' slice remains unchanged.
+                // front.len() + back.len() == self.len, so 'end' is non-negative
+                // and end < front.len()
+                let end = front.len() - (len - back.len());
+                let drop_front = front.get_unchecked_mut(..end) as *mut _;
+                self.head += end;
+                self.len = len;
+                ptr::drop_in_place(drop_front);
+            } else {
+                let drop_front = front as *mut _;
+                // 'end' is non-negative by the condition above
+                let end = back.len() - len;
+                let drop_back = back.get_unchecked_mut(..end) as *mut _;
+                self.head = self.to_physical_idx(self.len - len);
+                self.len = len;
+
+                // Make sure the second half is dropped even when a destructor
+                // in the first one panics.
+                let _back_dropper = Dropper(&mut *drop_back);
+                ptr::drop_in_place(drop_front);
+            }
+        }
+    }
+
     /// Returns a reference to the underlying allocator.
     #[unstable(feature = "allocator_api", issue = "32838")]
     #[inline]
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 619d9f258e3..4b8ea708e7e 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -3536,11 +3536,11 @@ impl<T> Default for Weak<T> {
     }
 }
 
-// NOTE: We checked_add here to deal with mem::forget safely. In particular
-// if you mem::forget Rcs (or Weaks), the ref-count can overflow, and then
-// you can free the allocation while outstanding Rcs (or Weaks) exist.
-// We abort because this is such a degenerate scenario that we don't care about
-// what happens -- no real program should ever experience this.
+// NOTE: If you mem::forget Rcs (or Weaks), drop is skipped and the ref-count
+// is not decremented, meaning the ref-count can overflow, and then you can
+// free the allocation while outstanding Rcs (or Weaks) exist, which would be
+// unsound. We abort because this is such a degenerate scenario that we don't
+// care about what happens -- no real program should ever experience this.
 //
 // This should have negligible overhead since you don't actually need to
 // clone these much in Rust thanks to ownership and move-semantics.
diff --git a/library/alloc/src/vec/extract_if.rs b/library/alloc/src/vec/extract_if.rs
index 8a591a87796..a456d3d9e60 100644
--- a/library/alloc/src/vec/extract_if.rs
+++ b/library/alloc/src/vec/extract_if.rs
@@ -1,5 +1,5 @@
 use core::ops::{Range, RangeBounds};
-use core::{ptr, slice};
+use core::{fmt, ptr, slice};
 
 use super::Vec;
 use crate::alloc::{Allocator, Global};
@@ -16,7 +16,6 @@ use crate::alloc::{Allocator, Global};
 /// let iter: std::vec::ExtractIf<'_, _, _> = v.extract_if(.., |x| *x % 2 == 0);
 /// ```
 #[stable(feature = "extract_if", since = "1.87.0")]
-#[derive(Debug)]
 #[must_use = "iterators are lazy and do nothing unless consumed"]
 pub struct ExtractIf<
     'a,
@@ -108,3 +107,15 @@ impl<T, F, A: Allocator> Drop for ExtractIf<'_, T, F, A> {
         }
     }
 }
+
+#[stable(feature = "extract_if", since = "1.87.0")]
+impl<T, F, A> fmt::Debug for ExtractIf<'_, T, F, A>
+where
+    T: fmt::Debug,
+    A: Allocator,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let peek = if self.idx < self.end { self.vec.get(self.idx) } else { None };
+        f.debug_struct("ExtractIf").field("peek", &peek).finish_non_exhaustive()
+    }
+}
diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs
index 1af110691ba..37df928228d 100644
--- a/library/alloc/src/vec/into_iter.rs
+++ b/library/alloc/src/vec/into_iter.rs
@@ -259,6 +259,11 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
     }
 
     #[inline]
+    fn last(mut self) -> Option<T> {
+        self.next_back()
+    }
+
+    #[inline]
     fn next_chunk<const N: usize>(&mut self) -> Result<[T; N], core::array::IntoIter<T, N>> {
         let mut raw_ary = [const { MaybeUninit::uninit() }; N];
 
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 65a83cb98ba..a97912304c8 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -3659,28 +3659,34 @@ impl<T, A: Allocator> Vec<T, A> {
     ///
     /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
     /// or the iteration short-circuits, then the remaining elements will be retained.
-    /// Use [`retain`] with a negated predicate if you do not need the returned iterator.
+    /// Use [`retain_mut`] with a negated predicate if you do not need the returned iterator.
     ///
-    /// [`retain`]: Vec::retain
+    /// [`retain_mut`]: Vec::retain_mut
     ///
     /// Using this method is equivalent to the following code:
     ///
     /// ```
-    /// # use std::cmp::min;
-    /// # let some_predicate = |x: &mut i32| { *x == 2 || *x == 3 || *x == 6 };
-    /// # let mut vec = vec![1, 2, 3, 4, 5, 6];
-    /// # let range = 1..4;
+    /// # let some_predicate = |x: &mut i32| { *x % 2 == 1 };
+    /// # let mut vec = vec![0, 1, 2, 3, 4, 5, 6];
+    /// # let mut vec2 = vec.clone();
+    /// # let range = 1..5;
     /// let mut i = range.start;
-    /// while i < min(vec.len(), range.end) {
+    /// let end_items = vec.len() - range.end;
+    /// # let mut extracted = vec![];
+    ///
+    /// while i < vec.len() - end_items {
     ///     if some_predicate(&mut vec[i]) {
     ///         let val = vec.remove(i);
+    /// #         extracted.push(val);
     ///         // your code here
     ///     } else {
     ///         i += 1;
     ///     }
     /// }
     ///
-    /// # assert_eq!(vec, vec![1, 4, 5]);
+    /// # let extracted2: Vec<_> = vec2.extract_if(range, some_predicate).collect();
+    /// # assert_eq!(vec, vec2);
+    /// # assert_eq!(extracted, extracted2);
     /// ```
     ///
     /// But `extract_if` is easier to use. `extract_if` is also more efficient,
diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs
index f1f4cc6f93b..38309585fad 100644
--- a/library/alloctests/tests/lib.rs
+++ b/library/alloctests/tests/lib.rs
@@ -37,6 +37,7 @@
 #![feature(str_as_str)]
 #![feature(strict_provenance_lints)]
 #![feature(vec_deque_pop_if)]
+#![feature(vec_deque_truncate_front)]
 #![feature(unique_rc_arc)]
 #![feature(macro_metavar_expr_concat)]
 #![allow(internal_features)]
diff --git a/library/alloctests/tests/vec_deque.rs b/library/alloctests/tests/vec_deque.rs
index 1b03c29e5bd..b77ea3a312b 100644
--- a/library/alloctests/tests/vec_deque.rs
+++ b/library/alloctests/tests/vec_deque.rs
@@ -1688,6 +1688,40 @@ fn truncate_leak() {
 
 #[test]
 #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
+fn truncate_front_leak() {
+    static mut DROPS: i32 = 0;
+
+    struct D(bool);
+
+    impl Drop for D {
+        fn drop(&mut self) {
+            unsafe {
+                DROPS += 1;
+            }
+
+            if self.0 {
+                panic!("panic in `drop`");
+            }
+        }
+    }
+
+    let mut q = VecDeque::new();
+    q.push_back(D(false));
+    q.push_back(D(false));
+    q.push_back(D(false));
+    q.push_back(D(false));
+    q.push_back(D(false));
+    q.push_front(D(true));
+    q.push_front(D(false));
+    q.push_front(D(false));
+
+    catch_unwind(AssertUnwindSafe(|| q.truncate_front(1))).ok();
+
+    assert_eq!(unsafe { DROPS }, 7);
+}
+
+#[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_drain_leak() {
     static mut DROPS: i32 = 0;
 
@@ -1863,3 +1897,38 @@ fn test_collect_from_into_iter_keeps_allocation() {
         assert_eq!(v.capacity(), 13);
     }
 }
+
+#[test]
+fn test_truncate_front() {
+    let mut v = VecDeque::with_capacity(13);
+    v.extend(0..7);
+    assert_eq!(v.as_slices(), ([0, 1, 2, 3, 4, 5, 6].as_slice(), [].as_slice()));
+    v.truncate_front(10);
+    assert_eq!(v.len(), 7);
+    assert_eq!(v.as_slices(), ([0, 1, 2, 3, 4, 5, 6].as_slice(), [].as_slice()));
+    v.truncate_front(7);
+    assert_eq!(v.len(), 7);
+    assert_eq!(v.as_slices(), ([0, 1, 2, 3, 4, 5, 6].as_slice(), [].as_slice()));
+    v.truncate_front(3);
+    assert_eq!(v.as_slices(), ([4, 5, 6].as_slice(), [].as_slice()));
+    assert_eq!(v.len(), 3);
+    v.truncate_front(0);
+    assert_eq!(v.as_slices(), ([].as_slice(), [].as_slice()));
+    assert_eq!(v.len(), 0);
+
+    v.clear();
+    v.extend(0..7);
+    assert_eq!(v.as_slices(), ([0, 1, 2, 3, 4, 5, 6].as_slice(), [].as_slice()));
+    v.push_front(9);
+    v.push_front(8);
+    v.push_front(7);
+    assert_eq!(v.as_slices(), ([7, 8, 9].as_slice(), [0, 1, 2, 3, 4, 5, 6].as_slice()));
+    v.truncate_front(12);
+    assert_eq!(v.as_slices(), ([7, 8, 9].as_slice(), [0, 1, 2, 3, 4, 5, 6].as_slice()));
+    v.truncate_front(10);
+    assert_eq!(v.as_slices(), ([7, 8, 9].as_slice(), [0, 1, 2, 3, 4, 5, 6].as_slice()));
+    v.truncate_front(8);
+    assert_eq!(v.as_slices(), ([9].as_slice(), [0, 1, 2, 3, 4, 5, 6].as_slice()));
+    v.truncate_front(5);
+    assert_eq!(v.as_slices(), ([2, 3, 4, 5, 6].as_slice(), [].as_slice()));
+}
diff --git a/library/backtrace b/library/backtrace
-Subproject 9d2c34e7e63afe1e71c333b247065e3b7ba4d88
+Subproject 6c882eb11984d737f62e85f36703effaf34c245
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index 394a3ea6778..cb83540c4ea 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -320,6 +320,10 @@ pub fn spin_loop() {
 /// This also means that this function does not offer any guarantees for cryptographic or security
 /// purposes.
 ///
+/// This limitation is not specific to `black_box`; there is no mechanism in the entire Rust
+/// language that can provide the guarantees required for constant-time cryptography.
+/// (There is also no such mechanism in LLVM, so the same is true for every other LLVM-based compiler.)
+///
 /// </div>
 ///
 /// [`std::convert::identity`]: crate::convert::identity
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index c5d5bc000f1..5649736e404 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -3320,7 +3320,6 @@ pub const fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
 #[inline]
 #[rustc_intrinsic]
 #[rustc_intrinsic_const_stable_indirect]
-#[rustc_allow_const_fn_unstable(const_swap_nonoverlapping)] // this is anyway not called since CTFE implements the intrinsic
 pub const unsafe fn typed_swap_nonoverlapping<T>(x: *mut T, y: *mut T) {
     // SAFETY: The caller provided single non-overlapping items behind
     // pointers, so swapping them with `count: 1` is fine.
diff --git a/library/core/src/iter/adapters/cloned.rs b/library/core/src/iter/adapters/cloned.rs
index 72d74628971..aea6d64281a 100644
--- a/library/core/src/iter/adapters/cloned.rs
+++ b/library/core/src/iter/adapters/cloned.rs
@@ -1,6 +1,5 @@
 use core::num::NonZero;
 
-use crate::cmp::Ordering;
 use crate::iter::adapters::zip::try_get_unchecked;
 use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
 use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen, UncheckedIterator};
@@ -42,31 +41,13 @@ where
         self.it.next().cloned()
     }
 
-    #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.it.size_hint()
     }
 
-    #[inline]
-    fn count(self) -> usize {
-        self.it.count()
-    }
-
-    fn last(self) -> Option<T> {
-        self.it.last().cloned()
-    }
-
-    #[inline]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
-        self.it.advance_by(n)
-    }
-
-    fn nth(&mut self, n: usize) -> Option<T> {
-        self.it.nth(n).cloned()
-    }
-
     fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
     where
+        Self: Sized,
         F: FnMut(B, Self::Item) -> R,
         R: Try<Output = B>,
     {
@@ -80,58 +61,6 @@ where
         self.it.map(T::clone).fold(init, f)
     }
 
-    fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item>
-    where
-        P: FnMut(&Self::Item) -> bool,
-    {
-        self.it.find(move |x| predicate(&x)).cloned()
-    }
-
-    fn max_by<F>(self, mut compare: F) -> Option<Self::Item>
-    where
-        F: FnMut(&Self::Item, &Self::Item) -> Ordering,
-    {
-        self.it.max_by(move |&x, &y| compare(x, y)).cloned()
-    }
-
-    fn min_by<F>(self, mut compare: F) -> Option<Self::Item>
-    where
-        F: FnMut(&Self::Item, &Self::Item) -> Ordering,
-    {
-        self.it.min_by(move |&x, &y| compare(x, y)).cloned()
-    }
-
-    fn cmp<O>(self, other: O) -> Ordering
-    where
-        O: IntoIterator<Item = Self::Item>,
-        Self::Item: Ord,
-    {
-        self.it.cmp_by(other, |x, y| x.cmp(&y))
-    }
-
-    fn partial_cmp<O>(self, other: O) -> Option<Ordering>
-    where
-        O: IntoIterator,
-        Self::Item: PartialOrd<O::Item>,
-    {
-        self.it.partial_cmp_by(other, |x, y| x.partial_cmp(&y))
-    }
-
-    fn eq<O>(self, other: O) -> bool
-    where
-        O: IntoIterator,
-        Self::Item: PartialEq<O::Item>,
-    {
-        self.it.eq_by(other, |x, y| x == &y)
-    }
-
-    fn is_sorted_by<F>(self, mut compare: F) -> bool
-    where
-        F: FnMut(&Self::Item, &Self::Item) -> bool,
-    {
-        self.it.is_sorted_by(move |&x, &y| compare(x, y))
-    }
-
     unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
     where
         Self: TrustedRandomAccessNoCoerce,
@@ -152,13 +81,9 @@ where
         self.it.next_back().cloned()
     }
 
-    #[inline]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
-        self.it.advance_back_by(n)
-    }
-
     fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
     where
+        Self: Sized,
         F: FnMut(B, Self::Item) -> R,
         R: Try<Output = B>,
     {
@@ -171,13 +96,6 @@ where
     {
         self.it.map(T::clone).rfold(init, f)
     }
-
-    fn rfind<P>(&mut self, mut predicate: P) -> Option<Self::Item>
-    where
-        P: FnMut(&Self::Item) -> bool,
-    {
-        self.it.rfind(move |x| predicate(&x)).cloned()
-    }
 }
 
 #[stable(feature = "iter_cloned", since = "1.1.0")]
@@ -186,12 +104,10 @@ where
     I: ExactSizeIterator<Item = &'a T>,
     T: Clone,
 {
-    #[inline]
     fn len(&self) -> usize {
         self.it.len()
     }
 
-    #[inline]
     fn is_empty(&self) -> bool {
         self.it.is_empty()
     }
diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs
index 73913aa34a9..23e4e25ab53 100644
--- a/library/core/src/iter/adapters/copied.rs
+++ b/library/core/src/iter/adapters/copied.rs
@@ -1,4 +1,3 @@
-use crate::cmp::Ordering;
 use crate::iter::adapters::zip::try_get_unchecked;
 use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
 use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
@@ -49,35 +48,20 @@ where
 
     fn next_chunk<const N: usize>(
         &mut self,
-    ) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> {
+    ) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>>
+    where
+        Self: Sized,
+    {
         <I as SpecNextChunk<'_, N, T>>::spec_next_chunk(&mut self.it)
     }
 
-    #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.it.size_hint()
     }
 
-    #[inline]
-    fn count(self) -> usize {
-        self.it.count()
-    }
-
-    fn last(self) -> Option<T> {
-        self.it.last().copied()
-    }
-
-    #[inline]
-    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
-        self.it.advance_by(n)
-    }
-
-    fn nth(&mut self, n: usize) -> Option<T> {
-        self.it.nth(n).copied()
-    }
-
     fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
     where
+        Self: Sized,
         F: FnMut(B, Self::Item) -> R,
         R: Try<Output = B>,
     {
@@ -91,56 +75,21 @@ where
         self.it.fold(init, copy_fold(f))
     }
 
-    fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item>
-    where
-        P: FnMut(&Self::Item) -> bool,
-    {
-        self.it.find(move |x| predicate(&x)).copied()
-    }
-
-    fn max_by<F>(self, mut compare: F) -> Option<Self::Item>
-    where
-        F: FnMut(&Self::Item, &Self::Item) -> Ordering,
-    {
-        self.it.max_by(move |&x, &y| compare(x, y)).copied()
-    }
-
-    fn min_by<F>(self, mut compare: F) -> Option<Self::Item>
-    where
-        F: FnMut(&Self::Item, &Self::Item) -> Ordering,
-    {
-        self.it.min_by(move |&x, &y| compare(x, y)).copied()
-    }
-
-    fn cmp<O>(self, other: O) -> Ordering
-    where
-        O: IntoIterator<Item = Self::Item>,
-        Self::Item: Ord,
-    {
-        self.it.cmp_by(other, |x, y| x.cmp(&y))
+    fn nth(&mut self, n: usize) -> Option<T> {
+        self.it.nth(n).copied()
     }
 
-    fn partial_cmp<O>(self, other: O) -> Option<Ordering>
-    where
-        O: IntoIterator,
-        Self::Item: PartialOrd<O::Item>,
-    {
-        self.it.partial_cmp_by(other, |x, y| x.partial_cmp(&y))
+    fn last(self) -> Option<T> {
+        self.it.last().copied()
     }
 
-    fn eq<O>(self, other: O) -> bool
-    where
-        O: IntoIterator,
-        Self::Item: PartialEq<O::Item>,
-    {
-        self.it.eq_by(other, |x, y| x == &y)
+    fn count(self) -> usize {
+        self.it.count()
     }
 
-    fn is_sorted_by<F>(self, mut compare: F) -> bool
-    where
-        F: FnMut(&Self::Item, &Self::Item) -> bool,
-    {
-        self.it.is_sorted_by(move |&x, &y| compare(x, y))
+    #[inline]
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
+        self.it.advance_by(n)
     }
 
     unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
@@ -163,13 +112,9 @@ where
         self.it.next_back().copied()
     }
 
-    #[inline]
-    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
-        self.it.advance_back_by(n)
-    }
-
     fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
     where
+        Self: Sized,
         F: FnMut(B, Self::Item) -> R,
         R: Try<Output = B>,
     {
@@ -183,11 +128,9 @@ where
         self.it.rfold(init, copy_fold(f))
     }
 
-    fn rfind<P>(&mut self, mut predicate: P) -> Option<Self::Item>
-    where
-        P: FnMut(&Self::Item) -> bool,
-    {
-        self.it.rfind(move |x| predicate(&x)).copied()
+    #[inline]
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
+        self.it.advance_back_by(n)
     }
 }
 
@@ -197,12 +140,10 @@ where
     I: ExactSizeIterator<Item = &'a T>,
     T: Copy,
 {
-    #[inline]
     fn len(&self) -> usize {
         self.it.len()
     }
 
-    #[inline]
     fn is_empty(&self) -> bool {
         self.it.is_empty()
     }
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index c68fd2115d6..d1e71f0e60f 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -56,12 +56,12 @@ pub trait Iterator {
     /// ```
     /// let a = [1, 2, 3];
     ///
-    /// let mut iter = a.iter();
+    /// let mut iter = a.into_iter();
     ///
     /// // A call to next() returns the next value...
-    /// assert_eq!(Some(&1), iter.next());
-    /// assert_eq!(Some(&2), iter.next());
-    /// assert_eq!(Some(&3), iter.next());
+    /// assert_eq!(Some(1), iter.next());
+    /// assert_eq!(Some(2), iter.next());
+    /// assert_eq!(Some(3), iter.next());
     ///
     /// // ... and then None once it's over.
     /// assert_eq!(None, iter.next());
@@ -239,10 +239,10 @@ pub trait Iterator {
     ///
     /// ```
     /// let a = [1, 2, 3];
-    /// assert_eq!(a.iter().last(), Some(&3));
+    /// assert_eq!(a.into_iter().last(), Some(3));
     ///
     /// let a = [1, 2, 3, 4, 5];
-    /// assert_eq!(a.iter().last(), Some(&5));
+    /// assert_eq!(a.into_iter().last(), Some(5));
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -284,12 +284,12 @@ pub trait Iterator {
     /// use std::num::NonZero;
     ///
     /// let a = [1, 2, 3, 4];
-    /// let mut iter = a.iter();
+    /// let mut iter = a.into_iter();
     ///
     /// assert_eq!(iter.advance_by(2), Ok(()));
-    /// assert_eq!(iter.next(), Some(&3));
+    /// assert_eq!(iter.next(), Some(3));
     /// assert_eq!(iter.advance_by(0), Ok(()));
-    /// assert_eq!(iter.advance_by(100), Err(NonZero::new(99).unwrap())); // only `&4` was skipped
+    /// assert_eq!(iter.advance_by(100), Err(NonZero::new(99).unwrap())); // only `4` was skipped
     /// ```
     #[inline]
     #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")]
@@ -322,7 +322,7 @@ pub trait Iterator {
     ///
     /// ```
     /// let a = [1, 2, 3];
-    /// assert_eq!(a.iter().nth(1), Some(&2));
+    /// assert_eq!(a.into_iter().nth(1), Some(2));
     /// ```
     ///
     /// Calling `nth()` multiple times doesn't rewind the iterator:
@@ -330,9 +330,9 @@ pub trait Iterator {
     /// ```
     /// let a = [1, 2, 3];
     ///
-    /// let mut iter = a.iter();
+    /// let mut iter = a.into_iter();
     ///
-    /// assert_eq!(iter.nth(1), Some(&2));
+    /// assert_eq!(iter.nth(1), Some(2));
     /// assert_eq!(iter.nth(1), None);
     /// ```
     ///
@@ -340,7 +340,7 @@ pub trait Iterator {
     ///
     /// ```
     /// let a = [1, 2, 3];
-    /// assert_eq!(a.iter().nth(10), None);
+    /// assert_eq!(a.into_iter().nth(10), None);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -385,11 +385,11 @@ pub trait Iterator {
     ///
     /// ```
     /// let a = [0, 1, 2, 3, 4, 5];
-    /// let mut iter = a.iter().step_by(2);
+    /// let mut iter = a.into_iter().step_by(2);
     ///
-    /// assert_eq!(iter.next(), Some(&0));
-    /// assert_eq!(iter.next(), Some(&2));
-    /// assert_eq!(iter.next(), Some(&4));
+    /// assert_eq!(iter.next(), Some(0));
+    /// assert_eq!(iter.next(), Some(2));
+    /// assert_eq!(iter.next(), Some(4));
     /// assert_eq!(iter.next(), None);
     /// ```
     #[inline]
@@ -417,37 +417,37 @@ pub trait Iterator {
     /// Basic usage:
     ///
     /// ```
-    /// let a1 = [1, 2, 3];
-    /// let a2 = [4, 5, 6];
+    /// let s1 = "abc".chars();
+    /// let s2 = "def".chars();
     ///
-    /// let mut iter = a1.iter().chain(a2.iter());
+    /// let mut iter = s1.chain(s2);
     ///
-    /// assert_eq!(iter.next(), Some(&1));
-    /// assert_eq!(iter.next(), Some(&2));
-    /// assert_eq!(iter.next(), Some(&3));
-    /// assert_eq!(iter.next(), Some(&4));
-    /// assert_eq!(iter.next(), Some(&5));
-    /// assert_eq!(iter.next(), Some(&6));
+    /// assert_eq!(iter.next(), Some('a'));
+    /// assert_eq!(iter.next(), Some('b'));
+    /// assert_eq!(iter.next(), Some('c'));
+    /// assert_eq!(iter.next(), Some('d'));
+    /// assert_eq!(iter.next(), Some('e'));
+    /// assert_eq!(iter.next(), Some('f'));
     /// assert_eq!(iter.next(), None);
     /// ```
     ///
     /// Since the argument to `chain()` uses [`IntoIterator`], we can pass
     /// anything that can be converted into an [`Iterator`], not just an
-    /// [`Iterator`] itself. For example, slices (`&[T]`) implement
+    /// [`Iterator`] itself. For example, arrays (`[T]`) implement
     /// [`IntoIterator`], and so can be passed to `chain()` directly:
     ///
     /// ```
-    /// let s1 = &[1, 2, 3];
-    /// let s2 = &[4, 5, 6];
+    /// let a1 = [1, 2, 3];
+    /// let a2 = [4, 5, 6];
     ///
-    /// let mut iter = s1.iter().chain(s2);
+    /// let mut iter = a1.into_iter().chain(a2);
     ///
-    /// assert_eq!(iter.next(), Some(&1));
-    /// assert_eq!(iter.next(), Some(&2));
-    /// assert_eq!(iter.next(), Some(&3));
-    /// assert_eq!(iter.next(), Some(&4));
-    /// assert_eq!(iter.next(), Some(&5));
-    /// assert_eq!(iter.next(), Some(&6));
+    /// assert_eq!(iter.next(), Some(1));
+    /// assert_eq!(iter.next(), Some(2));
+    /// assert_eq!(iter.next(), Some(3));
+    /// assert_eq!(iter.next(), Some(4));
+    /// assert_eq!(iter.next(), Some(5));
+    /// assert_eq!(iter.next(), Some(6));
     /// assert_eq!(iter.next(), None);
     /// ```
     ///
@@ -496,31 +496,31 @@ pub trait Iterator {
     /// Basic usage:
     ///
     /// ```
-    /// let a1 = [1, 2, 3];
-    /// let a2 = [4, 5, 6];
+    /// let s1 = "abc".chars();
+    /// let s2 = "def".chars();
     ///
-    /// let mut iter = a1.iter().zip(a2.iter());
+    /// let mut iter = s1.zip(s2);
     ///
-    /// assert_eq!(iter.next(), Some((&1, &4)));
-    /// assert_eq!(iter.next(), Some((&2, &5)));
-    /// assert_eq!(iter.next(), Some((&3, &6)));
+    /// assert_eq!(iter.next(), Some(('a', 'd')));
+    /// assert_eq!(iter.next(), Some(('b', 'e')));
+    /// assert_eq!(iter.next(), Some(('c', 'f')));
     /// assert_eq!(iter.next(), None);
     /// ```
     ///
     /// Since the argument to `zip()` uses [`IntoIterator`], we can pass
     /// anything that can be converted into an [`Iterator`], not just an
-    /// [`Iterator`] itself. For example, slices (`&[T]`) implement
+    /// [`Iterator`] itself. For example, arrays (`[T]`) implement
     /// [`IntoIterator`], and so can be passed to `zip()` directly:
     ///
     /// ```
-    /// let s1 = &[1, 2, 3];
-    /// let s2 = &[4, 5, 6];
+    /// let a1 = [1, 2, 3];
+    /// let a2 = [4, 5, 6];
     ///
-    /// let mut iter = s1.iter().zip(s2);
+    /// let mut iter = a1.into_iter().zip(a2);
     ///
-    /// assert_eq!(iter.next(), Some((&1, &4)));
-    /// assert_eq!(iter.next(), Some((&2, &5)));
-    /// assert_eq!(iter.next(), Some((&3, &6)));
+    /// assert_eq!(iter.next(), Some((1, 4)));
+    /// assert_eq!(iter.next(), Some((2, 5)));
+    /// assert_eq!(iter.next(), Some((3, 6)));
     /// assert_eq!(iter.next(), None);
     /// ```
     ///
@@ -604,12 +604,12 @@ pub trait Iterator {
     /// ```
     /// #![feature(iter_intersperse)]
     ///
-    /// let mut a = [0, 1, 2].iter().intersperse(&100);
-    /// assert_eq!(a.next(), Some(&0));   // The first element from `a`.
-    /// assert_eq!(a.next(), Some(&100)); // The separator.
-    /// assert_eq!(a.next(), Some(&1));   // The next element from `a`.
-    /// assert_eq!(a.next(), Some(&100)); // The separator.
-    /// assert_eq!(a.next(), Some(&2));   // The last element from `a`.
+    /// let mut a = [0, 1, 2].into_iter().intersperse(100);
+    /// assert_eq!(a.next(), Some(0));   // The first element from `a`.
+    /// assert_eq!(a.next(), Some(100)); // The separator.
+    /// assert_eq!(a.next(), Some(1));   // The next element from `a`.
+    /// assert_eq!(a.next(), Some(100)); // The separator.
+    /// assert_eq!(a.next(), Some(2));   // The last element from `a`.
     /// assert_eq!(a.next(), None);       // The iterator is finished.
     /// ```
     ///
@@ -617,7 +617,8 @@ pub trait Iterator {
     /// ```
     /// #![feature(iter_intersperse)]
     ///
-    /// let hello = ["Hello", "World", "!"].iter().copied().intersperse(" ").collect::<String>();
+    /// let words = ["Hello", "World", "!"];
+    /// let hello: String = words.into_iter().intersperse(" ").collect();
     /// assert_eq!(hello, "Hello World !");
     /// ```
     ///
@@ -673,7 +674,7 @@ pub trait Iterator {
     /// let src = ["Hello", "to", "all", "people", "!!"].iter().copied();
     ///
     /// // The closure mutably borrows its context to generate an item.
-    /// let mut happy_emojis = [" ❤️ ", " 😀 "].iter().copied();
+    /// let mut happy_emojis = [" ❤️ ", " 😀 "].into_iter();
     /// let separator = || happy_emojis.next().unwrap_or(" 🦀 ");
     ///
     /// let result = src.intersperse_with(separator).collect::<String>();
@@ -734,7 +735,7 @@ pub trait Iterator {
     ///
     /// // it won't even execute, as it is lazy. Rust will warn you about this.
     ///
-    /// // Instead, use for:
+    /// // Instead, use a for-loop:
     /// for x in 0..5 {
     ///     println!("{x}");
     /// }
@@ -814,10 +815,10 @@ pub trait Iterator {
     /// ```
     /// let a = [0i32, 1, 2];
     ///
-    /// let mut iter = a.iter().filter(|x| x.is_positive());
+    /// let mut iter = a.into_iter().filter(|x| x.is_positive());
     ///
-    /// assert_eq!(iter.next(), Some(&1));
-    /// assert_eq!(iter.next(), Some(&2));
+    /// assert_eq!(iter.next(), Some(1));
+    /// assert_eq!(iter.next(), Some(2));
     /// assert_eq!(iter.next(), None);
     /// ```
     ///
@@ -826,21 +827,20 @@ pub trait Iterator {
     /// situation, where the type of the closure is a double reference:
     ///
     /// ```
-    /// let a = [0, 1, 2];
+    /// let s = &[0, 1, 2];
     ///
-    /// let mut iter = a.iter().filter(|x| **x > 1); // need two *s!
+    /// let mut iter = s.iter().filter(|x| **x > 1); // needs two *s!
     ///
     /// assert_eq!(iter.next(), Some(&2));
     /// assert_eq!(iter.next(), None);
     /// ```
     ///
-    /// It's common to instead use destructuring on the argument to strip away
-    /// one:
+    /// It's common to instead use destructuring on the argument to strip away one:
     ///
     /// ```
-    /// let a = [0, 1, 2];
+    /// let s = &[0, 1, 2];
     ///
-    /// let mut iter = a.iter().filter(|&x| *x > 1); // both & and *
+    /// let mut iter = s.iter().filter(|&x| *x > 1); // both & and *
     ///
     /// assert_eq!(iter.next(), Some(&2));
     /// assert_eq!(iter.next(), None);
@@ -849,9 +849,9 @@ pub trait Iterator {
     /// or both:
     ///
     /// ```
-    /// let a = [0, 1, 2];
+    /// let s = &[0, 1, 2];
     ///
-    /// let mut iter = a.iter().filter(|&&x| x > 1); // two &s
+    /// let mut iter = s.iter().filter(|&&x| x > 1); // two &s
     ///
     /// assert_eq!(iter.next(), Some(&2));
     /// assert_eq!(iter.next(), None);
@@ -945,11 +945,11 @@ pub trait Iterator {
     /// ```
     /// let a = ['a', 'b', 'c'];
     ///
-    /// let mut iter = a.iter().enumerate();
+    /// let mut iter = a.into_iter().enumerate();
     ///
-    /// assert_eq!(iter.next(), Some((0, &'a')));
-    /// assert_eq!(iter.next(), Some((1, &'b')));
-    /// assert_eq!(iter.next(), Some((2, &'c')));
+    /// assert_eq!(iter.next(), Some((0, 'a')));
+    /// assert_eq!(iter.next(), Some((1, 'b')));
+    /// assert_eq!(iter.next(), Some((2, 'c')));
     /// assert_eq!(iter.next(), None);
     /// ```
     #[inline]
@@ -980,19 +980,19 @@ pub trait Iterator {
     /// ```
     /// let xs = [1, 2, 3];
     ///
-    /// let mut iter = xs.iter().peekable();
+    /// let mut iter = xs.into_iter().peekable();
     ///
     /// // peek() lets us see into the future
-    /// assert_eq!(iter.peek(), Some(&&1));
-    /// assert_eq!(iter.next(), Some(&1));
+    /// assert_eq!(iter.peek(), Some(&1));
+    /// assert_eq!(iter.next(), Some(1));
     ///
-    /// assert_eq!(iter.next(), Some(&2));
+    /// assert_eq!(iter.next(), Some(2));
     ///
     /// // we can peek() multiple times, the iterator won't advance
-    /// assert_eq!(iter.peek(), Some(&&3));
-    /// assert_eq!(iter.peek(), Some(&&3));
+    /// assert_eq!(iter.peek(), Some(&3));
+    /// assert_eq!(iter.peek(), Some(&3));
     ///
-    /// assert_eq!(iter.next(), Some(&3));
+    /// assert_eq!(iter.next(), Some(3));
     ///
     /// // after the iterator is finished, so is peek()
     /// assert_eq!(iter.peek(), None);
@@ -1005,21 +1005,21 @@ pub trait Iterator {
     /// ```
     /// let xs = [1, 2, 3];
     ///
-    /// let mut iter = xs.iter().peekable();
+    /// let mut iter = xs.into_iter().peekable();
     ///
     /// // `peek_mut()` lets us see into the future
-    /// assert_eq!(iter.peek_mut(), Some(&mut &1));
-    /// assert_eq!(iter.peek_mut(), Some(&mut &1));
-    /// assert_eq!(iter.next(), Some(&1));
+    /// assert_eq!(iter.peek_mut(), Some(&mut 1));
+    /// assert_eq!(iter.peek_mut(), Some(&mut 1));
+    /// assert_eq!(iter.next(), Some(1));
     ///
-    /// if let Some(mut p) = iter.peek_mut() {
-    ///     assert_eq!(*p, &2);
+    /// if let Some(p) = iter.peek_mut() {
+    ///     assert_eq!(*p, 2);
     ///     // put a value into the iterator
-    ///     *p = &1000;
+    ///     *p = 1000;
     /// }
     ///
     /// // The value reappears as the iterator continues
-    /// assert_eq!(iter.collect::<Vec<_>>(), vec![&1000, &3]);
+    /// assert_eq!(iter.collect::<Vec<_>>(), vec![1000, 3]);
     /// ```
     /// [`peek`]: Peekable::peek
     /// [`peek_mut`]: Peekable::peek_mut
@@ -1051,10 +1051,10 @@ pub trait Iterator {
     /// ```
     /// let a = [-1i32, 0, 1];
     ///
-    /// let mut iter = a.iter().skip_while(|x| x.is_negative());
+    /// let mut iter = a.into_iter().skip_while(|x| x.is_negative());
     ///
-    /// assert_eq!(iter.next(), Some(&0));
-    /// assert_eq!(iter.next(), Some(&1));
+    /// assert_eq!(iter.next(), Some(0));
+    /// assert_eq!(iter.next(), Some(1));
     /// assert_eq!(iter.next(), None);
     /// ```
     ///
@@ -1063,9 +1063,9 @@ pub trait Iterator {
     /// situation, where the type of the closure argument is a double reference:
     ///
     /// ```
-    /// let a = [-1, 0, 1];
+    /// let s = &[-1, 0, 1];
     ///
-    /// let mut iter = a.iter().skip_while(|x| **x < 0); // need two *s!
+    /// let mut iter = s.iter().skip_while(|x| **x < 0); // need two *s!
     ///
     /// assert_eq!(iter.next(), Some(&0));
     /// assert_eq!(iter.next(), Some(&1));
@@ -1077,14 +1077,14 @@ pub trait Iterator {
     /// ```
     /// let a = [-1, 0, 1, -2];
     ///
-    /// let mut iter = a.iter().skip_while(|x| **x < 0);
+    /// let mut iter = a.into_iter().skip_while(|&x| x < 0);
     ///
-    /// assert_eq!(iter.next(), Some(&0));
-    /// assert_eq!(iter.next(), Some(&1));
+    /// assert_eq!(iter.next(), Some(0));
+    /// assert_eq!(iter.next(), Some(1));
     ///
     /// // while this would have been false, since we already got a false,
     /// // skip_while() isn't used any more
-    /// assert_eq!(iter.next(), Some(&-2));
+    /// assert_eq!(iter.next(), Some(-2));
     ///
     /// assert_eq!(iter.next(), None);
     /// ```
@@ -1115,9 +1115,9 @@ pub trait Iterator {
     /// ```
     /// let a = [-1i32, 0, 1];
     ///
-    /// let mut iter = a.iter().take_while(|x| x.is_negative());
+    /// let mut iter = a.into_iter().take_while(|x| x.is_negative());
     ///
-    /// assert_eq!(iter.next(), Some(&-1));
+    /// assert_eq!(iter.next(), Some(-1));
     /// assert_eq!(iter.next(), None);
     /// ```
     ///
@@ -1126,9 +1126,9 @@ pub trait Iterator {
     /// situation, where the type of the closure is a double reference:
     ///
     /// ```
-    /// let a = [-1, 0, 1];
+    /// let s = &[-1, 0, 1];
     ///
-    /// let mut iter = a.iter().take_while(|x| **x < 0); // need two *s!
+    /// let mut iter = s.iter().take_while(|x| **x < 0); // need two *s!
     ///
     /// assert_eq!(iter.next(), Some(&-1));
     /// assert_eq!(iter.next(), None);
@@ -1139,12 +1139,12 @@ pub trait Iterator {
     /// ```
     /// let a = [-1, 0, 1, -2];
     ///
-    /// let mut iter = a.iter().take_while(|x| **x < 0);
+    /// let mut iter = a.into_iter().take_while(|&x| x < 0);
     ///
-    /// assert_eq!(iter.next(), Some(&-1));
+    /// assert_eq!(iter.next(), Some(-1));
     ///
     /// // We have more elements that are less than zero, but since we already
-    /// // got a false, take_while() isn't used any more
+    /// // got a false, take_while() ignores the remaining elements.
     /// assert_eq!(iter.next(), None);
     /// ```
     ///
@@ -1154,18 +1154,15 @@ pub trait Iterator {
     ///
     /// ```
     /// let a = [1, 2, 3, 4];
-    /// let mut iter = a.iter();
+    /// let mut iter = a.into_iter();
     ///
-    /// let result: Vec<i32> = iter.by_ref()
-    ///                            .take_while(|n| **n != 3)
-    ///                            .cloned()
-    ///                            .collect();
+    /// let result: Vec<i32> = iter.by_ref().take_while(|&n| n != 3).collect();
     ///
-    /// assert_eq!(result, &[1, 2]);
+    /// assert_eq!(result, [1, 2]);
     ///
-    /// let result: Vec<i32> = iter.cloned().collect();
+    /// let result: Vec<i32> = iter.collect();
     ///
-    /// assert_eq!(result, &[4]);
+    /// assert_eq!(result, [4]);
     /// ```
     ///
     /// The `3` is no longer there, because it was consumed in order to see if
@@ -1193,7 +1190,7 @@ pub trait Iterator {
     /// ```
     /// let a = [-1i32, 4, 0, 1];
     ///
-    /// let mut iter = a.iter().map_while(|x| 16i32.checked_div(*x));
+    /// let mut iter = a.into_iter().map_while(|x| 16i32.checked_div(x));
     ///
     /// assert_eq!(iter.next(), Some(-16));
     /// assert_eq!(iter.next(), Some(4));
@@ -1208,8 +1205,8 @@ pub trait Iterator {
     /// ```
     /// let a = [-1i32, 4, 0, 1];
     ///
-    /// let mut iter = a.iter()
-    ///                 .map(|x| 16i32.checked_div(*x))
+    /// let mut iter = a.into_iter()
+    ///                 .map(|x| 16i32.checked_div(x))
     ///                 .take_while(|x| x.is_some())
     ///                 .map(|x| x.unwrap());
     ///
@@ -1223,12 +1220,12 @@ pub trait Iterator {
     /// ```
     /// let a = [0, 1, 2, -3, 4, 5, -6];
     ///
-    /// let iter = a.iter().map_while(|x| u32::try_from(*x).ok());
-    /// let vec = iter.collect::<Vec<_>>();
+    /// let iter = a.into_iter().map_while(|x| u32::try_from(x).ok());
+    /// let vec: Vec<_> = iter.collect();
     ///
-    /// // We have more elements which could fit in u32 (4, 5), but `map_while` returned `None` for `-3`
+    /// // We have more elements that could fit in u32 (such as 4, 5), but `map_while` returned `None` for `-3`
     /// // (as the `predicate` returned `None`) and `collect` stops at the first `None` encountered.
-    /// assert_eq!(vec, vec![0, 1, 2]);
+    /// assert_eq!(vec, [0, 1, 2]);
     /// ```
     ///
     /// Because `map_while()` needs to look at the value in order to see if it
@@ -1237,17 +1234,17 @@ pub trait Iterator {
     ///
     /// ```
     /// let a = [1, 2, -3, 4];
-    /// let mut iter = a.iter();
+    /// let mut iter = a.into_iter();
     ///
     /// let result: Vec<u32> = iter.by_ref()
-    ///                            .map_while(|n| u32::try_from(*n).ok())
+    ///                            .map_while(|n| u32::try_from(n).ok())
     ///                            .collect();
     ///
-    /// assert_eq!(result, &[1, 2]);
+    /// assert_eq!(result, [1, 2]);
     ///
-    /// let result: Vec<i32> = iter.cloned().collect();
+    /// let result: Vec<i32> = iter.collect();
     ///
-    /// assert_eq!(result, &[4]);
+    /// assert_eq!(result, [4]);
     /// ```
     ///
     /// The `-3` is no longer there, because it was consumed in order to see if
@@ -1255,7 +1252,7 @@ pub trait Iterator {
     ///
     /// Note that unlike [`take_while`] this iterator is **not** fused.
     /// It is also not specified what this iterator returns after the first [`None`] is returned.
-    /// If you need fused iterator, use [`fuse`].
+    /// If you need a fused iterator, use [`fuse`].
     ///
     /// [`fuse`]: Iterator::fuse
     #[inline]
@@ -1282,9 +1279,9 @@ pub trait Iterator {
     /// ```
     /// let a = [1, 2, 3];
     ///
-    /// let mut iter = a.iter().skip(2);
+    /// let mut iter = a.into_iter().skip(2);
     ///
-    /// assert_eq!(iter.next(), Some(&3));
+    /// assert_eq!(iter.next(), Some(3));
     /// assert_eq!(iter.next(), None);
     /// ```
     #[inline]
@@ -1312,10 +1309,10 @@ pub trait Iterator {
     /// ```
     /// let a = [1, 2, 3];
     ///
-    /// let mut iter = a.iter().take(2);
+    /// let mut iter = a.into_iter().take(2);
     ///
-    /// assert_eq!(iter.next(), Some(&1));
-    /// assert_eq!(iter.next(), Some(&2));
+    /// assert_eq!(iter.next(), Some(1));
+    /// assert_eq!(iter.next(), Some(2));
     /// assert_eq!(iter.next(), None);
     /// ```
     ///
@@ -1358,6 +1355,7 @@ pub trait Iterator {
     /// ```
     ///
     /// [`by_ref`]: Iterator::by_ref
+    #[doc(alias = "limit")]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn take(self, n: usize) -> Take<Self>
@@ -1388,7 +1386,7 @@ pub trait Iterator {
     /// ```
     /// let a = [1, 2, 3, 4];
     ///
-    /// let mut iter = a.iter().scan(1, |state, &x| {
+    /// let mut iter = a.into_iter().scan(1, |state, x| {
     ///     // each iteration, we'll multiply the state by the element ...
     ///     *state = *state * x;
     ///
@@ -1466,8 +1464,8 @@ pub trait Iterator {
     ///
     /// ```
     /// let data = vec![vec![1, 2, 3, 4], vec![5, 6]];
-    /// let flattened = data.into_iter().flatten().collect::<Vec<u8>>();
-    /// assert_eq!(flattened, &[1, 2, 3, 4, 5, 6]);
+    /// let flattened: Vec<_> = data.into_iter().flatten().collect();
+    /// assert_eq!(flattened, [1, 2, 3, 4, 5, 6]);
     /// ```
     ///
     /// Mapping and then flattening:
@@ -1501,11 +1499,11 @@ pub trait Iterator {
     /// ```
     /// let options = vec![Some(123), Some(321), None, Some(231)];
     /// let flattened_options: Vec<_> = options.into_iter().flatten().collect();
-    /// assert_eq!(flattened_options, vec![123, 321, 231]);
+    /// assert_eq!(flattened_options, [123, 321, 231]);
     ///
     /// let results = vec![Ok(123), Ok(321), Err(456), Ok(231)];
     /// let flattened_results: Vec<_> = results.into_iter().flatten().collect();
-    /// assert_eq!(flattened_results, vec![123, 321, 231]);
+    /// assert_eq!(flattened_results, [123, 321, 231]);
     /// ```
     ///
     /// Flattening only removes one level of nesting at a time:
@@ -1513,11 +1511,11 @@ pub trait Iterator {
     /// ```
     /// let d3 = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]];
     ///
-    /// let d2 = d3.iter().flatten().collect::<Vec<_>>();
-    /// assert_eq!(d2, [&[1, 2], &[3, 4], &[5, 6], &[7, 8]]);
+    /// let d2: Vec<_> = d3.into_iter().flatten().collect();
+    /// assert_eq!(d2, [[1, 2], [3, 4], [5, 6], [7, 8]]);
     ///
-    /// let d1 = d3.iter().flatten().flatten().collect::<Vec<_>>();
-    /// assert_eq!(d1, [&1, &2, &3, &4, &5, &6, &7, &8]);
+    /// let d1: Vec<_> = d3.into_iter().flatten().flatten().collect();
+    /// assert_eq!(d1, [1, 2, 3, 4, 5, 6, 7, 8]);
     /// ```
     ///
     /// Here we see that `flatten()` does not perform a "deep" flatten.
@@ -1904,7 +1902,7 @@ pub trait Iterator {
     /// let a = [1, 2, 3];
     ///
     /// let doubled: Vec<i32> = a.iter()
-    ///                          .map(|&x| x * 2)
+    ///                          .map(|x| x * 2)
     ///                          .collect();
     ///
     /// assert_eq!(vec![2, 4, 6], doubled);
@@ -1920,7 +1918,7 @@ pub trait Iterator {
     ///
     /// let a = [1, 2, 3];
     ///
-    /// let doubled: VecDeque<i32> = a.iter().map(|&x| x * 2).collect();
+    /// let doubled: VecDeque<i32> = a.iter().map(|x| x * 2).collect();
     ///
     /// assert_eq!(2, doubled[0]);
     /// assert_eq!(4, doubled[1]);
@@ -1953,8 +1951,8 @@ pub trait Iterator {
     /// ```
     /// let chars = ['g', 'd', 'k', 'k', 'n'];
     ///
-    /// let hello: String = chars.iter()
-    ///     .map(|&x| x as u8)
+    /// let hello: String = chars.into_iter()
+    ///     .map(|x| x as u8)
     ///     .map(|x| (x + 1) as char)
     ///     .collect();
     ///
@@ -1967,14 +1965,14 @@ pub trait Iterator {
     /// ```
     /// let results = [Ok(1), Err("nope"), Ok(3), Err("bad")];
     ///
-    /// let result: Result<Vec<_>, &str> = results.iter().cloned().collect();
+    /// let result: Result<Vec<_>, &str> = results.into_iter().collect();
     ///
     /// // gives us the first error
     /// assert_eq!(Err("nope"), result);
     ///
     /// let results = [Ok(1), Ok(3)];
     ///
-    /// let result: Result<Vec<_>, &str> = results.iter().cloned().collect();
+    /// let result: Result<Vec<_>, &str> = results.into_iter().collect();
     ///
     /// // gives us the list of answers
     /// assert_eq!(Ok(vec![1, 3]), result);
@@ -2105,8 +2103,8 @@ pub trait Iterator {
     /// let a = [1, 2, 3];
     /// let mut vec: Vec::<i32> = vec![0, 1];
     ///
-    /// a.iter().map(|&x| x * 2).collect_into(&mut vec);
-    /// a.iter().map(|&x| x * 10).collect_into(&mut vec);
+    /// a.iter().map(|x| x * 2).collect_into(&mut vec);
+    /// a.iter().map(|x| x * 10).collect_into(&mut vec);
     ///
     /// assert_eq!(vec, vec![0, 1, 2, 4, 6, 10, 20, 30]);
     /// ```
@@ -2119,8 +2117,8 @@ pub trait Iterator {
     /// let a = [1, 2, 3];
     /// let mut vec: Vec::<i32> = Vec::with_capacity(6);
     ///
-    /// a.iter().map(|&x| x * 2).collect_into(&mut vec);
-    /// a.iter().map(|&x| x * 10).collect_into(&mut vec);
+    /// a.iter().map(|x| x * 2).collect_into(&mut vec);
+    /// a.iter().map(|x| x * 10).collect_into(&mut vec);
     ///
     /// assert_eq!(6, vec.capacity());
     /// assert_eq!(vec, vec![2, 4, 6, 10, 20, 30]);
@@ -2174,8 +2172,8 @@ pub trait Iterator {
     ///     .into_iter()
     ///     .partition(|n| n % 2 == 0);
     ///
-    /// assert_eq!(even, vec![2]);
-    /// assert_eq!(odd, vec![1, 3]);
+    /// assert_eq!(even, [2]);
+    /// assert_eq!(odd, [1, 3]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn partition<B, F>(self, f: F) -> (B, B)
@@ -2233,11 +2231,11 @@ pub trait Iterator {
     /// let mut a = [1, 2, 3, 4, 5, 6, 7];
     ///
     /// // Partition in-place between evens and odds
-    /// let i = a.iter_mut().partition_in_place(|&n| n % 2 == 0);
+    /// let i = a.iter_mut().partition_in_place(|n| n % 2 == 0);
     ///
     /// assert_eq!(i, 3);
-    /// assert!(a[..i].iter().all(|&n| n % 2 == 0)); // evens
-    /// assert!(a[i..].iter().all(|&n| n % 2 == 1)); // odds
+    /// assert!(a[..i].iter().all(|n| n % 2 == 0)); // evens
+    /// assert!(a[i..].iter().all(|n| n % 2 == 1)); // odds
     /// ```
     #[unstable(feature = "iter_partition_in_place", reason = "new API", issue = "62543")]
     fn partition_in_place<'a, T: 'a, P>(mut self, ref mut predicate: P) -> usize
@@ -2344,7 +2342,7 @@ pub trait Iterator {
     /// let a = [1, 2, 3];
     ///
     /// // the checked sum of all of the elements of the array
-    /// let sum = a.iter().try_fold(0i8, |acc, &x| acc.checked_add(x));
+    /// let sum = a.into_iter().try_fold(0i8, |acc, x| acc.checked_add(x));
     ///
     /// assert_eq!(sum, Some(6));
     /// ```
@@ -2353,16 +2351,16 @@ pub trait Iterator {
     ///
     /// ```
     /// let a = [10, 20, 30, 100, 40, 50];
-    /// let mut it = a.iter();
+    /// let mut iter = a.into_iter();
     ///
     /// // This sum overflows when adding the 100 element
-    /// let sum = it.try_fold(0i8, |acc, &x| acc.checked_add(x));
+    /// let sum = iter.try_fold(0i8, |acc, x| acc.checked_add(x));
     /// assert_eq!(sum, None);
     ///
     /// // Because it short-circuited, the remaining elements are still
     /// // available through the iterator.
-    /// assert_eq!(it.len(), 2);
-    /// assert_eq!(it.next(), Some(&40));
+    /// assert_eq!(iter.len(), 2);
+    /// assert_eq!(iter.next(), Some(40));
     /// ```
     ///
     /// While you cannot `break` from a closure, the [`ControlFlow`] type allows
@@ -2715,9 +2713,9 @@ pub trait Iterator {
     /// ```
     /// let a = [1, 2, 3];
     ///
-    /// assert!(a.iter().all(|&x| x > 0));
+    /// assert!(a.into_iter().all(|x| x > 0));
     ///
-    /// assert!(!a.iter().all(|&x| x > 2));
+    /// assert!(!a.into_iter().all(|x| x > 2));
     /// ```
     ///
     /// Stopping at the first `false`:
@@ -2725,12 +2723,12 @@ pub trait Iterator {
     /// ```
     /// let a = [1, 2, 3];
     ///
-    /// let mut iter = a.iter();
+    /// let mut iter = a.into_iter();
     ///
-    /// assert!(!iter.all(|&x| x != 2));
+    /// assert!(!iter.all(|x| x != 2));
     ///
     /// // we can still use `iter`, as there are more elements.
-    /// assert_eq!(iter.next(), Some(&3));
+    /// assert_eq!(iter.next(), Some(3));
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -2768,9 +2766,9 @@ pub trait Iterator {
     /// ```
     /// let a = [1, 2, 3];
     ///
-    /// assert!(a.iter().any(|&x| x > 0));
+    /// assert!(a.into_iter().any(|x| x > 0));
     ///
-    /// assert!(!a.iter().any(|&x| x > 5));
+    /// assert!(!a.into_iter().any(|x| x > 5));
     /// ```
     ///
     /// Stopping at the first `true`:
@@ -2778,12 +2776,12 @@ pub trait Iterator {
     /// ```
     /// let a = [1, 2, 3];
     ///
-    /// let mut iter = a.iter();
+    /// let mut iter = a.into_iter();
     ///
-    /// assert!(iter.any(|&x| x != 2));
+    /// assert!(iter.any(|x| x != 2));
     ///
     /// // we can still use `iter`, as there are more elements.
-    /// assert_eq!(iter.next(), Some(&2));
+    /// assert_eq!(iter.next(), Some(2));
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -2829,9 +2827,8 @@ pub trait Iterator {
     /// ```
     /// let a = [1, 2, 3];
     ///
-    /// assert_eq!(a.iter().find(|&&x| x == 2), Some(&2));
-    ///
-    /// assert_eq!(a.iter().find(|&&x| x == 5), None);
+    /// assert_eq!(a.into_iter().find(|&x| x == 2), Some(2));
+    /// assert_eq!(a.into_iter().find(|&x| x == 5), None);
     /// ```
     ///
     /// Stopping at the first `true`:
@@ -2839,12 +2836,12 @@ pub trait Iterator {
     /// ```
     /// let a = [1, 2, 3];
     ///
-    /// let mut iter = a.iter();
+    /// let mut iter = a.into_iter();
     ///
-    /// assert_eq!(iter.find(|&&x| x == 2), Some(&2));
+    /// assert_eq!(iter.find(|&x| x == 2), Some(2));
     ///
     /// // we can still use `iter`, as there are more elements.
-    /// assert_eq!(iter.next(), Some(&3));
+    /// assert_eq!(iter.next(), Some(3));
     /// ```
     ///
     /// Note that `iter.find(f)` is equivalent to `iter.filter(f).next()`.
@@ -2912,13 +2909,13 @@ pub trait Iterator {
     /// let a = ["1", "2", "lol", "NaN", "5"];
     ///
     /// let is_my_num = |s: &str, search: i32| -> Result<bool, std::num::ParseIntError> {
-    ///     Ok(s.parse::<i32>()?  == search)
+    ///     Ok(s.parse::<i32>()? == search)
     /// };
     ///
-    /// let result = a.iter().try_find(|&&s| is_my_num(s, 2));
-    /// assert_eq!(result, Ok(Some(&"2")));
+    /// let result = a.into_iter().try_find(|&s| is_my_num(s, 2));
+    /// assert_eq!(result, Ok(Some("2")));
     ///
-    /// let result = a.iter().try_find(|&&s| is_my_num(s, 5));
+    /// let result = a.into_iter().try_find(|&s| is_my_num(s, 5));
     /// assert!(result.is_err());
     /// ```
     ///
@@ -2930,11 +2927,11 @@ pub trait Iterator {
     /// use std::num::NonZero;
     ///
     /// let a = [3, 5, 7, 4, 9, 0, 11u32];
-    /// let result = a.iter().try_find(|&&x| NonZero::new(x).map(|y| y.is_power_of_two()));
-    /// assert_eq!(result, Some(Some(&4)));
-    /// let result = a.iter().take(3).try_find(|&&x| NonZero::new(x).map(|y| y.is_power_of_two()));
+    /// let result = a.into_iter().try_find(|&x| NonZero::new(x).map(|y| y.is_power_of_two()));
+    /// assert_eq!(result, Some(Some(4)));
+    /// let result = a.into_iter().take(3).try_find(|&x| NonZero::new(x).map(|y| y.is_power_of_two()));
     /// assert_eq!(result, Some(None));
-    /// let result = a.iter().rev().try_find(|&&x| NonZero::new(x).map(|y| y.is_power_of_two()));
+    /// let result = a.into_iter().rev().try_find(|&x| NonZero::new(x).map(|y| y.is_power_of_two()));
     /// assert_eq!(result, None);
     /// ```
     #[inline]
@@ -2999,9 +2996,9 @@ pub trait Iterator {
     /// ```
     /// let a = [1, 2, 3];
     ///
-    /// assert_eq!(a.iter().position(|&x| x == 2), Some(1));
+    /// assert_eq!(a.into_iter().position(|x| x == 2), Some(1));
     ///
-    /// assert_eq!(a.iter().position(|&x| x == 5), None);
+    /// assert_eq!(a.into_iter().position(|x| x == 5), None);
     /// ```
     ///
     /// Stopping at the first `true`:
@@ -3009,15 +3006,15 @@ pub trait Iterator {
     /// ```
     /// let a = [1, 2, 3, 4];
     ///
-    /// let mut iter = a.iter();
+    /// let mut iter = a.into_iter();
     ///
-    /// assert_eq!(iter.position(|&x| x >= 2), Some(1));
+    /// assert_eq!(iter.position(|x| x >= 2), Some(1));
     ///
     /// // we can still use `iter`, as there are more elements.
-    /// assert_eq!(iter.next(), Some(&3));
+    /// assert_eq!(iter.next(), Some(3));
     ///
     /// // The returned index depends on iterator state
-    /// assert_eq!(iter.position(|&x| x == 4), Some(0));
+    /// assert_eq!(iter.position(|x| x == 4), Some(0));
     ///
     /// ```
     #[inline]
@@ -3067,9 +3064,9 @@ pub trait Iterator {
     /// ```
     /// let a = [1, 2, 3];
     ///
-    /// assert_eq!(a.iter().rposition(|&x| x == 3), Some(2));
+    /// assert_eq!(a.into_iter().rposition(|x| x == 3), Some(2));
     ///
-    /// assert_eq!(a.iter().rposition(|&x| x == 5), None);
+    /// assert_eq!(a.into_iter().rposition(|x| x == 5), None);
     /// ```
     ///
     /// Stopping at the first `true`:
@@ -3077,13 +3074,13 @@ pub trait Iterator {
     /// ```
     /// let a = [-1, 2, 3, 4];
     ///
-    /// let mut iter = a.iter();
+    /// let mut iter = a.into_iter();
     ///
-    /// assert_eq!(iter.rposition(|&x| x >= 2), Some(3));
+    /// assert_eq!(iter.rposition(|x| x >= 2), Some(3));
     ///
     /// // we can still use `iter`, as there are more elements.
-    /// assert_eq!(iter.next(), Some(&-1));
-    /// assert_eq!(iter.next_back(), Some(&3));
+    /// assert_eq!(iter.next(), Some(-1));
+    /// assert_eq!(iter.next_back(), Some(3));
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -3129,10 +3126,10 @@ pub trait Iterator {
     ///
     /// ```
     /// let a = [1, 2, 3];
-    /// let b: Vec<u32> = Vec::new();
+    /// let b: [u32; 0] = [];
     ///
-    /// assert_eq!(a.iter().max(), Some(&3));
-    /// assert_eq!(b.iter().max(), None);
+    /// assert_eq!(a.into_iter().max(), Some(3));
+    /// assert_eq!(b.into_iter().max(), None);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -3165,10 +3162,10 @@ pub trait Iterator {
     ///
     /// ```
     /// let a = [1, 2, 3];
-    /// let b: Vec<u32> = Vec::new();
+    /// let b: [u32; 0] = [];
     ///
-    /// assert_eq!(a.iter().min(), Some(&1));
-    /// assert_eq!(b.iter().min(), None);
+    /// assert_eq!(a.into_iter().min(), Some(1));
+    /// assert_eq!(b.into_iter().min(), None);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -3190,7 +3187,7 @@ pub trait Iterator {
     ///
     /// ```
     /// let a = [-3_i32, 0, 1, 5, -10];
-    /// assert_eq!(*a.iter().max_by_key(|x| x.abs()).unwrap(), -10);
+    /// assert_eq!(a.into_iter().max_by_key(|x| x.abs()).unwrap(), -10);
     /// ```
     #[inline]
     #[stable(feature = "iter_cmp_by_key", since = "1.6.0")]
@@ -3223,7 +3220,7 @@ pub trait Iterator {
     ///
     /// ```
     /// let a = [-3_i32, 0, 1, 5, -10];
-    /// assert_eq!(*a.iter().max_by(|x, y| x.cmp(y)).unwrap(), 5);
+    /// assert_eq!(a.into_iter().max_by(|x, y| x.cmp(y)).unwrap(), 5);
     /// ```
     #[inline]
     #[stable(feature = "iter_max_by", since = "1.15.0")]
@@ -3250,7 +3247,7 @@ pub trait Iterator {
     ///
     /// ```
     /// let a = [-3_i32, 0, 1, 5, -10];
-    /// assert_eq!(*a.iter().min_by_key(|x| x.abs()).unwrap(), 0);
+    /// assert_eq!(a.into_iter().min_by_key(|x| x.abs()).unwrap(), 0);
     /// ```
     #[inline]
     #[stable(feature = "iter_cmp_by_key", since = "1.6.0")]
@@ -3283,7 +3280,7 @@ pub trait Iterator {
     ///
     /// ```
     /// let a = [-3_i32, 0, 1, 5, -10];
-    /// assert_eq!(*a.iter().min_by(|x, y| x.cmp(y)).unwrap(), -10);
+    /// assert_eq!(a.into_iter().min_by(|x, y| x.cmp(y)).unwrap(), -10);
     /// ```
     #[inline]
     #[stable(feature = "iter_min_by", since = "1.15.0")]
@@ -3313,11 +3310,11 @@ pub trait Iterator {
     /// ```
     /// let a = [1, 2, 3];
     ///
-    /// let mut iter = a.iter().rev();
+    /// let mut iter = a.into_iter().rev();
     ///
-    /// assert_eq!(iter.next(), Some(&3));
-    /// assert_eq!(iter.next(), Some(&2));
-    /// assert_eq!(iter.next(), Some(&1));
+    /// assert_eq!(iter.next(), Some(3));
+    /// assert_eq!(iter.next(), Some(2));
+    /// assert_eq!(iter.next(), Some(1));
     ///
     /// assert_eq!(iter.next(), None);
     /// ```
@@ -3346,7 +3343,7 @@ pub trait Iterator {
     /// ```
     /// let a = [(1, 2), (3, 4), (5, 6)];
     ///
-    /// let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip();
+    /// let (left, right): (Vec<_>, Vec<_>) = a.into_iter().unzip();
     ///
     /// assert_eq!(left, [1, 3, 5]);
     /// assert_eq!(right, [2, 4, 6]);
@@ -3354,7 +3351,7 @@ pub trait Iterator {
     /// // you can also unzip multiple nested tuples at once
     /// let a = [(1, (2, 3)), (4, (5, 6))];
     ///
-    /// let (x, (y, z)): (Vec<_>, (Vec<_>, Vec<_>)) = a.iter().cloned().unzip();
+    /// let (x, (y, z)): (Vec<_>, (Vec<_>, Vec<_>)) = a.into_iter().unzip();
     /// assert_eq!(x, [1, 4]);
     /// assert_eq!(y, [2, 5]);
     /// assert_eq!(z, [3, 6]);
@@ -3386,8 +3383,8 @@ pub trait Iterator {
     /// // copied is the same as .map(|&x| x)
     /// let v_map: Vec<_> = a.iter().map(|&x| x).collect();
     ///
-    /// assert_eq!(v_copied, vec![1, 2, 3]);
-    /// assert_eq!(v_map, vec![1, 2, 3]);
+    /// assert_eq!(v_copied, [1, 2, 3]);
+    /// assert_eq!(v_map, [1, 2, 3]);
     /// ```
     #[stable(feature = "iter_copied", since = "1.36.0")]
     #[rustc_diagnostic_item = "iter_copied"]
@@ -3422,8 +3419,8 @@ pub trait Iterator {
     /// // cloned is the same as .map(|&x| x), for integers
     /// let v_map: Vec<_> = a.iter().map(|&x| x).collect();
     ///
-    /// assert_eq!(v_cloned, vec![1, 2, 3]);
-    /// assert_eq!(v_map, vec![1, 2, 3]);
+    /// assert_eq!(v_cloned, [1, 2, 3]);
+    /// assert_eq!(v_map, [1, 2, 3]);
     /// ```
     ///
     /// To get the best performance, try to clone late:
@@ -3459,15 +3456,14 @@ pub trait Iterator {
     /// ```
     /// let a = [1, 2, 3];
     ///
-    /// let mut it = a.iter().cycle();
+    /// let mut iter = a.into_iter().cycle();
     ///
-    /// assert_eq!(it.next(), Some(&1));
-    /// assert_eq!(it.next(), Some(&2));
-    /// assert_eq!(it.next(), Some(&3));
-    /// assert_eq!(it.next(), Some(&1));
-    /// assert_eq!(it.next(), Some(&2));
-    /// assert_eq!(it.next(), Some(&3));
-    /// assert_eq!(it.next(), Some(&1));
+    /// loop {
+    ///     assert_eq!(iter.next(), Some(1));
+    ///     assert_eq!(iter.next(), Some(2));
+    ///     assert_eq!(iter.next(), Some(3));
+    /// #   break;
+    /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
@@ -3625,9 +3621,9 @@ pub trait Iterator {
     /// let xs = [1, 2, 3, 4];
     /// let ys = [1, 4, 9, 16];
     ///
-    /// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| x.cmp(&y)), Ordering::Less);
-    /// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (x * x).cmp(&y)), Ordering::Equal);
-    /// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (2 * x).cmp(&y)), Ordering::Greater);
+    /// assert_eq!(xs.into_iter().cmp_by(ys, |x, y| x.cmp(&y)), Ordering::Less);
+    /// assert_eq!(xs.into_iter().cmp_by(ys, |x, y| (x * x).cmp(&y)), Ordering::Equal);
+    /// assert_eq!(xs.into_iter().cmp_by(ys, |x, y| (2 * x).cmp(&y)), Ordering::Greater);
     /// ```
     #[unstable(feature = "iter_order_by", issue = "64295")]
     fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
@@ -3709,15 +3705,15 @@ pub trait Iterator {
     /// let ys = [1.0, 4.0, 9.0, 16.0];
     ///
     /// assert_eq!(
-    ///     xs.iter().partial_cmp_by(&ys, |&x, &y| x.partial_cmp(&y)),
+    ///     xs.iter().partial_cmp_by(ys, |x, y| x.partial_cmp(&y)),
     ///     Some(Ordering::Less)
     /// );
     /// assert_eq!(
-    ///     xs.iter().partial_cmp_by(&ys, |&x, &y| (x * x).partial_cmp(&y)),
+    ///     xs.iter().partial_cmp_by(ys, |x, y| (x * x).partial_cmp(&y)),
     ///     Some(Ordering::Equal)
     /// );
     /// assert_eq!(
-    ///     xs.iter().partial_cmp_by(&ys, |&x, &y| (2.0 * x).partial_cmp(&y)),
+    ///     xs.iter().partial_cmp_by(ys, |x, y| (2.0 * x).partial_cmp(&y)),
     ///     Some(Ordering::Greater)
     /// );
     /// ```
@@ -3775,7 +3771,7 @@ pub trait Iterator {
     /// let xs = [1, 2, 3, 4];
     /// let ys = [1, 4, 9, 16];
     ///
-    /// assert!(xs.iter().eq_by(&ys, |&x, &y| x * x == y));
+    /// assert!(xs.iter().eq_by(ys, |x, y| x * x == y));
     /// ```
     #[unstable(feature = "iter_order_by", issue = "64295")]
     fn eq_by<I, F>(self, other: I, eq: F) -> bool
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 3ad6662bdd7..7dc8c060cd5 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1661,7 +1661,6 @@ pub(crate) mod builtin {
     #[unstable(
         feature = "test",
         issue = "50297",
-        soft,
         reason = "`bench` is a part of custom test frameworks which are unstable"
     )]
     #[allow_internal_unstable(test, rustc_attrs, coverage_attribute)]
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 445c789a7de..aa103af93ff 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -1065,10 +1065,45 @@ pub const unsafe fn swap<T>(x: *mut T, y: *mut T) {
 /// assert_eq!(x, [7, 8, 3, 4]);
 /// assert_eq!(y, [1, 2, 9]);
 /// ```
+///
+/// # Const evaluation limitations
+///
+/// If this function is invoked during const-evaluation, the current implementation has a small (and
+/// rarely relevant) limitation: if `count` is at least 2 and the data pointed to by `x` or `y`
+/// contains a pointer that crosses the boundary of two `T`-sized chunks of memory, the function may
+/// fail to evaluate (similar to a panic during const-evaluation). This behavior may change in the
+/// future.
+///
+/// The limitation is illustrated by the following example:
+///
+/// ```
+/// use std::mem::size_of;
+/// use std::ptr;
+///
+/// const { unsafe {
+///     const PTR_SIZE: usize = size_of::<*const i32>();
+///     let mut data1 = [0u8; PTR_SIZE];
+///     let mut data2 = [0u8; PTR_SIZE];
+///     // Store a pointer in `data1`.
+///     data1.as_mut_ptr().cast::<*const i32>().write_unaligned(&42);
+///     // Swap the contents of `data1` and `data2` by swapping `PTR_SIZE` many `u8`-sized chunks.
+///     // This call will fail, because the pointer in `data1` crosses the boundary
+///     // between several of the 1-byte chunks that are being swapped here.
+///     //ptr::swap_nonoverlapping(data1.as_mut_ptr(), data2.as_mut_ptr(), PTR_SIZE);
+///     // Swap the contents of `data1` and `data2` by swapping a single chunk of size
+///     // `[u8; PTR_SIZE]`. That works, as there is no pointer crossing the boundary between
+///     // two chunks.
+///     ptr::swap_nonoverlapping(&mut data1, &mut data2, 1);
+///     // Read the pointer from `data2` and dereference it.
+///     let ptr = data2.as_ptr().cast::<*const i32>().read_unaligned();
+///     assert!(*ptr == 42);
+/// } }
+/// ```
 #[inline]
 #[stable(feature = "swap_nonoverlapping", since = "1.27.0")]
-#[rustc_const_unstable(feature = "const_swap_nonoverlapping", issue = "133668")]
+#[rustc_const_stable(feature = "const_swap_nonoverlapping", since = "CURRENT_RUSTC_VERSION")]
 #[rustc_diagnostic_item = "ptr_swap_nonoverlapping"]
+#[rustc_allow_const_fn_unstable(const_eval_select)] // both implementations behave the same
 pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
     ub_checks::assert_unsafe_precondition!(
         check_library_ub,
diff --git a/library/core/src/str/lossy.rs b/library/core/src/str/lossy.rs
index ed2cefc59a5..8d4210c8082 100644
--- a/library/core/src/str/lossy.rs
+++ b/library/core/src/str/lossy.rs
@@ -147,12 +147,14 @@ impl fmt::Debug for Debug<'_> {
 /// An iterator used to decode a slice of mostly UTF-8 bytes to string slices
 /// ([`&str`]) and byte slices ([`&[u8]`][byteslice]).
 ///
+/// This struct is created by the [`utf8_chunks`] method on bytes slices.
 /// If you want a simple conversion from UTF-8 byte slices to string slices,
 /// [`from_utf8`] is easier to use.
 ///
 /// See the [`Utf8Chunk`] type for documentation of the items yielded by this iterator.
 ///
 /// [byteslice]: slice
+/// [`utf8_chunks`]: slice::utf8_chunks
 /// [`from_utf8`]: super::from_utf8
 ///
 /// # Examples
diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs
index f52e338a085..a71c4139308 100644
--- a/library/coretests/tests/lib.rs
+++ b/library/coretests/tests/lib.rs
@@ -15,7 +15,6 @@
 #![feature(char_max_len)]
 #![feature(clone_to_uninit)]
 #![feature(const_eval_select)]
-#![feature(const_swap_nonoverlapping)]
 #![feature(const_trait_impl)]
 #![feature(core_intrinsics)]
 #![feature(core_intrinsics_fallbacks)]
diff --git a/library/coretests/tests/ptr.rs b/library/coretests/tests/ptr.rs
index 7d6e4eac1e2..bb60fb07468 100644
--- a/library/coretests/tests/ptr.rs
+++ b/library/coretests/tests/ptr.rs
@@ -949,6 +949,10 @@ fn test_const_swap_ptr() {
         // Make sure they still work.
         assert!(*s1.0.ptr == 1);
         assert!(*s2.0.ptr == 666);
+
+        // This is where we'd swap again using a `u8` type and a `count` of `size_of::<T>()` if it
+        // were not for the limitation of `swap_nonoverlapping` around pointers crossing multiple
+        // elements.
     };
 }
 
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 36a1c57b020..79e9b8430b8 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -543,18 +543,18 @@ impl Span {
     /// The path to the source file in which this span occurs, for display purposes.
     ///
     /// This might not correspond to a valid file system path.
-    /// It might be remapped, or might be an artificial path such as `"<macro expansion>"`.
-    #[unstable(feature = "proc_macro_span", issue = "54725")]
+    /// It might be remapped (e.g. `"/src/lib.rs"`) or an artificial path (e.g. `"<command line>"`).
+    #[stable(feature = "proc_macro_span_file", since = "CURRENT_RUSTC_VERSION")]
     pub fn file(&self) -> String {
         self.0.file()
     }
 
-    /// The path to the source file in which this span occurs on disk.
+    /// The path to the source file in which this span occurs on the local file system.
     ///
     /// This is the actual path on disk. It is unaffected by path remapping.
     ///
     /// This path should not be embedded in the output of the macro; prefer `file()` instead.
-    #[unstable(feature = "proc_macro_span", issue = "54725")]
+    #[stable(feature = "proc_macro_span_file", since = "CURRENT_RUSTC_VERSION")]
     pub fn local_file(&self) -> Option<PathBuf> {
         self.0.local_file().map(|s| PathBuf::from(s))
     }
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index d7bd28b5279..7915196e8e8 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -18,7 +18,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
 panic_unwind = { path = "../panic_unwind", optional = true }
 panic_abort = { path = "../panic_abort" }
 core = { path = "../core", public = true }
-compiler_builtins = { version = "=0.1.156" }
+compiler_builtins = { version = "=0.1.158" }
 unwind = { path = "../unwind" }
 hashbrown = { version = "0.15", default-features = false, features = [
     'rustc-dep-of-std',
@@ -57,7 +57,7 @@ object = { version = "0.36.0", default-features = false, optional = true, featur
     'archive',
 ] }
 
-[target.'cfg(windows)'.dependencies.windows-targets]
+[target.'cfg(any(windows, target_os = "cygwin"))'.dependencies.windows-targets]
 path = "../windows_targets"
 
 [dev-dependencies]
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 9ad26e5d28e..961d6ee0665 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -683,7 +683,7 @@ impl<K, V, S> HashMap<K, V, S> {
     /// ```
     #[inline]
     #[rustc_lint_query_instability]
-    #[stable(feature = "hash_extract_if", since = "1.87.0")]
+    #[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
     pub fn extract_if<F>(&mut self, pred: F) -> ExtractIf<'_, K, V, F>
     where
         F: FnMut(&K, &mut V) -> bool,
@@ -1680,12 +1680,9 @@ impl<'a, K, V> Drain<'a, K, V> {
 /// ]);
 /// let iter = map.extract_if(|_k, v| *v % 2 == 0);
 /// ```
-#[stable(feature = "hash_extract_if", since = "1.87.0")]
+#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
 #[must_use = "iterators are lazy and do nothing unless consumed"]
-pub struct ExtractIf<'a, K, V, F>
-where
-    F: FnMut(&K, &mut V) -> bool,
-{
+pub struct ExtractIf<'a, K, V, F> {
     base: base::ExtractIf<'a, K, V, F>,
 }
 
@@ -2297,7 +2294,7 @@ where
     }
 }
 
-#[stable(feature = "hash_extract_if", since = "1.87.0")]
+#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
 impl<K, V, F> Iterator for ExtractIf<'_, K, V, F>
 where
     F: FnMut(&K, &mut V) -> bool,
@@ -2314,13 +2311,14 @@ where
     }
 }
 
-#[stable(feature = "hash_extract_if", since = "1.87.0")]
+#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
 impl<K, V, F> FusedIterator for ExtractIf<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool {}
 
-#[stable(feature = "hash_extract_if", since = "1.87.0")]
-impl<'a, K, V, F> fmt::Debug for ExtractIf<'a, K, V, F>
+#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
+impl<K, V, F> fmt::Debug for ExtractIf<'_, K, V, F>
 where
-    F: FnMut(&K, &mut V) -> bool,
+    K: fmt::Debug,
+    V: fmt::Debug,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("ExtractIf").finish_non_exhaustive()
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index 7be000594bc..fa2f4f0a58f 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -308,7 +308,7 @@ impl<T, S> HashSet<T, S> {
     /// ```
     #[inline]
     #[rustc_lint_query_instability]
-    #[stable(feature = "hash_extract_if", since = "1.87.0")]
+    #[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
     pub fn extract_if<F>(&mut self, pred: F) -> ExtractIf<'_, T, F>
     where
         F: FnMut(&T) -> bool,
@@ -1390,11 +1390,8 @@ pub struct Drain<'a, K: 'a> {
 ///
 /// let mut extract_ifed = a.extract_if(|v| v % 2 == 0);
 /// ```
-#[stable(feature = "hash_extract_if", since = "1.87.0")]
-pub struct ExtractIf<'a, K, F>
-where
-    F: FnMut(&K) -> bool,
-{
+#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
+pub struct ExtractIf<'a, K, F> {
     base: base::ExtractIf<'a, K, F>,
 }
 
@@ -1673,7 +1670,7 @@ impl<K: fmt::Debug> fmt::Debug for Drain<'_, K> {
     }
 }
 
-#[stable(feature = "hash_extract_if", since = "1.87.0")]
+#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
 impl<K, F> Iterator for ExtractIf<'_, K, F>
 where
     F: FnMut(&K) -> bool,
@@ -1690,13 +1687,13 @@ where
     }
 }
 
-#[stable(feature = "hash_extract_if", since = "1.87.0")]
+#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
 impl<K, F> FusedIterator for ExtractIf<'_, K, F> where F: FnMut(&K) -> bool {}
 
-#[stable(feature = "hash_extract_if", since = "1.87.0")]
-impl<'a, K, F> fmt::Debug for ExtractIf<'a, K, F>
+#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")]
+impl<K, F> fmt::Debug for ExtractIf<'_, K, F>
 where
-    F: FnMut(&K) -> bool,
+    K: fmt::Debug,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("ExtractIf").finish_non_exhaustive()
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 462c06dcea2..11f439b9996 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -21,7 +21,6 @@
 mod tests;
 
 use crate::ffi::OsString;
-use crate::fmt;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};
 use crate::path::{Path, PathBuf};
 use crate::sealed::Sealed;
@@ -29,6 +28,7 @@ use crate::sync::Arc;
 use crate::sys::fs as fs_imp;
 use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 use crate::time::SystemTime;
+use crate::{error, fmt};
 
 /// An object providing access to an open file on the filesystem.
 ///
@@ -116,6 +116,22 @@ pub struct File {
     inner: fs_imp::File,
 }
 
+/// An enumeration of possible errors which can occur while trying to acquire a lock
+/// from the [`try_lock`] method and [`try_lock_shared`] method on a [`File`].
+///
+/// [`try_lock`]: File::try_lock
+/// [`try_lock_shared`]: File::try_lock_shared
+#[unstable(feature = "file_lock", issue = "130994")]
+pub enum TryLockError {
+    /// The lock could not be acquired due to an I/O error on the file. The standard library will
+    /// not return an [`ErrorKind::WouldBlock`] error inside [`TryLockError::Error`]
+    ///
+    /// [`ErrorKind::WouldBlock`]: io::ErrorKind::WouldBlock
+    Error(io::Error),
+    /// The lock could not be acquired at this time because it is held by another handle/process.
+    WouldBlock,
+}
+
 /// Metadata information about a file.
 ///
 /// This structure is returned from the [`metadata`] or
@@ -352,6 +368,30 @@ pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result
     inner(path.as_ref(), contents.as_ref())
 }
 
+#[unstable(feature = "file_lock", issue = "130994")]
+impl error::Error for TryLockError {}
+
+#[unstable(feature = "file_lock", issue = "130994")]
+impl fmt::Debug for TryLockError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            TryLockError::Error(err) => err.fmt(f),
+            TryLockError::WouldBlock => "WouldBlock".fmt(f),
+        }
+    }
+}
+
+#[unstable(feature = "file_lock", issue = "130994")]
+impl fmt::Display for TryLockError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            TryLockError::Error(_) => "lock acquisition failed due to I/O error",
+            TryLockError::WouldBlock => "lock acquisition failed because the operation would block",
+        }
+        .fmt(f)
+    }
+}
+
 impl File {
     /// Attempts to open a file in read-only mode.
     ///
@@ -734,8 +774,8 @@ impl File {
 
     /// Try to acquire an exclusive lock on the file.
     ///
-    /// Returns `Ok(false)` if a different lock is already held on this file (via another
-    /// handle/descriptor).
+    /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file
+    /// (via another handle/descriptor).
     ///
     /// This acquires an exclusive lock; no other file handle to this file may acquire another lock.
     ///
@@ -777,23 +817,27 @@ impl File {
     ///
     /// ```no_run
     /// #![feature(file_lock)]
-    /// use std::fs::File;
+    /// use std::fs::{File, TryLockError};
     ///
     /// fn main() -> std::io::Result<()> {
     ///     let f = File::create("foo.txt")?;
-    ///     f.try_lock()?;
+    ///     match f.try_lock() {
+    ///         Ok(_) => (),
+    ///         Err(TryLockError::WouldBlock) => (), // Lock not acquired
+    ///         Err(TryLockError::Error(err)) => return Err(err),
+    ///     }
     ///     Ok(())
     /// }
     /// ```
     #[unstable(feature = "file_lock", issue = "130994")]
-    pub fn try_lock(&self) -> io::Result<bool> {
+    pub fn try_lock(&self) -> Result<(), TryLockError> {
         self.inner.try_lock()
     }
 
     /// Try to acquire a shared (non-exclusive) lock on the file.
     ///
-    /// Returns `Ok(false)` if an exclusive lock is already held on this file (via another
-    /// handle/descriptor).
+    /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file
+    /// (via another handle/descriptor).
     ///
     /// This acquires a shared lock; more than one file handle may hold a shared lock, but none may
     /// hold an exclusive lock at the same time.
@@ -834,16 +878,21 @@ impl File {
     ///
     /// ```no_run
     /// #![feature(file_lock)]
-    /// use std::fs::File;
+    /// use std::fs::{File, TryLockError};
     ///
     /// fn main() -> std::io::Result<()> {
     ///     let f = File::open("foo.txt")?;
-    ///     f.try_lock_shared()?;
+    ///     match f.try_lock_shared() {
+    ///         Ok(_) => (),
+    ///         Err(TryLockError::WouldBlock) => (), // Lock not acquired
+    ///         Err(TryLockError::Error(err)) => return Err(err),
+    ///     }
+    ///
     ///     Ok(())
     /// }
     /// ```
     #[unstable(feature = "file_lock", issue = "130994")]
-    pub fn try_lock_shared(&self) -> io::Result<bool> {
+    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
         self.inner.try_lock_shared()
     }
 
@@ -2994,7 +3043,7 @@ pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir> {
 /// When possible, permissions should be set at creation time instead.
 ///
 /// # Rationale
-/// POSIX does not specify an `lchown` function,
+/// POSIX does not specify an `lchmod` function,
 /// and symlinks can be followed regardless of what permission bits are set.
 ///
 /// # Errors
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 4712e58980c..c81a5ff4d96 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -1,6 +1,22 @@
 use rand::RngCore;
 
+#[cfg(any(
+    windows,
+    target_os = "freebsd",
+    target_os = "linux",
+    target_os = "netbsd",
+    target_vendor = "apple",
+))]
+use crate::assert_matches::assert_matches;
 use crate::char::MAX_LEN_UTF8;
+#[cfg(any(
+    windows,
+    target_os = "freebsd",
+    target_os = "linux",
+    target_os = "netbsd",
+    target_vendor = "apple",
+))]
+use crate::fs::TryLockError;
 use crate::fs::{self, File, FileTimes, OpenOptions};
 use crate::io::prelude::*;
 use crate::io::{BorrowedBuf, ErrorKind, SeekFrom};
@@ -223,8 +239,8 @@ fn file_lock_multiple_shared() {
     check!(f2.lock_shared());
     check!(f1.unlock());
     check!(f2.unlock());
-    assert!(check!(f1.try_lock_shared()));
-    assert!(check!(f2.try_lock_shared()));
+    check!(f1.try_lock_shared());
+    check!(f2.try_lock_shared());
 }
 
 #[test]
@@ -243,12 +259,12 @@ fn file_lock_blocking() {
 
     // Check that shared locks block exclusive locks
     check!(f1.lock_shared());
-    assert!(!check!(f2.try_lock()));
+    assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock));
     check!(f1.unlock());
 
     // Check that exclusive locks block shared locks
     check!(f1.lock());
-    assert!(!check!(f2.try_lock_shared()));
+    assert_matches!(f2.try_lock_shared(), Err(TryLockError::WouldBlock));
 }
 
 #[test]
@@ -267,9 +283,9 @@ fn file_lock_drop() {
 
     // Check that locks are released when the File is dropped
     check!(f1.lock_shared());
-    assert!(!check!(f2.try_lock()));
+    assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock));
     drop(f1);
-    assert!(check!(f2.try_lock()));
+    check!(f2.try_lock());
 }
 
 #[test]
@@ -288,10 +304,10 @@ fn file_lock_dup() {
 
     // Check that locks are not dropped if the File has been cloned
     check!(f1.lock_shared());
-    assert!(!check!(f2.try_lock()));
+    assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock));
     let cloned = check!(f1.try_clone());
     drop(f1);
-    assert!(!check!(f2.try_lock()));
+    assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock));
     drop(cloned)
 }
 
@@ -307,9 +323,9 @@ fn file_lock_double_unlock() {
     // Check that both are released by unlock()
     check!(f1.lock());
     check!(f1.lock_shared());
-    assert!(!check!(f2.try_lock()));
+    assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock));
     check!(f1.unlock());
-    assert!(check!(f2.try_lock()));
+    check!(f2.try_lock());
 }
 
 #[test]
@@ -714,6 +730,10 @@ fn recursive_mkdir_empty() {
 }
 
 #[test]
+#[cfg_attr(
+    all(windows, target_arch = "aarch64"),
+    ignore = "SymLinks not enabled on Arm64 Windows runners https://github.com/actions/partner-runner-images/issues/94"
+)]
 fn recursive_rmdir() {
     let tmpdir = tmpdir();
     let d1 = tmpdir.join("d1");
@@ -733,6 +753,10 @@ fn recursive_rmdir() {
 }
 
 #[test]
+#[cfg_attr(
+    all(windows, target_arch = "aarch64"),
+    ignore = "SymLinks not enabled on Arm64 Windows runners https://github.com/actions/partner-runner-images/issues/94"
+)]
 fn recursive_rmdir_of_symlink() {
     // test we do not recursively delete a symlink but only dirs.
     let tmpdir = tmpdir();
@@ -1517,6 +1541,10 @@ fn file_open_not_found() {
 }
 
 #[test]
+#[cfg_attr(
+    all(windows, target_arch = "aarch64"),
+    ignore = "SymLinks not enabled on Arm64 Windows runners https://github.com/actions/partner-runner-images/issues/94"
+)]
 fn create_dir_all_with_junctions() {
     let tmpdir = tmpdir();
     let target = tmpdir.join("target");
@@ -1995,6 +2023,10 @@ fn test_rename_symlink() {
 
 #[test]
 #[cfg(windows)]
+#[cfg_attr(
+    all(windows, target_arch = "aarch64"),
+    ignore = "SymLinks not enabled on Arm64 Windows runners https://github.com/actions/partner-runner-images/issues/94"
+)]
 fn test_rename_junction() {
     let tmpdir = tmpdir();
     let original = tmpdir.join("original");
diff --git a/library/std/src/io/pipe.rs b/library/std/src/io/pipe.rs
index c6b7b49a351..47243806cd2 100644
--- a/library/std/src/io/pipe.rs
+++ b/library/std/src/io/pipe.rs
@@ -2,7 +2,7 @@ use crate::io;
 use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner};
 use crate::sys_common::{FromInner, IntoInner};
 
-/// Create an anonymous pipe.
+/// Creates an anonymous pipe.
 ///
 /// # Behavior
 ///
@@ -108,7 +108,7 @@ impl IntoInner<AnonPipe> for PipeWriter {
 }
 
 impl PipeReader {
-    /// Create a new [`PipeReader`] instance that shares the same underlying file description.
+    /// Creates a new [`PipeReader`] instance that shares the same underlying file description.
     ///
     /// # Examples
     ///
@@ -167,7 +167,7 @@ impl PipeReader {
 }
 
 impl PipeWriter {
-    /// Create a new [`PipeWriter`] instance that shares the same underlying file description.
+    /// Creates a new [`PipeWriter`] instance that shares the same underlying file description.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index 76ce7bce81b..df6b9a6e563 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -168,8 +168,6 @@ use crate::num::NonZero;
 use crate::path::Path;
 use crate::sys::pipe::{AnonPipe, read2};
 use crate::sys::process as imp;
-#[stable(feature = "command_access", since = "1.57.0")]
-pub use crate::sys_common::process::CommandEnvs;
 use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 use crate::{fmt, fs, str};
 
@@ -1073,7 +1071,7 @@ impl Command {
     /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn output(&mut self) -> io::Result<Output> {
-        let (status, stdout, stderr) = self.inner.output()?;
+        let (status, stdout, stderr) = imp::output(&mut self.inner)?;
         Ok(Output { status: ExitStatus(status), stdout, stderr })
     }
 
@@ -1174,7 +1172,7 @@ impl Command {
     /// ```
     #[stable(feature = "command_access", since = "1.57.0")]
     pub fn get_envs(&self) -> CommandEnvs<'_> {
-        self.inner.get_envs()
+        CommandEnvs { iter: self.inner.get_envs() }
     }
 
     /// Returns the working directory for the child process.
@@ -1264,6 +1262,48 @@ impl<'a> ExactSizeIterator for CommandArgs<'a> {
     }
 }
 
+/// An iterator over the command environment variables.
+///
+/// This struct is created by
+/// [`Command::get_envs`][crate::process::Command::get_envs]. See its
+/// documentation for more.
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[stable(feature = "command_access", since = "1.57.0")]
+pub struct CommandEnvs<'a> {
+    iter: imp::CommandEnvs<'a>,
+}
+
+#[stable(feature = "command_access", since = "1.57.0")]
+impl<'a> Iterator for CommandEnvs<'a> {
+    type Item = (&'a OsStr, Option<&'a OsStr>);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.iter.next()
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+}
+
+#[stable(feature = "command_access", since = "1.57.0")]
+impl<'a> ExactSizeIterator for CommandEnvs<'a> {
+    fn len(&self) -> usize {
+        self.iter.len()
+    }
+
+    fn is_empty(&self) -> bool {
+        self.iter.is_empty()
+    }
+}
+
+#[stable(feature = "command_access", since = "1.57.0")]
+impl<'a> fmt::Debug for CommandEnvs<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.iter.fmt(f)
+    }
+}
+
 /// The output of a finished process.
 ///
 /// This is returned in a Result by either the [`output`] method of a
diff --git a/library/std/src/sys/args/common.rs b/library/std/src/sys/args/common.rs
index 303b373ccf9..e787105a05a 100644
--- a/library/std/src/sys/args/common.rs
+++ b/library/std/src/sys/args/common.rs
@@ -49,8 +49,8 @@ impl Iterator for Args {
     }
 
     #[inline]
-    fn last(mut self) -> Option<OsString> {
-        self.iter.next_back()
+    fn last(self) -> Option<OsString> {
+        self.iter.last()
     }
 
     #[inline]
diff --git a/library/std/src/sys/fs/hermit.rs b/library/std/src/sys/fs/hermit.rs
index 99690abe8ed..a9774bef9e3 100644
--- a/library/std/src/sys/fs/hermit.rs
+++ b/library/std/src/sys/fs/hermit.rs
@@ -1,4 +1,5 @@
 use crate::ffi::{CStr, OsStr, OsString, c_char};
+use crate::fs::TryLockError;
 use crate::io::{self, BorrowedCursor, Error, ErrorKind, IoSlice, IoSliceMut, SeekFrom};
 use crate::os::hermit::ffi::OsStringExt;
 use crate::os::hermit::hermit_abi::{
@@ -12,7 +13,7 @@ use crate::sys::common::small_c_string::run_path_with_cstr;
 use crate::sys::fd::FileDesc;
 pub use crate::sys::fs::common::{copy, exists};
 use crate::sys::time::SystemTime;
-use crate::sys::{cvt, unsupported};
+use crate::sys::{cvt, unsupported, unsupported_err};
 use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 use crate::{fmt, mem};
 
@@ -366,12 +367,12 @@ impl File {
         unsupported()
     }
 
-    pub fn try_lock(&self) -> io::Result<bool> {
-        unsupported()
+    pub fn try_lock(&self) -> Result<(), TryLockError> {
+        Err(TryLockError::Error(unsupported_err()))
     }
 
-    pub fn try_lock_shared(&self) -> io::Result<bool> {
-        unsupported()
+    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
+        Err(TryLockError::Error(unsupported_err()))
     }
 
     pub fn unlock(&self) -> io::Result<()> {
diff --git a/library/std/src/sys/fs/solid.rs b/library/std/src/sys/fs/solid.rs
index 39de933b724..3bfb39bac95 100644
--- a/library/std/src/sys/fs/solid.rs
+++ b/library/std/src/sys/fs/solid.rs
@@ -2,6 +2,7 @@
 
 use crate::ffi::{CStr, CString, OsStr, OsString};
 use crate::fmt;
+use crate::fs::TryLockError;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
 use crate::mem::MaybeUninit;
 use crate::os::raw::{c_int, c_short};
@@ -11,7 +12,7 @@ use crate::sync::Arc;
 pub use crate::sys::fs::common::exists;
 use crate::sys::pal::{abi, error};
 use crate::sys::time::SystemTime;
-use crate::sys::unsupported;
+use crate::sys::{unsupported, unsupported_err};
 use crate::sys_common::ignore_notfound;
 
 type CIntNotMinusOne = core::num::niche_types::NotAllOnes<c_int>;
@@ -352,12 +353,12 @@ impl File {
         unsupported()
     }
 
-    pub fn try_lock(&self) -> io::Result<bool> {
-        unsupported()
+    pub fn try_lock(&self) -> Result<(), TryLockError> {
+        Err(TryLockError::Error(unsupported_err()))
     }
 
-    pub fn try_lock_shared(&self) -> io::Result<bool> {
-        unsupported()
+    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
+        Err(TryLockError::Error(unsupported_err()))
     }
 
     pub fn unlock(&self) -> io::Result<()> {
diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs
index d6ae86bd3d2..416c90b98b6 100644
--- a/library/std/src/sys/fs/uefi.rs
+++ b/library/std/src/sys/fs/uefi.rs
@@ -2,6 +2,7 @@ use r_efi::protocols::file;
 
 use crate::ffi::OsString;
 use crate::fmt;
+use crate::fs::TryLockError;
 use crate::hash::Hash;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
 use crate::path::{Path, PathBuf};
@@ -227,11 +228,11 @@ impl File {
         self.0
     }
 
-    pub fn try_lock(&self) -> io::Result<bool> {
+    pub fn try_lock(&self) -> Result<(), TryLockError> {
         self.0
     }
 
-    pub fn try_lock_shared(&self) -> io::Result<bool> {
+    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
         self.0
     }
 
diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs
index 5af59a2a914..863358596c1 100644
--- a/library/std/src/sys/fs/unix.rs
+++ b/library/std/src/sys/fs/unix.rs
@@ -75,6 +75,7 @@ use libc::{dirent64, fstat64, ftruncate64, lseek64, lstat64, off64_t, open64, st
 
 use crate::ffi::{CStr, OsStr, OsString};
 use crate::fmt::{self, Write as _};
+use crate::fs::TryLockError;
 use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom};
 use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd};
 use crate::os::unix::prelude::*;
@@ -1310,15 +1311,17 @@ impl File {
         target_os = "netbsd",
         target_vendor = "apple",
     ))]
-    pub fn try_lock(&self) -> io::Result<bool> {
+    pub fn try_lock(&self) -> Result<(), TryLockError> {
         let result = cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_EX | libc::LOCK_NB) });
-        if let Err(ref err) = result {
+        if let Err(err) = result {
             if err.kind() == io::ErrorKind::WouldBlock {
-                return Ok(false);
+                Err(TryLockError::WouldBlock)
+            } else {
+                Err(TryLockError::Error(err))
             }
+        } else {
+            Ok(())
         }
-        result?;
-        return Ok(true);
     }
 
     #[cfg(not(any(
@@ -1328,8 +1331,11 @@ impl File {
         target_os = "netbsd",
         target_vendor = "apple",
     )))]
-    pub fn try_lock(&self) -> io::Result<bool> {
-        Err(io::const_error!(io::ErrorKind::Unsupported, "try_lock() not supported"))
+    pub fn try_lock(&self) -> Result<(), TryLockError> {
+        Err(TryLockError::Error(io::const_error!(
+            io::ErrorKind::Unsupported,
+            "try_lock() not supported"
+        )))
     }
 
     #[cfg(any(
@@ -1339,15 +1345,17 @@ impl File {
         target_os = "netbsd",
         target_vendor = "apple",
     ))]
-    pub fn try_lock_shared(&self) -> io::Result<bool> {
+    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
         let result = cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_SH | libc::LOCK_NB) });
-        if let Err(ref err) = result {
+        if let Err(err) = result {
             if err.kind() == io::ErrorKind::WouldBlock {
-                return Ok(false);
+                Err(TryLockError::WouldBlock)
+            } else {
+                Err(TryLockError::Error(err))
             }
+        } else {
+            Ok(())
         }
-        result?;
-        return Ok(true);
     }
 
     #[cfg(not(any(
@@ -1357,8 +1365,11 @@ impl File {
         target_os = "netbsd",
         target_vendor = "apple",
     )))]
-    pub fn try_lock_shared(&self) -> io::Result<bool> {
-        Err(io::const_error!(io::ErrorKind::Unsupported, "try_lock_shared() not supported"))
+    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
+        Err(TryLockError::Error(io::const_error!(
+            io::ErrorKind::Unsupported,
+            "try_lock_shared() not supported"
+        )))
     }
 
     #[cfg(any(
diff --git a/library/std/src/sys/fs/unsupported.rs b/library/std/src/sys/fs/unsupported.rs
index 45e93deffa3..0ff9533c047 100644
--- a/library/std/src/sys/fs/unsupported.rs
+++ b/library/std/src/sys/fs/unsupported.rs
@@ -1,5 +1,6 @@
 use crate::ffi::OsString;
 use crate::fmt;
+use crate::fs::TryLockError;
 use crate::hash::{Hash, Hasher};
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
 use crate::path::{Path, PathBuf};
@@ -206,11 +207,11 @@ impl File {
         self.0
     }
 
-    pub fn try_lock(&self) -> io::Result<bool> {
+    pub fn try_lock(&self) -> Result<(), TryLockError> {
         self.0
     }
 
-    pub fn try_lock_shared(&self) -> io::Result<bool> {
+    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
         self.0
     }
 
diff --git a/library/std/src/sys/fs/wasi.rs b/library/std/src/sys/fs/wasi.rs
index 773040571bc..ebfc7377a2e 100644
--- a/library/std/src/sys/fs/wasi.rs
+++ b/library/std/src/sys/fs/wasi.rs
@@ -1,4 +1,5 @@
 use crate::ffi::{CStr, OsStr, OsString};
+use crate::fs::TryLockError;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
 use crate::mem::{self, ManuallyDrop};
 use crate::os::raw::c_int;
@@ -10,7 +11,7 @@ use crate::sys::common::small_c_string::run_path_with_cstr;
 use crate::sys::fd::WasiFd;
 pub use crate::sys::fs::common::exists;
 use crate::sys::time::SystemTime;
-use crate::sys::unsupported;
+use crate::sys::{unsupported, unsupported_err};
 use crate::sys_common::{AsInner, FromInner, IntoInner, ignore_notfound};
 use crate::{fmt, iter, ptr};
 
@@ -461,12 +462,12 @@ impl File {
         unsupported()
     }
 
-    pub fn try_lock(&self) -> io::Result<bool> {
-        unsupported()
+    pub fn try_lock(&self) -> Result<(), TryLockError> {
+        Err(TryLockError::Error(unsupported_err()))
     }
 
-    pub fn try_lock_shared(&self) -> io::Result<bool> {
-        unsupported()
+    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
+        Err(TryLockError::Error(unsupported_err()))
     }
 
     pub fn unlock(&self) -> io::Result<()> {
diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs
index 9215f937567..9039fd00f5d 100644
--- a/library/std/src/sys/fs/windows.rs
+++ b/library/std/src/sys/fs/windows.rs
@@ -3,6 +3,7 @@
 use crate::alloc::{Layout, alloc, dealloc};
 use crate::borrow::Cow;
 use crate::ffi::{OsStr, OsString, c_void};
+use crate::fs::TryLockError;
 use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom};
 use crate::mem::{self, MaybeUninit, offset_of};
 use crate::os::windows::io::{AsHandle, BorrowedHandle};
@@ -399,7 +400,7 @@ impl File {
         self.acquire_lock(0)
     }
 
-    pub fn try_lock(&self) -> io::Result<bool> {
+    pub fn try_lock(&self) -> Result<(), TryLockError> {
         let result = cvt(unsafe {
             let mut overlapped = mem::zeroed();
             c::LockFileEx(
@@ -413,18 +414,18 @@ impl File {
         });
 
         match result {
-            Ok(_) => Ok(true),
+            Ok(_) => Ok(()),
             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(TryLockError::WouldBlock)
             }
-            Err(err) => Err(err),
+            Err(err) => Err(TryLockError::Error(err)),
         }
     }
 
-    pub fn try_lock_shared(&self) -> io::Result<bool> {
+    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
         let result = cvt(unsafe {
             let mut overlapped = mem::zeroed();
             c::LockFileEx(
@@ -438,14 +439,14 @@ impl File {
         });
 
         match result {
-            Ok(_) => Ok(true),
+            Ok(_) => Ok(()),
             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(TryLockError::WouldBlock)
             }
-            Err(err) => Err(err),
+            Err(err) => Err(TryLockError::Error(err)),
         }
     }
 
diff --git a/library/std/src/sys/pal/unix/fuchsia.rs b/library/std/src/sys/pal/unix/fuchsia.rs
index 7932bd26d76..c118dee6247 100644
--- a/library/std/src/sys/pal/unix/fuchsia.rs
+++ b/library/std/src/sys/pal/unix/fuchsia.rs
@@ -1,48 +1,35 @@
-#![allow(non_camel_case_types, unused)]
+#![expect(non_camel_case_types)]
 
-use libc::{c_int, c_void, size_t};
+use libc::size_t;
 
+use crate::ffi::{c_char, c_int, c_void};
 use crate::io;
-use crate::mem::MaybeUninit;
-use crate::os::raw::c_char;
 
-pub type zx_handle_t = u32;
-pub type zx_vaddr_t = usize;
-pub type zx_rights_t = u32;
-pub type zx_status_t = i32;
-
-pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
+//////////
+// Time //
+//////////
 
 pub type zx_time_t = i64;
-pub const ZX_TIME_INFINITE: zx_time_t = i64::MAX;
-
-pub type zx_signals_t = u32;
-
-pub const ZX_OBJECT_SIGNAL_3: zx_signals_t = 1 << 3;
 
-pub const ZX_TASK_TERMINATED: zx_signals_t = ZX_OBJECT_SIGNAL_3;
+pub const ZX_TIME_INFINITE: zx_time_t = i64::MAX;
 
-pub const ZX_RIGHT_SAME_RIGHTS: zx_rights_t = 1 << 31;
+unsafe extern "C" {
+    pub safe fn zx_clock_get_monotonic() -> zx_time_t;
+}
 
-// The upper four bits gives the minor version.
-pub type zx_object_info_topic_t = u32;
+/////////////
+// Handles //
+/////////////
 
-pub const ZX_INFO_PROCESS: zx_object_info_topic_t = 3 | (1 << 28);
+pub type zx_handle_t = u32;
 
-pub type zx_info_process_flags_t = u32;
+pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
 
-pub fn zx_cvt<T>(t: T) -> io::Result<T>
-where
-    T: TryInto<zx_status_t> + Copy,
-{
-    if let Ok(status) = TryInto::try_into(t) {
-        if status < 0 { Err(io::Error::from_raw_os_error(status)) } else { Ok(t) }
-    } else {
-        Err(io::Error::last_os_error())
-    }
+unsafe extern "C" {
+    pub fn zx_handle_close(handle: zx_handle_t) -> zx_status_t;
 }
 
-// Safe wrapper around zx_handle_t
+/// A safe wrapper around `zx_handle_t`.
 pub struct Handle {
     raw: zx_handle_t,
 }
@@ -65,6 +52,66 @@ impl Drop for Handle {
     }
 }
 
+///////////
+// Futex //
+///////////
+
+pub type zx_futex_t = crate::sync::atomic::Atomic<u32>;
+
+unsafe extern "C" {
+    pub fn zx_object_wait_one(
+        handle: zx_handle_t,
+        signals: zx_signals_t,
+        timeout: zx_time_t,
+        pending: *mut zx_signals_t,
+    ) -> zx_status_t;
+
+    pub fn zx_futex_wait(
+        value_ptr: *const zx_futex_t,
+        current_value: zx_futex_t,
+        new_futex_owner: zx_handle_t,
+        deadline: zx_time_t,
+    ) -> zx_status_t;
+    pub fn zx_futex_wake(value_ptr: *const zx_futex_t, wake_count: u32) -> zx_status_t;
+    pub fn zx_futex_wake_single_owner(value_ptr: *const zx_futex_t) -> zx_status_t;
+    pub safe fn zx_thread_self() -> zx_handle_t;
+}
+
+////////////////
+// Properties //
+////////////////
+
+pub const ZX_PROP_NAME: u32 = 3;
+
+unsafe extern "C" {
+    pub fn zx_object_set_property(
+        handle: zx_handle_t,
+        property: u32,
+        value: *const libc::c_void,
+        value_size: libc::size_t,
+    ) -> zx_status_t;
+}
+
+/////////////
+// Signals //
+/////////////
+
+pub type zx_signals_t = u32;
+
+pub const ZX_OBJECT_SIGNAL_3: zx_signals_t = 1 << 3;
+pub const ZX_TASK_TERMINATED: zx_signals_t = ZX_OBJECT_SIGNAL_3;
+
+/////////////////
+// Object info //
+/////////////////
+
+// The upper four bits gives the minor version.
+pub type zx_object_info_topic_t = u32;
+
+pub const ZX_INFO_PROCESS: zx_object_info_topic_t = 3 | (1 << 28);
+
+pub type zx_info_process_flags_t = u32;
+
 // Returned for topic ZX_INFO_PROCESS
 #[derive(Default)]
 #[repr(C)]
@@ -76,25 +123,6 @@ pub struct zx_info_process_t {
 }
 
 unsafe extern "C" {
-    pub fn zx_job_default() -> zx_handle_t;
-
-    pub fn zx_task_kill(handle: zx_handle_t) -> zx_status_t;
-
-    pub fn zx_handle_close(handle: zx_handle_t) -> zx_status_t;
-
-    pub fn zx_handle_duplicate(
-        handle: zx_handle_t,
-        rights: zx_rights_t,
-        out: *const zx_handle_t,
-    ) -> zx_handle_t;
-
-    pub fn zx_object_wait_one(
-        handle: zx_handle_t,
-        signals: zx_signals_t,
-        timeout: zx_time_t,
-        pending: *mut zx_signals_t,
-    ) -> zx_status_t;
-
     pub fn zx_object_get_info(
         handle: zx_handle_t,
         topic: u32,
@@ -105,6 +133,10 @@ unsafe extern "C" {
     ) -> zx_status_t;
 }
 
+///////////////
+// Processes //
+///////////////
+
 #[derive(Default)]
 #[repr(C)]
 pub struct fdio_spawn_action_t {
@@ -130,6 +162,8 @@ unsafe extern "C" {
 
     pub fn fdio_fd_clone(fd: c_int, out_handle: *mut zx_handle_t) -> zx_status_t;
     pub fn fdio_fd_create(handle: zx_handle_t, fd: *mut c_int) -> zx_status_t;
+
+    pub fn zx_task_kill(handle: zx_handle_t) -> zx_status_t;
 }
 
 // fdio_spawn_etc flags
@@ -137,173 +171,34 @@ unsafe extern "C" {
 pub const FDIO_SPAWN_CLONE_JOB: u32 = 0x0001;
 pub const FDIO_SPAWN_CLONE_LDSVC: u32 = 0x0002;
 pub const FDIO_SPAWN_CLONE_NAMESPACE: u32 = 0x0004;
-pub const FDIO_SPAWN_CLONE_STDIO: u32 = 0x0008;
 pub const FDIO_SPAWN_CLONE_ENVIRON: u32 = 0x0010;
 pub const FDIO_SPAWN_CLONE_UTC_CLOCK: u32 = 0x0020;
-pub const FDIO_SPAWN_CLONE_ALL: u32 = 0xFFFF;
 
 // fdio_spawn_etc actions
 
-pub const FDIO_SPAWN_ACTION_CLONE_FD: u32 = 0x0001;
 pub const FDIO_SPAWN_ACTION_TRANSFER_FD: u32 = 0x0002;
 
-// Errors
-
-#[allow(unused)]
-pub const ERR_INTERNAL: zx_status_t = -1;
-
-// ERR_NOT_SUPPORTED: The operation is not implemented, supported,
-// or enabled.
-#[allow(unused)]
-pub const ERR_NOT_SUPPORTED: zx_status_t = -2;
-
-// ERR_NO_RESOURCES: The system was not able to allocate some resource
-// needed for the operation.
-#[allow(unused)]
-pub const ERR_NO_RESOURCES: zx_status_t = -3;
-
-// ERR_NO_MEMORY: The system was not able to allocate memory needed
-// for the operation.
-#[allow(unused)]
-pub const ERR_NO_MEMORY: zx_status_t = -4;
-
-// ERR_CALL_FAILED: The second phase of zx_channel_call(; did not complete
-// successfully.
-#[allow(unused)]
-pub const ERR_CALL_FAILED: zx_status_t = -5;
-
-// ERR_INTERRUPTED_RETRY: The system call was interrupted, but should be
-// retried.  This should not be seen outside of the VDSO.
-#[allow(unused)]
-pub const ERR_INTERRUPTED_RETRY: zx_status_t = -6;
-
-// ======= Parameter errors =======
-// ERR_INVALID_ARGS: an argument is invalid, ex. null pointer
-#[allow(unused)]
-pub const ERR_INVALID_ARGS: zx_status_t = -10;
-
-// ERR_BAD_HANDLE: A specified handle value does not refer to a handle.
-#[allow(unused)]
-pub const ERR_BAD_HANDLE: zx_status_t = -11;
-
-// ERR_WRONG_TYPE: The subject of the operation is the wrong type to
-// perform the operation.
-// Example: Attempting a message_read on a thread handle.
-#[allow(unused)]
-pub const ERR_WRONG_TYPE: zx_status_t = -12;
-
-// ERR_BAD_SYSCALL: The specified syscall number is invalid.
-#[allow(unused)]
-pub const ERR_BAD_SYSCALL: zx_status_t = -13;
-
-// ERR_OUT_OF_RANGE: An argument is outside the valid range for this
-// operation.
-#[allow(unused)]
-pub const ERR_OUT_OF_RANGE: zx_status_t = -14;
-
-// ERR_BUFFER_TOO_SMALL: A caller provided buffer is too small for
-// this operation.
-#[allow(unused)]
-pub const ERR_BUFFER_TOO_SMALL: zx_status_t = -15;
-
-// ======= Precondition or state errors =======
-// ERR_BAD_STATE: operation failed because the current state of the
-// object does not allow it, or a precondition of the operation is
-// not satisfied
-#[allow(unused)]
-pub const ERR_BAD_STATE: zx_status_t = -20;
-
-// ERR_TIMED_OUT: The time limit for the operation elapsed before
-// the operation completed.
-#[allow(unused)]
-pub const ERR_TIMED_OUT: zx_status_t = -21;
-
-// ERR_SHOULD_WAIT: The operation cannot be performed currently but
-// potentially could succeed if the caller waits for a prerequisite
-// to be satisfied, for example waiting for a handle to be readable
-// or writable.
-// Example: Attempting to read from a message pipe that has no
-// messages waiting but has an open remote will return ERR_SHOULD_WAIT.
-// Attempting to read from a message pipe that has no messages waiting
-// and has a closed remote end will return ERR_REMOTE_CLOSED.
-#[allow(unused)]
-pub const ERR_SHOULD_WAIT: zx_status_t = -22;
-
-// ERR_CANCELED: The in-progress operation (e.g., a wait) has been
-// // canceled.
-#[allow(unused)]
-pub const ERR_CANCELED: zx_status_t = -23;
-
-// ERR_PEER_CLOSED: The operation failed because the remote end
-// of the subject of the operation was closed.
-#[allow(unused)]
-pub const ERR_PEER_CLOSED: zx_status_t = -24;
-
-// ERR_NOT_FOUND: The requested entity is not found.
-#[allow(unused)]
-pub const ERR_NOT_FOUND: zx_status_t = -25;
-
-// ERR_ALREADY_EXISTS: An object with the specified identifier
-// already exists.
-// Example: Attempting to create a file when a file already exists
-// with that name.
-#[allow(unused)]
-pub const ERR_ALREADY_EXISTS: zx_status_t = -26;
-
-// ERR_ALREADY_BOUND: The operation failed because the named entity
-// is already owned or controlled by another entity. The operation
-// could succeed later if the current owner releases the entity.
-#[allow(unused)]
-pub const ERR_ALREADY_BOUND: zx_status_t = -27;
-
-// ERR_UNAVAILABLE: The subject of the operation is currently unable
-// to perform the operation.
-// Note: This is used when there's no direct way for the caller to
-// observe when the subject will be able to perform the operation
-// and should thus retry.
-#[allow(unused)]
-pub const ERR_UNAVAILABLE: zx_status_t = -28;
-
-// ======= Permission check errors =======
-// ERR_ACCESS_DENIED: The caller did not have permission to perform
-// the specified operation.
-#[allow(unused)]
-pub const ERR_ACCESS_DENIED: zx_status_t = -30;
-
-// ======= Input-output errors =======
-// ERR_IO: Otherwise unspecified error occurred during I/O.
-#[allow(unused)]
-pub const ERR_IO: zx_status_t = -40;
-
-// ERR_REFUSED: The entity the I/O operation is being performed on
-// rejected the operation.
-// Example: an I2C device NAK'ing a transaction or a disk controller
-// rejecting an invalid command.
-#[allow(unused)]
-pub const ERR_IO_REFUSED: zx_status_t = -41;
-
-// ERR_IO_DATA_INTEGRITY: The data in the operation failed an integrity
-// check and is possibly corrupted.
-// Example: CRC or Parity error.
-#[allow(unused)]
-pub const ERR_IO_DATA_INTEGRITY: zx_status_t = -42;
-
-// ERR_IO_DATA_LOSS: The data in the operation is currently unavailable
-// and may be permanently lost.
-// Example: A disk block is irrecoverably damaged.
-#[allow(unused)]
-pub const ERR_IO_DATA_LOSS: zx_status_t = -43;
-
-// Filesystem specific errors
-#[allow(unused)]
-pub const ERR_BAD_PATH: zx_status_t = -50;
-#[allow(unused)]
-pub const ERR_NOT_DIR: zx_status_t = -51;
-#[allow(unused)]
-pub const ERR_NOT_FILE: zx_status_t = -52;
-// ERR_FILE_BIG: A file exceeds a filesystem-specific size limit.
-#[allow(unused)]
-pub const ERR_FILE_BIG: zx_status_t = -53;
-// ERR_NO_SPACE: Filesystem or device space is exhausted.
-#[allow(unused)]
-pub const ERR_NO_SPACE: zx_status_t = -54;
+////////////
+// Errors //
+////////////
+
+pub type zx_status_t = i32;
+
+pub const ZX_OK: zx_status_t = 0;
+pub const ZX_ERR_NOT_SUPPORTED: zx_status_t = -2;
+pub const ZX_ERR_INVALID_ARGS: zx_status_t = -10;
+pub const ZX_ERR_BAD_HANDLE: zx_status_t = -11;
+pub const ZX_ERR_WRONG_TYPE: zx_status_t = -12;
+pub const ZX_ERR_BAD_STATE: zx_status_t = -20;
+pub const ZX_ERR_TIMED_OUT: zx_status_t = -21;
+
+pub fn zx_cvt<T>(t: T) -> io::Result<T>
+where
+    T: TryInto<zx_status_t> + Copy,
+{
+    if let Ok(status) = TryInto::try_into(t) {
+        if status < 0 { Err(io::Error::from_raw_os_error(status)) } else { Ok(t) }
+    } else {
+        Err(io::Error::last_os_error())
+    }
+}
diff --git a/library/std/src/sys/pal/unix/futex.rs b/library/std/src/sys/pal/unix/futex.rs
index 8d89163c42c..c23278bdf5e 100644
--- a/library/std/src/sys/pal/unix/futex.rs
+++ b/library/std/src/sys/pal/unix/futex.rs
@@ -255,66 +255,28 @@ pub fn futex_wake_all(futex: &Atomic<u32>) {
 }
 
 #[cfg(target_os = "fuchsia")]
-pub mod zircon {
-    pub type zx_futex_t = crate::sync::atomic::Atomic<u32>;
-    pub type zx_handle_t = u32;
-    pub type zx_status_t = i32;
-    pub type zx_time_t = i64;
-
-    pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
-
-    pub const ZX_TIME_INFINITE: zx_time_t = zx_time_t::MAX;
-
-    pub const ZX_OK: zx_status_t = 0;
-    pub const ZX_ERR_INVALID_ARGS: zx_status_t = -10;
-    pub const ZX_ERR_BAD_HANDLE: zx_status_t = -11;
-    pub const ZX_ERR_WRONG_TYPE: zx_status_t = -12;
-    pub const ZX_ERR_BAD_STATE: zx_status_t = -20;
-    pub const ZX_ERR_TIMED_OUT: zx_status_t = -21;
-
-    unsafe extern "C" {
-        pub fn zx_clock_get_monotonic() -> zx_time_t;
-        pub fn zx_futex_wait(
-            value_ptr: *const zx_futex_t,
-            current_value: zx_futex_t,
-            new_futex_owner: zx_handle_t,
-            deadline: zx_time_t,
-        ) -> zx_status_t;
-        pub fn zx_futex_wake(value_ptr: *const zx_futex_t, wake_count: u32) -> zx_status_t;
-        pub fn zx_futex_wake_single_owner(value_ptr: *const zx_futex_t) -> zx_status_t;
-        pub fn zx_thread_self() -> zx_handle_t;
-    }
-}
-
-#[cfg(target_os = "fuchsia")]
 pub fn futex_wait(futex: &Atomic<u32>, expected: u32, timeout: Option<Duration>) -> bool {
+    use super::fuchsia::*;
+
     // Sleep forever if the timeout is longer than fits in a i64.
     let deadline = timeout
-        .and_then(|d| {
-            i64::try_from(d.as_nanos())
-                .ok()?
-                .checked_add(unsafe { zircon::zx_clock_get_monotonic() })
-        })
-        .unwrap_or(zircon::ZX_TIME_INFINITE);
+        .and_then(|d| i64::try_from(d.as_nanos()).ok()?.checked_add(zx_clock_get_monotonic()))
+        .unwrap_or(ZX_TIME_INFINITE);
 
     unsafe {
-        zircon::zx_futex_wait(
-            futex,
-            core::sync::atomic::AtomicU32::new(expected),
-            zircon::ZX_HANDLE_INVALID,
-            deadline,
-        ) != zircon::ZX_ERR_TIMED_OUT
+        zx_futex_wait(futex, zx_futex_t::new(expected), ZX_HANDLE_INVALID, deadline)
+            != ZX_ERR_TIMED_OUT
     }
 }
 
 // Fuchsia doesn't tell us how many threads are woken up, so this always returns false.
 #[cfg(target_os = "fuchsia")]
 pub fn futex_wake(futex: &Atomic<u32>) -> bool {
-    unsafe { zircon::zx_futex_wake(futex, 1) };
+    unsafe { super::fuchsia::zx_futex_wake(futex, 1) };
     false
 }
 
 #[cfg(target_os = "fuchsia")]
 pub fn futex_wake_all(futex: &Atomic<u32>) {
-    unsafe { zircon::zx_futex_wake(futex, u32::MAX) };
+    unsafe { super::fuchsia::zx_futex_wake(futex, u32::MAX) };
 }
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 4cdc2eaf0e5..afda7c65e10 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -22,23 +22,6 @@ pub const DEFAULT_MIN_STACK_SIZE: usize = 256 * 1024;
 #[cfg(any(target_os = "espidf", target_os = "nuttx"))]
 pub const DEFAULT_MIN_STACK_SIZE: usize = 0; // 0 indicates that the stack size configured in the ESP-IDF/NuttX menuconfig system should be used
 
-#[cfg(target_os = "fuchsia")]
-mod zircon {
-    type zx_handle_t = u32;
-    type zx_status_t = i32;
-    pub const ZX_PROP_NAME: u32 = 3;
-
-    unsafe extern "C" {
-        pub fn zx_object_set_property(
-            handle: zx_handle_t,
-            property: u32,
-            value: *const libc::c_void,
-            value_size: libc::size_t,
-        ) -> zx_status_t;
-        pub fn zx_thread_self() -> zx_handle_t;
-    }
-}
-
 pub struct Thread {
     id: libc::pthread_t,
 }
@@ -216,7 +199,7 @@ impl Thread {
 
     #[cfg(target_os = "fuchsia")]
     pub fn set_name(name: &CStr) {
-        use self::zircon::*;
+        use super::fuchsia::*;
         unsafe {
             zx_object_set_property(
                 zx_thread_self(),
diff --git a/library/std/src/sys_common/process.rs b/library/std/src/sys/process/env.rs
index 9f61d69d858..e08b476540e 100644
--- a/library/std/src/sys_common/process.rs
+++ b/library/std/src/sys/process/env.rs
@@ -1,13 +1,9 @@
-#![allow(dead_code)]
-#![unstable(feature = "process_internals", issue = "none")]
-
 use crate::collections::BTreeMap;
 use crate::ffi::{OsStr, OsString};
-use crate::sys::pipe::read2;
-use crate::sys::process::{EnvKey, ExitStatus, Process, StdioPipes};
-use crate::{env, fmt, io};
+use crate::sys::process::EnvKey;
+use crate::{env, fmt};
 
-// Stores a set of changes to an environment
+/// Stores a set of changes to an environment
 #[derive(Clone, Default)]
 pub struct CommandEnv {
     clear: bool,
@@ -92,30 +88,23 @@ impl CommandEnv {
     }
 }
 
-/// An iterator over the command environment variables.
-///
-/// This struct is created by
-/// [`Command::get_envs`][crate::process::Command::get_envs]. See its
-/// documentation for more.
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[stable(feature = "command_access", since = "1.57.0")]
 #[derive(Debug)]
 pub struct CommandEnvs<'a> {
     iter: crate::collections::btree_map::Iter<'a, EnvKey, Option<OsString>>,
 }
 
-#[stable(feature = "command_access", since = "1.57.0")]
 impl<'a> Iterator for CommandEnvs<'a> {
     type Item = (&'a OsStr, Option<&'a OsStr>);
+
     fn next(&mut self) -> Option<Self::Item> {
         self.iter.next().map(|(key, value)| (key.as_ref(), value.as_deref()))
     }
+
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
 }
 
-#[stable(feature = "command_access", since = "1.57.0")]
 impl<'a> ExactSizeIterator for CommandEnvs<'a> {
     fn len(&self) -> usize {
         self.iter.len()
@@ -124,30 +113,3 @@ impl<'a> ExactSizeIterator for CommandEnvs<'a> {
         self.iter.is_empty()
     }
 }
-
-pub fn wait_with_output(
-    mut process: Process,
-    mut pipes: StdioPipes,
-) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
-    drop(pipes.stdin.take());
-
-    let (mut stdout, mut stderr) = (Vec::new(), Vec::new());
-    match (pipes.stdout.take(), pipes.stderr.take()) {
-        (None, None) => {}
-        (Some(out), None) => {
-            let res = out.read_to_end(&mut stdout);
-            res.unwrap();
-        }
-        (None, Some(err)) => {
-            let res = err.read_to_end(&mut stderr);
-            res.unwrap();
-        }
-        (Some(out), Some(err)) => {
-            let res = read2(out, &mut stdout, err, &mut stderr);
-            res.unwrap();
-        }
-    }
-
-    let status = process.wait()?;
-    Ok((status, stdout, stderr))
-}
diff --git a/library/std/src/sys/process/mod.rs b/library/std/src/sys/process/mod.rs
index 92cfac7f47c..91c7005a328 100644
--- a/library/std/src/sys/process/mod.rs
+++ b/library/std/src/sys/process/mod.rs
@@ -14,6 +14,65 @@ cfg_if::cfg_if! {
     }
 }
 
+// This module is shared by all platforms, but nearly all platforms except for
+// the "normal" UNIX ones leave some of this code unused.
+#[cfg_attr(not(target_os = "linux"), allow(dead_code))]
+mod env;
+
+pub use env::CommandEnvs;
 pub use imp::{
     Command, CommandArgs, EnvKey, ExitCode, ExitStatus, ExitStatusError, Process, Stdio, StdioPipes,
 };
+
+#[cfg(any(
+    all(
+        target_family = "unix",
+        not(any(
+            target_os = "espidf",
+            target_os = "horizon",
+            target_os = "vita",
+            target_os = "nuttx"
+        ))
+    ),
+    target_os = "windows",
+))]
+pub fn output(cmd: &mut Command) -> crate::io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
+    use crate::sys::pipe::read2;
+
+    let (mut process, mut pipes) = cmd.spawn(Stdio::MakePipe, false)?;
+
+    drop(pipes.stdin.take());
+    let (mut stdout, mut stderr) = (Vec::new(), Vec::new());
+    match (pipes.stdout.take(), pipes.stderr.take()) {
+        (None, None) => {}
+        (Some(out), None) => {
+            let res = out.read_to_end(&mut stdout);
+            res.unwrap();
+        }
+        (None, Some(err)) => {
+            let res = err.read_to_end(&mut stderr);
+            res.unwrap();
+        }
+        (Some(out), Some(err)) => {
+            let res = read2(out, &mut stdout, err, &mut stderr);
+            res.unwrap();
+        }
+    }
+
+    let status = process.wait()?;
+    Ok((status, stdout, stderr))
+}
+
+#[cfg(not(any(
+    all(
+        target_family = "unix",
+        not(any(
+            target_os = "espidf",
+            target_os = "horizon",
+            target_os = "vita",
+            target_os = "nuttx"
+        ))
+    ),
+    target_os = "windows",
+)))]
+pub use imp::output;
diff --git a/library/std/src/sys/process/uefi.rs b/library/std/src/sys/process/uefi.rs
index 5f922292d05..4864c586988 100644
--- a/library/std/src/sys/process/uefi.rs
+++ b/library/std/src/sys/process/uefi.rs
@@ -1,5 +1,6 @@
 use r_efi::protocols::{simple_text_input, simple_text_output};
 
+use super::env::{CommandEnv, CommandEnvs};
 use crate::collections::BTreeMap;
 pub use crate::ffi::OsString as EnvKey;
 use crate::ffi::{OsStr, OsString};
@@ -10,7 +11,6 @@ use crate::sys::pal::helpers;
 use crate::sys::pal::os::error_string;
 use crate::sys::pipe::AnonPipe;
 use crate::sys::unsupported;
-use crate::sys_common::process::{CommandEnv, CommandEnvs};
 use crate::{fmt, io};
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -139,72 +139,72 @@ impl Command {
             Stdio::MakePipe => unsupported(),
         }
     }
+}
 
-    pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
-        let mut cmd = uefi_command_internal::Image::load_image(&self.prog)?;
-
-        // UEFI adds the bin name by default
-        if !self.args.is_empty() {
-            let args = uefi_command_internal::create_args(&self.prog, &self.args);
-            cmd.set_args(args);
-        }
-
-        // Setup Stdout
-        let stdout = self.stdout.unwrap_or(Stdio::MakePipe);
-        let stdout = Self::create_pipe(stdout)?;
-        if let Some(con) = stdout {
-            cmd.stdout_init(con)
-        } else {
-            cmd.stdout_inherit()
-        };
-
-        // Setup Stderr
-        let stderr = self.stderr.unwrap_or(Stdio::MakePipe);
-        let stderr = Self::create_pipe(stderr)?;
-        if let Some(con) = stderr {
-            cmd.stderr_init(con)
-        } else {
-            cmd.stderr_inherit()
-        };
-
-        // Setup Stdin
-        let stdin = self.stdin.unwrap_or(Stdio::Null);
-        let stdin = Self::create_stdin(stdin)?;
-        if let Some(con) = stdin {
-            cmd.stdin_init(con)
-        } else {
-            cmd.stdin_inherit()
-        };
-
-        let env = env_changes(&self.env);
-
-        // Set any new vars
-        if let Some(e) = &env {
-            for (k, (_, v)) in e {
-                match v {
-                    Some(v) => unsafe { crate::env::set_var(k, v) },
-                    None => unsafe { crate::env::remove_var(k) },
-                }
+pub fn output(command: &mut Command) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
+    let mut cmd = uefi_command_internal::Image::load_image(&command.prog)?;
+
+    // UEFI adds the bin name by default
+    if !command.args.is_empty() {
+        let args = uefi_command_internal::create_args(&command.prog, &command.args);
+        cmd.set_args(args);
+    }
+
+    // Setup Stdout
+    let stdout = command.stdout.unwrap_or(Stdio::MakePipe);
+    let stdout = Command::create_pipe(stdout)?;
+    if let Some(con) = stdout {
+        cmd.stdout_init(con)
+    } else {
+        cmd.stdout_inherit()
+    };
+
+    // Setup Stderr
+    let stderr = command.stderr.unwrap_or(Stdio::MakePipe);
+    let stderr = Command::create_pipe(stderr)?;
+    if let Some(con) = stderr {
+        cmd.stderr_init(con)
+    } else {
+        cmd.stderr_inherit()
+    };
+
+    // Setup Stdin
+    let stdin = command.stdin.unwrap_or(Stdio::Null);
+    let stdin = Command::create_stdin(stdin)?;
+    if let Some(con) = stdin {
+        cmd.stdin_init(con)
+    } else {
+        cmd.stdin_inherit()
+    };
+
+    let env = env_changes(&command.env);
+
+    // Set any new vars
+    if let Some(e) = &env {
+        for (k, (_, v)) in e {
+            match v {
+                Some(v) => unsafe { crate::env::set_var(k, v) },
+                None => unsafe { crate::env::remove_var(k) },
             }
         }
+    }
 
-        let stat = cmd.start_image()?;
+    let stat = cmd.start_image()?;
 
-        // Rollback any env changes
-        if let Some(e) = env {
-            for (k, (v, _)) in e {
-                match v {
-                    Some(v) => unsafe { crate::env::set_var(k, v) },
-                    None => unsafe { crate::env::remove_var(k) },
-                }
+    // Rollback any env changes
+    if let Some(e) = env {
+        for (k, (v, _)) in e {
+            match v {
+                Some(v) => unsafe { crate::env::set_var(k, v) },
+                None => unsafe { crate::env::remove_var(k) },
             }
         }
+    }
 
-        let stdout = cmd.stdout()?;
-        let stderr = cmd.stderr()?;
+    let stdout = cmd.stdout()?;
+    let stderr = cmd.stderr()?;
 
-        Ok((ExitStatus(stat), stdout, stderr))
-    }
+    Ok((ExitStatus(stat), stdout, stderr))
 }
 
 impl From<AnonPipe> for Stdio {
diff --git a/library/std/src/sys/process/unix/common.rs b/library/std/src/sys/process/unix/common.rs
index 8bc17f31491..a9c2510e6d4 100644
--- a/library/std/src/sys/process/unix/common.rs
+++ b/library/std/src/sys/process/unix/common.rs
@@ -12,7 +12,7 @@ use crate::sys::fs::File;
 #[cfg(not(target_os = "fuchsia"))]
 use crate::sys::fs::OpenOptions;
 use crate::sys::pipe::{self, AnonPipe};
-use crate::sys_common::process::{CommandEnv, CommandEnvs};
+use crate::sys::process::env::{CommandEnv, CommandEnvs};
 use crate::sys_common::{FromInner, IntoInner};
 use crate::{fmt, io, ptr};
 
diff --git a/library/std/src/sys/process/unix/fuchsia.rs b/library/std/src/sys/process/unix/fuchsia.rs
index 0de32ecffd4..017ab91797c 100644
--- a/library/std/src/sys/process/unix/fuchsia.rs
+++ b/library/std/src/sys/process/unix/fuchsia.rs
@@ -31,11 +31,6 @@ impl Command {
         Ok((Process { handle: Handle::new(process_handle) }, ours))
     }
 
-    pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
-        let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?;
-        crate::sys_common::process::wait_with_output(proc, pipes)
-    }
-
     pub fn exec(&mut self, default: Stdio) -> io::Error {
         if self.saw_nul() {
             return io::const_error!(
@@ -81,7 +76,7 @@ impl Command {
 
                 let mut handle = ZX_HANDLE_INVALID;
                 let status = fdio_fd_clone(target_fd, &mut handle);
-                if status == ERR_INVALID_ARGS || status == ERR_NOT_SUPPORTED {
+                if status == ZX_ERR_INVALID_ARGS || status == ZX_ERR_NOT_SUPPORTED {
                     // This descriptor is closed; skip it rather than generating an
                     // error.
                     return Ok(Default::default());
@@ -197,7 +192,7 @@ impl Process {
                 zx_object_wait_one(self.handle.raw(), ZX_TASK_TERMINATED, 0, ptr::null_mut());
             match status {
                 0 => {} // Success
-                x if x == ERR_TIMED_OUT => {
+                x if x == ZX_ERR_TIMED_OUT => {
                     return Ok(None);
                 }
                 _ => {
diff --git a/library/std/src/sys/process/unix/mod.rs b/library/std/src/sys/process/unix/mod.rs
index 2e8b38f7de1..ee8fd8b2ca3 100644
--- a/library/std/src/sys/process/unix/mod.rs
+++ b/library/std/src/sys/process/unix/mod.rs
@@ -11,6 +11,7 @@ cfg_if::cfg_if! {
     } else if #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))] {
         mod unsupported;
         use unsupported as imp;
+        pub use unsupported::output;
     } else {
         mod unix;
         use unix as imp;
diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs
index ae1c9558281..1b3bd2de265 100644
--- a/library/std/src/sys/process/unix/unix.rs
+++ b/library/std/src/sys/process/unix/unix.rs
@@ -162,11 +162,6 @@ impl Command {
         }
     }
 
-    pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
-        let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?;
-        crate::sys_common::process::wait_with_output(proc, pipes)
-    }
-
     // WatchOS and TVOS headers mark the `fork`/`exec*` functions with
     // `__WATCHOS_PROHIBITED __TVOS_PROHIBITED`, and indicate that the
     // `posix_spawn*` functions should be used instead. It isn't entirely clear
diff --git a/library/std/src/sys/process/unix/unsupported.rs b/library/std/src/sys/process/unix/unsupported.rs
index 78d270923cf..e86561a5c5c 100644
--- a/library/std/src/sys/process/unix/unsupported.rs
+++ b/library/std/src/sys/process/unix/unsupported.rs
@@ -18,15 +18,15 @@ impl Command {
         unsupported()
     }
 
-    pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
-        unsupported()
-    }
-
     pub fn exec(&mut self, _default: Stdio) -> io::Error {
         unsupported_err()
     }
 }
 
+pub fn output(_: &mut Command) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
+    unsupported()
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Processes
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/library/std/src/sys/process/unix/vxworks.rs b/library/std/src/sys/process/unix/vxworks.rs
index b92446f0cf6..fab3b36ebf3 100644
--- a/library/std/src/sys/process/unix/vxworks.rs
+++ b/library/std/src/sys/process/unix/vxworks.rs
@@ -112,11 +112,6 @@ impl Command {
         }
     }
 
-    pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
-        let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?;
-        crate::sys_common::process::wait_with_output(proc, pipes)
-    }
-
     pub fn exec(&mut self, default: Stdio) -> io::Error {
         let ret = Command::spawn(self, default, false);
         match ret {
diff --git a/library/std/src/sys/process/unsupported.rs b/library/std/src/sys/process/unsupported.rs
index fee81744f09..469922c78ac 100644
--- a/library/std/src/sys/process/unsupported.rs
+++ b/library/std/src/sys/process/unsupported.rs
@@ -1,3 +1,4 @@
+use super::env::{CommandEnv, CommandEnvs};
 pub use crate::ffi::OsString as EnvKey;
 use crate::ffi::{OsStr, OsString};
 use crate::num::NonZero;
@@ -5,7 +6,6 @@ use crate::path::Path;
 use crate::sys::fs::File;
 use crate::sys::pipe::AnonPipe;
 use crate::sys::unsupported;
-use crate::sys_common::process::{CommandEnv, CommandEnvs};
 use crate::{fmt, io};
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -104,10 +104,10 @@ impl Command {
     ) -> io::Result<(Process, StdioPipes)> {
         unsupported()
     }
+}
 
-    pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
-        unsupported()
-    }
+pub fn output(_cmd: &mut Command) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
+    unsupported()
 }
 
 impl From<AnonPipe> for Stdio {
diff --git a/library/std/src/sys/process/windows.rs b/library/std/src/sys/process/windows.rs
index 4cfdf908c58..4acd753eec9 100644
--- a/library/std/src/sys/process/windows.rs
+++ b/library/std/src/sys/process/windows.rs
@@ -5,6 +5,7 @@ mod tests;
 
 use core::ffi::c_void;
 
+use super::env::{CommandEnv, CommandEnvs};
 use crate::collections::BTreeMap;
 use crate::env::consts::{EXE_EXTENSION, EXE_SUFFIX};
 use crate::ffi::{OsStr, OsString};
@@ -24,7 +25,6 @@ use crate::sys::pal::{ensure_no_nuls, fill_utf16_buf};
 use crate::sys::pipe::{self, AnonPipe};
 use crate::sys::{cvt, path, stdio};
 use crate::sys_common::IntoInner;
-use crate::sys_common::process::{CommandEnv, CommandEnvs};
 use crate::{cmp, env, fmt, ptr};
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -389,11 +389,6 @@ impl Command {
             ))
         }
     }
-
-    pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
-        let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?;
-        crate::sys_common::process::wait_with_output(proc, pipes)
-    }
 }
 
 impl fmt::Debug for Command {
diff --git a/library/std/src/sys/sync/mutex/fuchsia.rs b/library/std/src/sys/sync/mutex/fuchsia.rs
index 3d388a4564a..cbb1926530f 100644
--- a/library/std/src/sys/sync/mutex/fuchsia.rs
+++ b/library/std/src/sys/sync/mutex/fuchsia.rs
@@ -39,7 +39,7 @@
 
 use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
 use crate::sync::atomic::{Atomic, AtomicU32};
-use crate::sys::futex::zircon::{
+use crate::sys::fuchsia::{
     ZX_ERR_BAD_HANDLE, ZX_ERR_BAD_STATE, ZX_ERR_INVALID_ARGS, ZX_ERR_TIMED_OUT, ZX_ERR_WRONG_TYPE,
     ZX_OK, ZX_TIME_INFINITE, zx_futex_wait, zx_futex_wake_single_owner, zx_handle_t,
     zx_thread_self,
@@ -83,13 +83,13 @@ impl Mutex {
 
     #[inline]
     pub fn try_lock(&self) -> bool {
-        let thread_self = unsafe { zx_thread_self() };
+        let thread_self = zx_thread_self();
         self.futex.compare_exchange(UNLOCKED, to_state(thread_self), Acquire, Relaxed).is_ok()
     }
 
     #[inline]
     pub fn lock(&self) {
-        let thread_self = unsafe { zx_thread_self() };
+        let thread_self = zx_thread_self();
         if let Err(state) =
             self.futex.compare_exchange(UNLOCKED, to_state(thread_self), Acquire, Relaxed)
         {
diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs
index 2a5de7f6666..b7f4656fa37 100644
--- a/library/std/src/sys_common/mod.rs
+++ b/library/std/src/sys_common/mod.rs
@@ -20,7 +20,6 @@
 #[cfg(test)]
 mod tests;
 
-pub mod process;
 pub mod wstr;
 pub mod wtf8;
 
diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs
index acaf026c679..7f56d1e3626 100644
--- a/library/test/src/lib.rs
+++ b/library/test/src/lib.rs
@@ -98,6 +98,15 @@ const SECONDARY_TEST_BENCH_BENCHMARKS_VAR: &str = "__RUST_TEST_BENCH_BENCHMARKS"
 // The default console test runner. It accepts the command line
 // arguments and a vector of test_descs.
 pub fn test_main(args: &[String], tests: Vec<TestDescAndFn>, options: Option<Options>) {
+    test_main_with_exit_callback(args, tests, options, || {})
+}
+
+pub fn test_main_with_exit_callback<F: FnOnce()>(
+    args: &[String],
+    tests: Vec<TestDescAndFn>,
+    options: Option<Options>,
+    exit_callback: F,
+) {
     let mut opts = match cli::parse_opts(args) {
         Some(Ok(o)) => o,
         Some(Err(msg)) => {
@@ -151,6 +160,7 @@ pub fn test_main(args: &[String], tests: Vec<TestDescAndFn>, options: Option<Opt
         let res = console::run_tests_console(&opts, tests);
         // Prevent Valgrind from reporting reachable blocks in users' unit tests.
         drop(panic::take_hook());
+        exit_callback();
         match res {
             Ok(true) => {}
             Ok(false) => process::exit(ERROR_EXIT_CODE),
diff --git a/library/windows_targets/src/lib.rs b/library/windows_targets/src/lib.rs
index c7d158584eb..bce54c5ffce 100644
--- a/library/windows_targets/src/lib.rs
+++ b/library/windows_targets/src/lib.rs
@@ -34,6 +34,7 @@ pub macro link {
 }
 
 #[cfg(not(feature = "windows_raw_dylib"))]
+#[cfg(not(target_os = "cygwin"))] // Cygwin doesn't need these libs
 #[cfg_attr(target_vendor = "win7", link(name = "advapi32"))]
 #[link(name = "ntdll")]
 #[link(name = "userenv")]
diff --git a/rustfmt.toml b/rustfmt.toml
index 7c384b876bf..d9857a7e3e7 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -19,6 +19,7 @@ ignore = [
     "/tests/debuginfo/",              # These tests are somewhat sensitive to source code layout.
     "/tests/incremental/",            # These tests are somewhat sensitive to source code layout.
     "/tests/pretty/",                 # These tests are very sensitive to source code layout.
+    "/tests/run-make/export",         # These tests contain syntax errors.
     "/tests/run-make/translation/test.rs", # This test contains syntax errors.
     "/tests/rustdoc/",                # Some have syntax errors, some are whitespace-sensitive.
     "/tests/rustdoc-gui/",            # Some tests are sensitive to source code layout.
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index d415668f54a..cdad3bd46fa 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -64,7 +64,7 @@ dependencies = [
  "tracing-subscriber",
  "tracing-tree",
  "walkdir",
- "windows",
+ "windows 0.57.0",
  "xz2",
 ]
 
@@ -159,12 +159,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "core-foundation-sys"
-version = "0.8.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
-
-[[package]]
 name = "cpufeatures"
 version = "0.2.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -441,6 +435,25 @@ dependencies = [
 ]
 
 [[package]]
+name = "objc2-core-foundation"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "objc2-io-kit"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71c1c64d6120e51cd86033f67176b1cb66780c2efe34dec55176f77befd93c0a"
+dependencies = [
+ "libc",
+ "objc2-core-foundation",
+]
+
+[[package]]
 name = "object"
 version = "0.36.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -700,15 +713,16 @@ dependencies = [
 
 [[package]]
 name = "sysinfo"
-version = "0.33.0"
+version = "0.35.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "948512566b1895f93b1592c7574baeb2de842f224f2aab158799ecadb8ebbb46"
+checksum = "b897c8ea620e181c7955369a31be5f48d9a9121cb59fd33ecef9ff2a34323422"
 dependencies = [
- "core-foundation-sys",
  "libc",
  "memchr",
  "ntapi",
- "windows",
+ "objc2-core-foundation",
+ "objc2-io-kit",
+ "windows 0.61.1",
 ]
 
 [[package]]
@@ -927,23 +941,68 @@ version = "0.57.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"
 dependencies = [
- "windows-core",
+ "windows-core 0.57.0",
  "windows-targets",
 ]
 
 [[package]]
+name = "windows"
+version = "0.61.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419"
+dependencies = [
+ "windows-collections",
+ "windows-core 0.61.0",
+ "windows-future",
+ "windows-link",
+ "windows-numerics",
+]
+
+[[package]]
+name = "windows-collections"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
+dependencies = [
+ "windows-core 0.61.0",
+]
+
+[[package]]
 name = "windows-core"
 version = "0.57.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
 dependencies = [
- "windows-implement",
- "windows-interface",
- "windows-result",
+ "windows-implement 0.57.0",
+ "windows-interface 0.57.0",
+ "windows-result 0.1.2",
  "windows-targets",
 ]
 
 [[package]]
+name = "windows-core"
+version = "0.61.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980"
+dependencies = [
+ "windows-implement 0.60.0",
+ "windows-interface 0.59.1",
+ "windows-link",
+ "windows-result 0.3.2",
+ "windows-strings",
+]
+
+[[package]]
+name = "windows-future"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a1d6bbefcb7b60acd19828e1bc965da6fcf18a7e39490c5f8be71e54a19ba32"
+dependencies = [
+ "windows-core 0.61.0",
+ "windows-link",
+]
+
+[[package]]
 name = "windows-implement"
 version = "0.57.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -955,6 +1014,17 @@ dependencies = [
 ]
 
 [[package]]
+name = "windows-implement"
+version = "0.60.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
 name = "windows-interface"
 version = "0.57.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -966,6 +1036,33 @@ dependencies = [
 ]
 
 [[package]]
+name = "windows-interface"
+version = "0.59.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "windows-link"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
+
+[[package]]
+name = "windows-numerics"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
+dependencies = [
+ "windows-core 0.61.0",
+ "windows-link",
+]
+
+[[package]]
 name = "windows-result"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -975,6 +1072,24 @@ dependencies = [
 ]
 
 [[package]]
+name = "windows-result"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
+name = "windows-strings"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
 name = "windows-sys"
 version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index 712a9b04c1a..e34de924cc1 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -58,7 +58,7 @@ walkdir = "2.4"
 xz2 = "0.1"
 
 # Dependencies needed by the build-metrics feature
-sysinfo = { version = "0.33.0", default-features = false, optional = true, features = ["system"] }
+sysinfo = { version = "0.35.0", default-features = false, optional = true, features = ["system"] }
 
 # Dependencies needed by the `tracing` feature
 tracing = { version = "0.1", optional = true, features = ["attributes"] }
diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs
index cbfe00a757c..833f8027951 100644
--- a/src/bootstrap/src/bin/main.rs
+++ b/src/bootstrap/src/bin/main.rs
@@ -163,7 +163,7 @@ fn check_version(config: &Config) -> Option<String> {
             msg.push_str("WARNING: The `change-id` is missing in the `bootstrap.toml`. This means that you will not be able to track the major changes made to the bootstrap configurations.\n");
             msg.push_str("NOTE: to silence this warning, ");
             msg.push_str(&format!(
-                "add `change-id = {latest_change_id}` or change-id = \"ignore\" at the top of `bootstrap.toml`"
+                "add `change-id = {latest_change_id}` or `change-id = \"ignore\"` at the top of `bootstrap.toml`"
             ));
             return Some(msg);
         }
@@ -195,7 +195,7 @@ fn check_version(config: &Config) -> Option<String> {
 
     msg.push_str("NOTE: to silence this warning, ");
     msg.push_str(&format!(
-        "update `bootstrap.toml` to use `change-id = {latest_change_id}` or change-id = \"ignore\" instead"
+        "update `bootstrap.toml` to use `change-id = {latest_change_id}` or `change-id = \"ignore\"` instead"
     ));
 
     if io::stdout().is_terminal() {
diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs
index ae9511b7867..fa848c492b4 100644
--- a/src/bootstrap/src/core/build_steps/check.rs
+++ b/src/bootstrap/src/core/build_steps/check.rs
@@ -527,3 +527,70 @@ tool_check_step!(Bootstrap { path: "src/bootstrap", default: false });
 // `run-make-support` will be built as part of suitable run-make compiletest test steps, but support
 // check to make it easier to work on.
 tool_check_step!(RunMakeSupport { path: "src/tools/run-make-support", default: false });
+
+/// Check step for the `coverage-dump` bootstrap tool. The coverage-dump tool
+/// is used internally by coverage tests.
+///
+/// FIXME(Zalathar): This is temporarily separate from the other tool check
+/// steps so that it can use the stage 0 compiler instead of `top_stage`,
+/// without introducing conflicts with the stage 0 redesign (#119899).
+///
+/// After the stage 0 redesign lands, we can look into using the stage 0
+/// compiler to check all bootstrap tools (#139170).
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub(crate) struct CoverageDump;
+
+impl CoverageDump {
+    const PATH: &str = "src/tools/coverage-dump";
+}
+
+impl Step for CoverageDump {
+    type Output = ();
+
+    /// Most contributors won't care about coverage-dump, so don't make their
+    /// check builds slower unless they opt in and check it explicitly.
+    const DEFAULT: bool = false;
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.path(Self::PATH)
+    }
+
+    fn make_run(run: RunConfig<'_>) {
+        run.builder.ensure(Self {});
+    }
+
+    fn run(self, builder: &Builder<'_>) -> Self::Output {
+        // Make sure we haven't forgotten any fields, if there are any.
+        let Self {} = self;
+        let display_name = "coverage-dump";
+        let host = builder.config.build;
+        let target = host;
+        let mode = Mode::ToolBootstrap;
+
+        let compiler = builder.compiler(0, host);
+        let cargo = prepare_tool_cargo(
+            builder,
+            compiler,
+            mode,
+            target,
+            builder.kind,
+            Self::PATH,
+            SourceType::InTree,
+            &[],
+        );
+
+        let stamp = BuildStamp::new(&builder.cargo_out(compiler, mode, target))
+            .with_prefix(&format!("{display_name}-check"));
+
+        let _guard = builder.msg_tool(
+            builder.kind,
+            mode,
+            display_name,
+            compiler.stage,
+            &compiler.host,
+            &target,
+        );
+        run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
+    }
+}
diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs
index 9da8b27a917..93900a9043e 100644
--- a/src/bootstrap/src/core/build_steps/format.rs
+++ b/src/bootstrap/src/core/build_steps/format.rs
@@ -9,7 +9,7 @@ use std::sync::mpsc::SyncSender;
 use build_helper::git::get_git_modified_files;
 use ignore::WalkBuilder;
 
-use crate::core::builder::Builder;
+use crate::core::builder::{Builder, Kind};
 use crate::utils::build_stamp::BuildStamp;
 use crate::utils::exec::command;
 use crate::utils::helpers::{self, t};
@@ -122,6 +122,12 @@ fn print_paths(verb: &str, adjective: Option<&str>, paths: &[String]) {
 }
 
 pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) {
+    if build.kind == Kind::Format && build.top_stage != 0 {
+        eprintln!("ERROR: `x fmt` only supports stage 0.");
+        eprintln!("HELP: Use `x run rustfmt` to run in-tree rustfmt.");
+        crate::exit!(1);
+    }
+
     if !paths.is_empty() {
         eprintln!(
             "fmt error: path arguments are no longer accepted; use `--all` to format everything"
diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs
index 5cacd5b9914..0bba441c3fa 100644
--- a/src/bootstrap/src/core/build_steps/run.rs
+++ b/src/bootstrap/src/core/build_steps/run.rs
@@ -392,3 +392,84 @@ impl Step for CyclicStep {
         builder.ensure(CyclicStep { n: self.n.saturating_sub(1) })
     }
 }
+
+/// Step to manually run the coverage-dump tool (`./x run coverage-dump`).
+///
+/// The coverage-dump tool is an internal detail of coverage tests, so this run
+/// step is only needed when testing coverage-dump manually.
+#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
+pub struct CoverageDump;
+
+impl Step for CoverageDump {
+    type Output = ();
+
+    const DEFAULT: bool = false;
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.path("src/tools/coverage-dump")
+    }
+
+    fn make_run(run: RunConfig<'_>) {
+        run.builder.ensure(Self {});
+    }
+
+    fn run(self, builder: &Builder<'_>) {
+        let mut cmd = builder.tool_cmd(Tool::CoverageDump);
+        cmd.args(&builder.config.free_args);
+        cmd.run(builder);
+    }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct Rustfmt;
+
+impl Step for Rustfmt {
+    type Output = ();
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.path("src/tools/rustfmt")
+    }
+
+    fn make_run(run: RunConfig<'_>) {
+        run.builder.ensure(Rustfmt);
+    }
+
+    fn run(self, builder: &Builder<'_>) {
+        let host = builder.build.build;
+
+        // `x run` uses stage 0 by default but rustfmt does not work well with stage 0.
+        // Change the stage to 1 if it's not set explicitly.
+        let stage = if builder.config.is_explicit_stage() || builder.top_stage >= 1 {
+            builder.top_stage
+        } else {
+            1
+        };
+
+        if stage == 0 {
+            eprintln!("rustfmt cannot be run at stage 0");
+            eprintln!("HELP: Use `x fmt` to use stage 0 rustfmt.");
+            std::process::exit(1);
+        }
+
+        let compiler = builder.compiler(stage, host);
+        let rustfmt_build = builder.ensure(tool::Rustfmt { compiler, target: host });
+
+        let mut rustfmt = tool::prepare_tool_cargo(
+            builder,
+            rustfmt_build.build_compiler,
+            Mode::ToolRustc,
+            host,
+            Kind::Run,
+            "src/tools/rustfmt",
+            SourceType::InTree,
+            &[],
+        );
+
+        rustfmt.args(["--bin", "rustfmt", "--"]);
+        rustfmt.args(builder.config.args());
+
+        rustfmt.into_cmd().run(builder);
+    }
+}
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index a7a3b5a878c..29fb576f574 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -54,6 +54,7 @@ impl Step for CrateBootstrap {
         run.path("src/tools/jsondoclint")
             .path("src/tools/suggest-tests")
             .path("src/tools/replace-version-placeholder")
+            .path("src/tools/coverage-dump")
             // We want `./x test tidy` to _run_ the tidy tool, not its tests.
             // So we need a separate alias to test the tidy tool itself.
             .alias("tidyselftest")
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index 36b3c95d638..d625c2ef584 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -112,9 +112,8 @@ impl Cargo {
         let mut cargo = builder.cargo(compiler, mode, source_type, target, cmd_kind);
 
         match cmd_kind {
-            // No need to configure the target linker for these command types,
-            // as they don't invoke rustc at all.
-            Kind::Clean | Kind::Suggest | Kind::Format | Kind::Setup => {}
+            // No need to configure the target linker for these command types.
+            Kind::Clean | Kind::Check | Kind::Suggest | Kind::Format | Kind::Setup => {}
             _ => {
                 cargo.configure_linker(builder);
             }
@@ -205,6 +204,8 @@ impl Cargo {
         self
     }
 
+    // FIXME(onur-ozkan): Add coverage to make sure modifications to this function
+    // doesn't cause cache invalidations (e.g., #130108).
     fn configure_linker(&mut self, builder: &Builder<'_>) -> &mut Cargo {
         let target = self.target;
         let compiler = self.compiler;
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index c32d9c2870c..75cc5d3986b 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -961,6 +961,7 @@ impl<'a> Builder<'a> {
                 check::RunMakeSupport,
                 check::Compiletest,
                 check::FeaturesStatusDump,
+                check::CoverageDump,
             ),
             Kind::Test => describe!(
                 crate::core::build_steps::toolstate::ToolStateCheck,
@@ -1114,6 +1115,8 @@ impl<'a> Builder<'a> {
                 run::UnicodeTableGenerator,
                 run::FeaturesStatusDump,
                 run::CyclicStep,
+                run::CoverageDump,
+                run::Rustfmt,
             ),
             Kind::Setup => {
                 describe!(setup::Profile, setup::Hook, setup::Link, setup::Editor)
@@ -1534,7 +1537,7 @@ impl<'a> Builder<'a> {
             let out = step.clone().run(self);
             let dur = start.elapsed();
             let deps = self.time_spent_on_dependencies.replace(parent + dur);
-            (out, dur - deps)
+            (out, dur.saturating_sub(deps))
         };
 
         if self.config.print_step_timings && !self.config.dry_run() {
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 88d181532a7..1e6acad5c0f 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -53,6 +53,7 @@ use tracing::{instrument, span};
 pub use utils::change_tracker::{
     CONFIG_CHANGE_HISTORY, find_recent_config_change_ids, human_readable_changes,
 };
+pub use utils::helpers::PanicTracker;
 
 use crate::core::build_steps::vendor::VENDOR_DIR;
 
diff --git a/src/bootstrap/src/utils/cc_detect.rs b/src/bootstrap/src/utils/cc_detect.rs
index 147b009d3f4..ceac24d4315 100644
--- a/src/bootstrap/src/utils/cc_detect.rs
+++ b/src/bootstrap/src/utils/cc_detect.rs
@@ -96,6 +96,7 @@ pub fn find(build: &Build) {
     let targets: HashSet<_> = match build.config.cmd {
         // We don't need to check cross targets for these commands.
         crate::Subcommand::Clean { .. }
+        | crate::Subcommand::Check { .. }
         | crate::Subcommand::Suggest { .. }
         | crate::Subcommand::Format { .. }
         | crate::Subcommand::Setup { .. } => {
diff --git a/src/bootstrap/src/utils/cc_detect/tests.rs b/src/bootstrap/src/utils/cc_detect/tests.rs
index b4a1b52dd23..43d61ce02c5 100644
--- a/src/bootstrap/src/utils/cc_detect/tests.rs
+++ b/src/bootstrap/src/utils/cc_detect/tests.rs
@@ -181,7 +181,7 @@ fn test_language_clang() {
 
 #[test]
 fn test_new_cc_build() {
-    let build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) });
+    let build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) });
     let target = TargetSelection::from_user("x86_64-unknown-linux-gnu");
     let cfg = new_cc_build(&build, target.clone());
     let compiler = cfg.get_compiler();
@@ -190,7 +190,7 @@ fn test_new_cc_build() {
 
 #[test]
 fn test_default_compiler_wasi() {
-    let build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) });
+    let build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) });
     let target = TargetSelection::from_user("wasm32-wasi");
     let wasi_sdk = PathBuf::from("/wasi-sdk");
     // SAFETY: bootstrap tests run on a single thread
@@ -215,7 +215,7 @@ fn test_default_compiler_wasi() {
 
 #[test]
 fn test_default_compiler_fallback() {
-    let build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) });
+    let build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) });
     let target = TargetSelection::from_user("x86_64-unknown-linux-gnu");
     let mut cfg = cc::Build::new();
     let result = default_compiler(&mut cfg, Language::C, target, &build);
@@ -224,7 +224,7 @@ fn test_default_compiler_fallback() {
 
 #[test]
 fn test_find_target_with_config() {
-    let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) });
+    let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) });
     let target = TargetSelection::from_user("x86_64-unknown-linux-gnu");
     let mut target_config = Target::default();
     target_config.cc = Some(PathBuf::from("dummy-cc"));
@@ -249,7 +249,7 @@ fn test_find_target_with_config() {
 
 #[test]
 fn test_find_target_without_config() {
-    let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) });
+    let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) });
     let target = TargetSelection::from_user("x86_64-unknown-linux-gnu");
     build.config.target_config.clear();
     find_target(&build, target.clone());
@@ -262,7 +262,7 @@ fn test_find_target_without_config() {
 
 #[test]
 fn test_find() {
-    let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) });
+    let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) });
     let target1 = TargetSelection::from_user("x86_64-unknown-linux-gnu");
     let target2 = TargetSelection::from_user("x86_64-unknown-openbsd");
     build.targets.push(target1.clone());
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index d926185ffaf..1d0ea3ebf61 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -406,4 +406,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Info,
         summary: "Added a new option `rust.debug-assertions-tools` to control debug asssertions for tools.",
     },
+    ChangeInfo {
+        change_id: 140732,
+        severity: ChangeSeverity::Info,
+        summary: "`./x run` now supports running in-tree `rustfmt`, e.g., `./x run rustfmt -- --check /path/to/file.rs`.",
+    },
 ];
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index 1299fbb7d62..b31b2757767 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -7,8 +7,9 @@ use std::ffi::OsStr;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
 use std::sync::OnceLock;
+use std::thread::panicking;
 use std::time::{Instant, SystemTime, UNIX_EPOCH};
-use std::{env, fs, io, str};
+use std::{env, fs, io, panic, str};
 
 use build_helper::util::fail;
 use object::read::archive::ArchiveFile;
@@ -22,6 +23,23 @@ pub use crate::utils::shared_helpers::{dylib_path, dylib_path_var};
 #[cfg(test)]
 mod tests;
 
+/// A wrapper around `std::panic::Location` used to track the location of panics
+/// triggered by `t` macro usage.
+pub struct PanicTracker<'a>(pub &'a panic::Location<'a>);
+
+impl Drop for PanicTracker<'_> {
+    fn drop(&mut self) {
+        if panicking() {
+            eprintln!(
+                "Panic was initiated from {}:{}:{}",
+                self.0.file(),
+                self.0.line(),
+                self.0.column()
+            );
+        }
+    }
+}
+
 /// A helper macro to `unwrap` a result except also print out details like:
 ///
 /// * The file/line of the panic
@@ -32,19 +50,21 @@ mod tests;
 /// using a `Result` with `try!`, but this may change one day...
 #[macro_export]
 macro_rules! t {
-    ($e:expr) => {
+    ($e:expr) => {{
+        let _panic_guard = $crate::PanicTracker(std::panic::Location::caller());
         match $e {
             Ok(e) => e,
             Err(e) => panic!("{} failed with {}", stringify!($e), e),
         }
-    };
+    }};
     // it can show extra info in the second parameter
-    ($e:expr, $extra:expr) => {
+    ($e:expr, $extra:expr) => {{
+        let _panic_guard = $crate::PanicTracker(std::panic::Location::caller());
         match $e {
             Ok(e) => e,
             Err(e) => panic!("{} failed with {} ({:?})", stringify!($e), e, $extra),
         }
-    };
+    }};
 }
 
 pub use t;
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
index 3428dd4826a..e15121e0f31 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
@@ -1 +1 @@
-0.20.3
\ No newline at end of file
+0.20.6
\ No newline at end of file
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 3bf3402aea982b876eb56c87da17b0685c6461d
+Subproject 387392674d74656f7cb437c05a96f0c52ea8e60
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject 0d7964d5b22cf920237ef1282d869564b4883b8
+Subproject 8a8918c698534547fa8a1a693cb3e7277f0bfb2
diff --git a/src/doc/rustc-dev-guide/src/mir/dataflow.md b/src/doc/rustc-dev-guide/src/mir/dataflow.md
index f31da5ca22e..85e57dd839b 100644
--- a/src/doc/rustc-dev-guide/src/mir/dataflow.md
+++ b/src/doc/rustc-dev-guide/src/mir/dataflow.md
@@ -148,8 +148,7 @@ whereas this code uses [`ResultsCursor`]:
 
 ```rust,ignore
 let mut results = MyAnalysis::new()
-    .into_engine(tcx, body, def_id)
-    .iterate_to_fixpoint()
+    .iterate_to_fixpoint(tcx, body, None);
     .into_results_cursor(body);
 
 // Inspect the fixpoint state immediately before each `Drop` terminator.
diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md
index c04f296ba0b..825be11c82a 100644
--- a/src/doc/rustc-dev-guide/src/tests/ci.md
+++ b/src/doc/rustc-dev-guide/src/tests/ci.md
@@ -135,12 +135,16 @@ There are several use-cases for try builds:
 - Run a specific CI job (e.g. Windows tests) on a PR, to quickly test if it
   passes the test suite executed by that job.
 
-You can select which CI jobs will
-be executed in the try build by adding lines containing `try-job:
-<job pattern>` to the PR description. All such specified jobs will be executed
-in the try build once the `@bors try` command is used on the PR. If no try
-jobs are specified in this way, the jobs defined in the `try` section of
-[`jobs.yml`] will be executed by default.
+By default, if you send a comment with `@bors try`, the jobs defined in the `try` section of
+[`jobs.yml`] will be executed. We call this mode a "fast try build". Such a try build
+will not execute any tests, and it will allow compilation warnings. It is useful when you want to
+get an optimized toolchain as fast as possible, for a crater run or performance benchmarks,
+even if it might not be working fully correctly.
+
+If you want to run a custom CI job in a try build and make sure that it passes all tests and does
+not produce any compilation warnings, you can select CI jobs to be executed by adding lines
+containing `try-job: <job pattern>` to the PR description. All such specified jobs will be executed
+in the try build once the `@bors try` command is used on the PR.
 
 Each pattern can either be an exact name of a job or a glob pattern that matches multiple jobs,
 for example `*msvc*` or `*-alt`. You can start at most 20 jobs in a single try build. When using
diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md
index b31c861c947..721d20b65c5 100644
--- a/src/doc/rustc-dev-guide/src/tests/ui.md
+++ b/src/doc/rustc-dev-guide/src/tests/ui.md
@@ -344,8 +344,7 @@ For checking runtime output, `//@ check-run-results` may be preferable.
 
 Only use `error-pattern` if none of the above works.
 
-Line annotations `//~` are still checked in tests using `error-pattern`.
-In exceptional cases, use `//@ compile-flags: --error-format=human` to opt out of these checks.
+Line annotations `//~` and `error-pattern` are compatible and can be used in the same test.
 
 ### Diagnostic kinds (error levels)
 
@@ -356,9 +355,12 @@ The diagnostic kinds that you can have are:
 - `NOTE`
 - `HELP`
 - `SUGGESTION`
+- `RAW`
 
 The `SUGGESTION` kind is used for specifying what the expected replacement text
 should be for a diagnostic suggestion.
+The `RAW` kind can be used for matching on lines from non-structured output sometimes emitted
+by the compiler instead of or in addition to structured json.
 
 `ERROR` and `WARN` kinds are required to be exhaustively covered by line annotations
 `//~` by default.
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index cf41f5b86a8..a3939e5a5c4 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -58,6 +58,7 @@
       - [thumbv7m-none-eabi](./platform-support/thumbv7m-none-eabi.md)
       - [thumbv8m.base-none-eabi](./platform-support/thumbv8m.base-none-eabi.md)
       - [thumbv8m.main-none-eabi\*](./platform-support/thumbv8m.main-none-eabi.md)
+    - [armv5te-unknown-linux-gnueabi](platform-support/armv5te-unknown-linux-gnueabi.md)
     - [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md)
     - [armv7-rtems-eabihf](platform-support/armv7-rtems-eabihf.md)
     - [armv7-sony-vita-newlibeabihf](platform-support/armv7-sony-vita-newlibeabihf.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 50c7ae3ef8d..60002a5f9e5 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -156,7 +156,7 @@ target | std | notes
 [`arm64ec-pc-windows-msvc`](platform-support/arm64ec-pc-windows-msvc.md) | ✓ | Arm64EC Windows MSVC
 [`armebv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian
 [`armebv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian, hardfloat
-`armv5te-unknown-linux-gnueabi` | ✓ | Armv5TE Linux (kernel 4.4, glibc 2.23)
+[`armv5te-unknown-linux-gnueabi`](platform-support/armv5te-unknown-linux-gnueabi.md) | ✓ | Armv5TE Linux (kernel 4.4, glibc 2.23)
 `armv5te-unknown-linux-musleabi` | ✓ | Armv5TE Linux with musl 1.2.3
 [`armv7-linux-androideabi`](platform-support/android.md) | ✓ | Armv7-A Android
 `armv7-unknown-linux-gnueabi` | ✓ | Armv7-A Linux (kernel 4.15, glibc 2.27)
diff --git a/src/doc/rustc/src/platform-support/armv5te-unknown-linux-gnueabi.md b/src/doc/rustc/src/platform-support/armv5te-unknown-linux-gnueabi.md
new file mode 100644
index 00000000000..1baf1049994
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/armv5te-unknown-linux-gnueabi.md
@@ -0,0 +1,29 @@
+# `armv5te-unknown-linux-gnueabi`
+
+**Tier: 2**
+
+This target supports Linux programs with glibc on ARMv5TE CPUs without
+floating-point units.
+
+## Target maintainers
+
+[@koalatux](https://github.com/koalatux)
+
+## Requirements
+
+The target is for cross-compilation only. Host tools are not supported.
+std is fully supported.
+
+## Building the target
+
+Because this target is tier 2, artifacts are available from rustup.
+
+## Building Rust programs
+
+For building rust programs, you might want to specify GCC as linker in
+`.cargo/config.toml` as follows:
+
+```toml
+[target.armv5te-unknown-linux-gnueabi]
+linker = "arm-linux-gnueabi-gcc"
+```
diff --git a/src/doc/rustc/src/platform-support/riscv32im-risc0-zkvm-elf.md b/src/doc/rustc/src/platform-support/riscv32im-risc0-zkvm-elf.md
index 09b42da26e7..1d02a7cfbc0 100644
--- a/src/doc/rustc/src/platform-support/riscv32im-risc0-zkvm-elf.md
+++ b/src/doc/rustc/src/platform-support/riscv32im-risc0-zkvm-elf.md
@@ -8,7 +8,6 @@ RISC Zero's Zero Knowledge Virtual Machine (zkVM) implementing the RV32IM instru
 
 [@flaub](https://github.com/flaub)
 [@jbruestle](https://github.com/jbruestle)
-[@SchmErik](https://github.com/SchmErik)
 
 ## Background
 
diff --git a/src/doc/style-guide/src/editions.md b/src/doc/style-guide/src/editions.md
index 19e62c4867c..81b7ff50052 100644
--- a/src/doc/style-guide/src/editions.md
+++ b/src/doc/style-guide/src/editions.md
@@ -26,6 +26,10 @@ edition).
 Not all Rust editions have corresponding changes to the Rust style. For
 instance, Rust 2015, Rust 2018, and Rust 2021 all use the same style edition.
 
+## Rust next style edition
+
+- Never break within a nullary function call `func()` or a unit literal `()`.
+
 ## Rust 2024 style edition
 
 This style guide describes the Rust 2024 style edition. The Rust 2024 style
diff --git a/src/doc/style-guide/src/expressions.md b/src/doc/style-guide/src/expressions.md
index 031e59d86e1..9df5d7d18ed 100644
--- a/src/doc/style-guide/src/expressions.md
+++ b/src/doc/style-guide/src/expressions.md
@@ -183,6 +183,10 @@ let f = Foo {
 };
 ```
 
+## Unit literals
+
+Never break between the opening and closing parentheses of the `()` unit literal.
+
 ## Tuple literals
 
 Use a single-line form where possible. Do not put spaces between the opening
@@ -377,6 +381,11 @@ Do put a space between an argument, and the comma which precedes it.
 
 Prefer not to break a line in the callee expression.
 
+For a function call with no arguments (a nullary function call like `func()`),
+never break within the parentheses, and never put a space between the
+parentheses. Always write a nullary function call as a single-line call, never
+a multi-line call.
+
 ### Single-line calls
 
 Do not put a space between the function name and open paren, between the open
diff --git a/src/doc/style-guide/src/nightly.md b/src/doc/style-guide/src/nightly.md
index d870edf1888..66e7fa3c9f8 100644
--- a/src/doc/style-guide/src/nightly.md
+++ b/src/doc/style-guide/src/nightly.md
@@ -5,15 +5,3 @@ This chapter documents style and formatting for nightly-only syntax. The rest of
 Style and formatting for nightly-only syntax should be removed from this chapter and integrated into the appropriate sections of the style guide at the time of stabilization.
 
 There is no guarantee of the stability of this chapter in contrast to the rest of the style guide. Refer to the style team policy for nightly formatting procedure regarding breaking changes to this chapter.
-
-### `feature(precise_capturing)`
-
-A `use<'a, T>` precise capturing bound is formatted as if it were a single path segment with non-turbofished angle-bracketed args, like a trait bound whose identifier is `use`.
-
-```
-fn foo() -> impl Sized + use<'a> {}
-
-// is formatted analogously to:
-
-fn foo() -> impl Sized + Use<'a> {}
-```
diff --git a/src/doc/style-guide/src/types.md b/src/doc/style-guide/src/types.md
index b7921c8914e..247f05b5769 100644
--- a/src/doc/style-guide/src/types.md
+++ b/src/doc/style-guide/src/types.md
@@ -59,3 +59,15 @@ Box<
     + Debug
 >
 ```
+
+## Precise capturing bounds
+
+A `use<'a, T>` precise capturing bound is formatted as if it were a single path segment with non-turbofished angle-bracketed args, like a trait bound whose identifier is `use`.
+
+```rust
+fn foo() -> impl Sized + use<'a> {}
+
+// is formatted analogously to:
+
+fn foo() -> impl Sized + Use<'a> {}
+```
diff --git a/src/doc/unstable-book/src/language-features/arbitrary-self-types.md b/src/doc/unstable-book/src/language-features/arbitrary-self-types.md
index 2f8b52d4043..d660dd13fe4 100644
--- a/src/doc/unstable-book/src/language-features/arbitrary-self-types.md
+++ b/src/doc/unstable-book/src/language-features/arbitrary-self-types.md
@@ -2,7 +2,7 @@
 
 The tracking issue for this feature is: [#44874]
 
-[#38788]: https://github.com/rust-lang/rust/issues/44874
+[#44874]: https://github.com/rust-lang/rust/issues/44874
 
 ------------------------
 
diff --git a/src/doc/unstable-book/src/language-features/deref-patterns.md b/src/doc/unstable-book/src/language-features/deref-patterns.md
index 0cc7106da48..4c3d456b9af 100644
--- a/src/doc/unstable-book/src/language-features/deref-patterns.md
+++ b/src/doc/unstable-book/src/language-features/deref-patterns.md
@@ -60,20 +60,30 @@ Like [`box_patterns`], deref patterns may move out of boxes:
 # #![feature(deref_patterns)]
 # #![allow(incomplete_features)]
 struct NoCopy;
-// Match exhaustiveness analysis is not yet implemented.
-let deref!(x) = Box::new(NoCopy) else { unreachable!() };
+let deref!(x) = Box::new(NoCopy);
 drop::<NoCopy>(x);
 ```
 
-Additionally, when `deref_patterns` is enabled, string literal patterns may be written where `str`
-is expected. Likewise, byte string literal patterns may be written where `[u8]` or `[u8; _]` is
-expected. This lets them be used in `deref!(_)` patterns:
+Additionally, `deref_patterns` implements changes to string and byte string literal patterns,
+allowing then to be used in deref patterns:
 
 ```rust
 # #![feature(deref_patterns)]
 # #![allow(incomplete_features)]
-match ("test".to_string(), b"test".to_vec()) {
-    (deref!("test"), deref!(b"test")) => {}
+match ("test".to_string(), Box::from("test"), b"test".to_vec()) {
+    ("test", "test", b"test") => {}
+    _ => panic!(),
+}
+
+// This works through multiple layers of reference and smart pointer:
+match (&Box::new(&"test".to_string()), &&&"test") {
+    ("test", "test") => {}
+    _ => panic!(),
+}
+
+// `deref!("...")` syntax may also be used:
+match "test".to_string() {
+    deref!("test") => {}
     _ => panic!(),
 }
 
@@ -82,10 +92,16 @@ match *"test" {
     "test" => {}
     _ => panic!(),
 }
+match *b"test" {
+    b"test" => {}
+    _ => panic!(),
+}
+match *(b"test" as &[u8]) {
+    b"test" => {}
+    _ => panic!(),
+}
 ```
 
-Implicit deref pattern syntax is not yet supported for string or byte string literals.
-
 [`box_patterns`]: ./box-patterns.md
 [`string_deref_patterns`]: ./string-deref-patterns.md
 [smart pointers in the standard library]: https://doc.rust-lang.org/std/ops/trait.DerefPure.html#implementors
diff --git a/src/doc/unstable-book/src/language-features/f128.md b/src/doc/unstable-book/src/language-features/f128.md
index 0cc5f677230..b523ffe10f2 100644
--- a/src/doc/unstable-book/src/language-features/f128.md
+++ b/src/doc/unstable-book/src/language-features/f128.md
@@ -6,4 +6,4 @@ The tracking issue for this feature is: [#116909]
 
 ---
 
-Enable the `f128` type for  IEEE 128-bit floating numbers (quad precision).
+Enable the `f128` type for IEEE 128-bit floating numbers (quad precision).
diff --git a/src/doc/unstable-book/src/language-features/f16.md b/src/doc/unstable-book/src/language-features/f16.md
index efb07a5146d..5f31dcbb06c 100644
--- a/src/doc/unstable-book/src/language-features/f16.md
+++ b/src/doc/unstable-book/src/language-features/f16.md
@@ -6,4 +6,4 @@ The tracking issue for this feature is: [#116909]
 
 ---
 
-Enable the `f16` type for  IEEE 16-bit floating numbers (half precision).
+Enable the `f16` type for IEEE 16-bit floating numbers (half precision).
diff --git a/src/doc/unstable-book/src/language-features/frontmatter.md b/src/doc/unstable-book/src/language-features/frontmatter.md
new file mode 100644
index 00000000000..1d5b4feb6ac
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/frontmatter.md
@@ -0,0 +1,25 @@
+# `frontmatter`
+
+The tracking issue for this feature is: [#136889]
+
+------
+
+The `frontmatter` feature allows an extra metadata block at the top of files for consumption by
+external tools. For example, it can be used by [`cargo-script`] files to specify dependencies.
+
+```rust
+#!/usr/bin/env -S cargo -Zscript
+---
+[dependencies]
+libc = "0.2.172"
+---
+#![feature(frontmatter)]
+# mod libc { pub type c_int = i32; }
+
+fn main() {
+    let x: libc::c_int = 1i32;
+}
+```
+
+[#136889]: https://github.com/rust-lang/rust/issues/136889
+[`cargo-script`]: https://rust-lang.github.io/rfcs/3502-cargo-script.html
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index 27ae0553c60..dbfdd8ebd16 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -14,7 +14,6 @@ base64 = "0.21.7"
 itertools = "0.12"
 indexmap = "2"
 minifier = { version = "0.3.5", default-features = false }
-pulldown-cmark-old = { version = "0.9.6", package = "pulldown-cmark", default-features = false }
 pulldown-cmark-escape = { version = "0.11.0", features = ["simd"] }
 regex = "1"
 rustdoc-json-types = { path = "../rustdoc-json-types" }
diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs
index e967fd40609..d684e6f8650 100644
--- a/src/librustdoc/clean/render_macro_matchers.rs
+++ b/src/librustdoc/clean/render_macro_matchers.rs
@@ -167,7 +167,7 @@ fn print_tts(printer: &mut Printer<'_>, tts: &TokenStream) {
 }
 
 fn usually_needs_space_between_keyword_and_open_delim(symbol: Symbol, span: Span) -> bool {
-    let ident = Ident { name: symbol, span };
+    let ident = Ident::new(symbol, span);
     let is_keyword = ident.is_used_keyword() || ident.is_unused_keyword();
     if !is_keyword {
         // An identifier that is not a keyword usually does not need a space
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index bbe11bf56af..15890fff0c3 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -786,7 +786,11 @@ impl Item {
                             // because it isn't public API.
                             None
                         }
-                        _ => Some(rustc_hir_pretty::attribute_to_string(&tcx, attr)),
+                        _ => Some({
+                            let mut s = rustc_hir_pretty::attribute_to_string(&tcx, attr);
+                            assert_eq!(s.pop(), Some('\n'));
+                            s
+                        }),
                     }
                 } else if attr.has_any_name(ALLOWED_ATTRIBUTES) {
                     Some(
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 829a9ca6e7d..0cdf2f92a89 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -262,11 +262,21 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
         Ok(None) => return,
         Err(error) => {
             eprintln!("{error}");
+            // Since some files in the temporary folder are still owned and alive, we need
+            // to manually remove the folder.
+            let _ = std::fs::remove_dir_all(temp_dir.path());
             std::process::exit(1);
         }
     };
 
-    run_tests(opts, &rustdoc_options, &unused_extern_reports, standalone_tests, mergeable_tests);
+    run_tests(
+        opts,
+        &rustdoc_options,
+        &unused_extern_reports,
+        standalone_tests,
+        mergeable_tests,
+        Some(temp_dir),
+    );
 
     let compiling_test_count = compiling_test_count.load(Ordering::SeqCst);
 
@@ -316,6 +326,8 @@ pub(crate) fn run_tests(
     unused_extern_reports: &Arc<Mutex<Vec<UnusedExterns>>>,
     mut standalone_tests: Vec<test::TestDescAndFn>,
     mergeable_tests: FxIndexMap<Edition, Vec<(DocTestBuilder, ScrapedDocTest)>>,
+    // We pass this argument so we can drop it manually before using `exit`.
+    mut temp_dir: Option<TempDir>,
 ) {
     let mut test_args = Vec::with_capacity(rustdoc_options.test_args.len() + 1);
     test_args.insert(0, "rustdoctest".to_string());
@@ -382,9 +394,14 @@ pub(crate) fn run_tests(
     // `running 0 tests...`.
     if ran_edition_tests == 0 || !standalone_tests.is_empty() {
         standalone_tests.sort_by(|a, b| a.desc.name.as_slice().cmp(b.desc.name.as_slice()));
-        test::test_main(&test_args, standalone_tests, None);
+        test::test_main_with_exit_callback(&test_args, standalone_tests, None, || {
+            // We ensure temp dir destructor is called.
+            std::mem::drop(temp_dir.take());
+        });
     }
     if nb_errors != 0 {
+        // We ensure temp dir destructor is called.
+        std::mem::drop(temp_dir);
         // libtest::ERROR_EXIT_CODE is not public but it's the same value.
         std::process::exit(101);
     }
@@ -450,7 +467,7 @@ enum TestFailure {
 }
 
 enum DirState {
-    Temp(tempfile::TempDir),
+    Temp(TempDir),
     Perm(PathBuf),
 }
 
diff --git a/src/librustdoc/doctest/markdown.rs b/src/librustdoc/doctest/markdown.rs
index 497a8d7c4a7..b3a3ce08a05 100644
--- a/src/librustdoc/doctest/markdown.rs
+++ b/src/librustdoc/doctest/markdown.rs
@@ -116,6 +116,7 @@ pub(crate) fn test(input: &Input, options: Options) -> Result<(), String> {
         &Arc::new(Mutex::new(Vec::new())),
         standalone_tests,
         mergeable_tests,
+        None,
     );
     Ok(())
 }
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index c943d3ad4d0..2db1ea8450c 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -9,7 +9,7 @@ use std::collections::VecDeque;
 use std::fmt::{Display, Write};
 
 use rustc_data_structures::fx::FxIndexMap;
-use rustc_lexer::{Cursor, LiteralKind, TokenKind};
+use rustc_lexer::{Cursor, FrontmatterAllowed, LiteralKind, TokenKind};
 use rustc_span::edition::Edition;
 use rustc_span::symbol::Symbol;
 use rustc_span::{BytePos, DUMMY_SP, Span};
@@ -638,7 +638,8 @@ impl<'src> Classifier<'src> {
     /// Takes as argument the source code to HTML-ify, the rust edition to use and the source code
     /// file span which will be used later on by the `span_correspondence_map`.
     fn new(src: &'src str, file_span: Span, decoration_info: Option<&DecorationInfo>) -> Self {
-        let tokens = PeekIter::new(TokenIter { src, cursor: Cursor::new(src) });
+        let tokens =
+            PeekIter::new(TokenIter { src, cursor: Cursor::new(src, FrontmatterAllowed::Yes) });
         let decorations = decoration_info.map(Decorations::new);
         Classifier {
             tokens,
@@ -884,6 +885,7 @@ impl<'src> Classifier<'src> {
             | TokenKind::At
             | TokenKind::Tilde
             | TokenKind::Colon
+            | TokenKind::Frontmatter { .. }
             | TokenKind::Unknown => return no_highlight(sink),
 
             TokenKind::Question => Class::QuestionMark,
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 19ac24a5d6e..f838f3f1106 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -55,6 +55,9 @@ xmlns="http://www.w3.org/2000/svg" fill="black" height="18px">\
 	--collapse-arrow-image: url('data:image/svg+xml,<svg width="16" height="16" viewBox="0 0 16 16" \
 	enable-background="new 0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path fill="none" \
 	d="M3,8l4,4l4,-4m-4,4M3,4l4,4l4,-4" stroke="black" stroke-width="2"/></svg>');
+	--hamburger-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" \
+		viewBox="0 0 22 22" fill="none" stroke="black">\
+		<path d="M3,5h16M3,11h16M3,17h16" stroke-width="2.75"/></svg>');
 }
 
 :root.sans-serif {
@@ -2001,9 +2004,11 @@ a.tooltip:hover::after {
 	display: flex;
 	margin-right: 4px;
 	position: fixed;
-	left: 6px;
 	height: 34px;
 	width: 34px;
+}
+.hide-sidebar #sidebar-button {
+	left: 6px;
 	background-color: var(--main-background-color);
 	z-index: 1;
 }
@@ -2019,6 +2024,8 @@ a.tooltip:hover::after {
 	align-items: center;
 	justify-content: center;
 	flex-direction: column;
+}
+#settings-menu > a, #help-button > a, button#toggle-all-docs {
 	border: 1px solid transparent;
 	border-radius: var(--button-border-radius);
 	color: var(--main-color);
@@ -2031,14 +2038,15 @@ a.tooltip:hover::after {
 	min-width: 0;
 }
 #sidebar-button > a {
-	background-color: var(--button-background-color);
-	border-color: var(--border-color);
+	background-color: var(--sidebar-background-color);
 	width: 33px;
 }
+#sidebar-button > a:hover, #sidebar-button > a:focus-visible {
+	background-color: var(--main-background-color);
+}
 
 #settings-menu > a:hover, #settings-menu > a:focus-visible,
 #help-button > a:hover, #help-button > a:focus-visible,
-#sidebar-button > a:hover, #sidebar-button > a:focus-visible,
 button#toggle-all-docs:hover, button#toggle-all-docs:focus-visible {
 	border-color: var(--settings-button-border-focus);
 	text-decoration: none;
@@ -2405,10 +2413,9 @@ However, it's not needed with smaller screen width because the doc/code block is
 	use hamburger button */
 .src #sidebar-button > a::before, .sidebar-menu-toggle::before {
 	/* hamburger button image */
-	content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" \
-		viewBox="0 0 22 22" fill="none" stroke="black">\
-		<path d="M3,5h16M3,11h16M3,17h16" stroke-width="2.75"/></svg>');
+	content: var(--hamburger-image);
 	opacity: 0.75;
+	filter: var(--mobile-sidebar-menu-filter);
 }
 .sidebar-menu-toggle:hover::before,
 .sidebar-menu-toggle:active::before,
@@ -2416,17 +2423,6 @@ However, it's not needed with smaller screen width because the doc/code block is
 	opacity: 1;
 }
 
-/* src sidebar button opens a folder view */
-.src #sidebar-button > a::before {
-	/* folder image */
-	content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" \
-		viewBox="0 0 22 22" fill="none" stroke="black">\
-		<path d="M16,9v-4h-6v-1l-2,-2h-4l-2,2v16h13L21,9h-15L2,19" stroke-width="1.25"/>\
-		<path d="M15,7h-11v3" stroke-width="0.75"/>\
-		<path d="M3.75,10v1.25" stroke-width="0.375"/></svg>');
-	opacity: 0.75;
-}
-
 /* Media Queries */
 
 /* Make sure all the buttons line wrap at the same time */
@@ -2611,9 +2607,6 @@ in src-script.js and main.js
 		width: 22px;
 		height: 22px;
 	}
-	.sidebar-menu-toggle::before {
-		filter: var(--mobile-sidebar-menu-filter);
-	}
 	.sidebar-menu-toggle:hover {
 		background: var(--main-background-color);
 	}
@@ -2671,6 +2664,14 @@ in src-script.js and main.js
 		margin: 0 0 -25px 0;
 		padding: var(--nav-sub-mobile-padding);
 	}
+
+	html:not(.src-sidebar-expanded) .src #sidebar-button > a {
+		background-color: var(--main-background-color);
+	}
+	html:not(.src-sidebar-expanded) .src #sidebar-button > a:hover,
+	html:not(.src-sidebar-expanded) .src #sidebar-button > a:focus-visible {
+		background-color: var(--sidebar-background-color);
+	}
 }
 
 
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 44bd96a7e45..bca40b8117b 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -170,12 +170,28 @@ pub fn main() {
     // NOTE: this compiles both versions of tracing unconditionally, because
     // - The compile time hit is not that bad, especially compared to rustdoc's incremental times, and
     // - Otherwise, there's no warning that logging is being ignored when `download-rustc` is enabled
-    // NOTE: The reason this doesn't show double logging when `download-rustc = false` and
-    // `debug_logging = true` is because all rustc logging goes to its version of tracing (the one
-    // in the sysroot), and all of rustdoc's logging goes to its version (the one in Cargo.toml).
 
-    init_logging(&early_dcx);
-    rustc_driver::init_logger(&early_dcx, rustc_log::LoggerConfig::from_env("RUSTDOC_LOG"));
+    crate::init_logging(&early_dcx);
+    match rustc_log::init_logger(rustc_log::LoggerConfig::from_env("RUSTDOC_LOG")) {
+        Ok(()) => {}
+        // With `download-rustc = true` there are definitely 2 distinct tracing crates in the
+        // dependency graph: one in the downloaded sysroot and one built just now as a dependency of
+        // rustdoc. So the sysroot's tracing is definitely not yet initialized here.
+        //
+        // But otherwise, depending on link style, there may or may not be 2 tracing crates in play.
+        // The one we just initialized in `crate::init_logging` above is rustdoc's direct dependency
+        // on tracing. When rustdoc is built by x.py using Cargo, rustc_driver's and rustc_log's
+        // tracing dependency is distinct from this one and also needs to be initialized (using the
+        // same RUSTDOC_LOG environment variable for both). Other build systems may use just a
+        // single tracing crate throughout the rustc and rustdoc build.
+        //
+        // The reason initializing 2 tracings does not show double logging when `download-rustc =
+        // false` and `debug_logging = true` is because all rustc logging goes only to its version
+        // of tracing (the one in the sysroot) and all of rustdoc's logging only goes to its version
+        // (the one in Cargo.toml).
+        Err(rustc_log::Error::AlreadyInit(_)) => {}
+        Err(error) => early_dcx.early_fatal(error.to_string()),
+    }
 
     let exit_code = rustc_driver::catch_with_exit_code(|| {
         let at_args = rustc_driver::args::raw_args(&early_dcx);
diff --git a/src/librustdoc/lint.rs b/src/librustdoc/lint.rs
index dcc27cd62e3..b09ea056885 100644
--- a/src/librustdoc/lint.rs
+++ b/src/librustdoc/lint.rs
@@ -196,14 +196,6 @@ declare_rustdoc_lint! {
     "detects redundant explicit links in doc comments"
 }
 
-declare_rustdoc_lint! {
-    /// This compatibility lint checks for Markdown syntax that works in the old engine but not
-    /// the new one.
-    UNPORTABLE_MARKDOWN,
-    Warn,
-    "detects markdown that is interpreted differently in different parser"
-}
-
 pub(crate) static RUSTDOC_LINTS: Lazy<Vec<&'static Lint>> = Lazy::new(|| {
     vec![
         BROKEN_INTRA_DOC_LINKS,
@@ -217,7 +209,6 @@ pub(crate) static RUSTDOC_LINTS: Lazy<Vec<&'static Lint>> = Lazy::new(|| {
         MISSING_CRATE_LEVEL_DOCS,
         UNESCAPED_BACKTICKS,
         REDUNDANT_EXPLICIT_LINKS,
-        UNPORTABLE_MARKDOWN,
     ]
 });
 
@@ -241,4 +232,5 @@ pub(crate) fn register_lints(_sess: &Session, lint_store: &mut LintStore) {
         .register_renamed("intra_doc_link_resolution_failure", "rustdoc::broken_intra_doc_links");
     lint_store.register_renamed("non_autolinks", "rustdoc::bare_urls");
     lint_store.register_renamed("rustdoc::non_autolinks", "rustdoc::bare_urls");
+    lint_store.register_removed("rustdoc::unportable_markdown", "old parser removed");
 }
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 36f5889dcf4..f3e2138d1a5 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -496,12 +496,21 @@ impl<'tcx> LinkCollector<'_, 'tcx> {
 
         // Try looking for methods and associated items.
         // NB: `path_root` could be empty when resolving in the root namespace (e.g. `::std`).
-        let (path_root, item_str) = path_str.rsplit_once("::").ok_or_else(|| {
-            // If there's no `::`, it's not an associated item.
-            // So we can be sure that `rustc_resolve` was accurate when it said it wasn't resolved.
-            debug!("found no `::`, assuming {path_str} was correctly not in scope");
-            UnresolvedPath { item_id, module_id, partial_res: None, unresolved: path_str.into() }
-        })?;
+        let (path_root, item_str) = match path_str.rsplit_once("::") {
+            Some(res @ (_path_root, item_str)) if !item_str.is_empty() => res,
+            _ => {
+                // If there's no `::`, or the `::` is at the end (e.g. `String::`) it's not an
+                // associated item. So we can be sure that `rustc_resolve` was accurate when it
+                // said it wasn't resolved.
+                debug!("`::` missing or at end, assuming {path_str} was not in scope");
+                return Err(UnresolvedPath {
+                    item_id,
+                    module_id,
+                    partial_res: None,
+                    unresolved: path_str.into(),
+                });
+            }
+        };
         let item_name = Symbol::intern(item_str);
 
         // FIXME(#83862): this arbitrarily gives precedence to primitives over modules to support
diff --git a/src/librustdoc/passes/lint.rs b/src/librustdoc/passes/lint.rs
index 1ecb53e61ac..7740d14148b 100644
--- a/src/librustdoc/passes/lint.rs
+++ b/src/librustdoc/passes/lint.rs
@@ -6,7 +6,6 @@ mod check_code_block_syntax;
 mod html_tags;
 mod redundant_explicit_links;
 mod unescaped_backticks;
-mod unportable_markdown;
 
 use super::Pass;
 use crate::clean::*;
@@ -49,9 +48,6 @@ impl DocVisitor<'_> for Linter<'_, '_> {
             }
             if may_have_block_comment_or_html {
                 html_tags::visit_item(self.cx, item, hir_id, &dox);
-                unportable_markdown::visit_item(self.cx, item, hir_id, &dox);
-            } else if may_have_link {
-                unportable_markdown::visit_item(self.cx, item, hir_id, &dox);
             }
         }
 
diff --git a/src/librustdoc/passes/lint/unportable_markdown.rs b/src/librustdoc/passes/lint/unportable_markdown.rs
deleted file mode 100644
index 95646413a2d..00000000000
--- a/src/librustdoc/passes/lint/unportable_markdown.rs
+++ /dev/null
@@ -1,145 +0,0 @@
-//! Detects specific markdown syntax that's different between pulldown-cmark
-//! 0.9 and 0.11.
-//!
-//! This is a mitigation for old parser bugs that affected some
-//! real crates' docs. The old parser claimed to comply with CommonMark,
-//! but it did not. These warnings will eventually be removed,
-//! though some of them may become Clippy lints.
-//!
-//! <https://github.com/rust-lang/rust/pull/121659#issuecomment-1992752820>
-//!
-//! <https://rustc-dev-guide.rust-lang.org/bug-fix-procedure.html#add-the-lint-to-the-list-of-removed-lists>
-
-use std::collections::{BTreeMap, BTreeSet};
-
-use rustc_hir::HirId;
-use rustc_lint_defs::Applicability;
-use rustc_resolve::rustdoc::source_span_for_markdown_range;
-use {pulldown_cmark as cmarkn, pulldown_cmark_old as cmarko};
-
-use crate::clean::Item;
-use crate::core::DocContext;
-
-pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &str) {
-    let tcx = cx.tcx;
-
-    // P1: unintended strikethrough was fixed by requiring single-tildes to flank
-    // the same way underscores do, so nothing is done here
-
-    // P2: block quotes without following space parsed wrong
-    //
-    // This is the set of starting points for block quotes with no space after
-    // the `>`. It is populated by the new parser, and if the old parser fails to
-    // clear it out, it'll produce a warning.
-    let mut spaceless_block_quotes = BTreeSet::new();
-
-    // P3: missing footnote references
-    //
-    // This is populated by listening for FootnoteReference from
-    // the new parser and old parser.
-    let mut missing_footnote_references = BTreeMap::new();
-    let mut found_footnote_references = BTreeSet::new();
-
-    // populate problem cases from new parser
-    {
-        pub fn main_body_opts_new() -> cmarkn::Options {
-            cmarkn::Options::ENABLE_TABLES
-                | cmarkn::Options::ENABLE_FOOTNOTES
-                | cmarkn::Options::ENABLE_STRIKETHROUGH
-                | cmarkn::Options::ENABLE_TASKLISTS
-                | cmarkn::Options::ENABLE_SMART_PUNCTUATION
-        }
-        let parser_new = cmarkn::Parser::new_ext(dox, main_body_opts_new()).into_offset_iter();
-        for (event, span) in parser_new {
-            if let cmarkn::Event::Start(cmarkn::Tag::BlockQuote(_)) = event {
-                if !dox[span.clone()].starts_with("> ") {
-                    spaceless_block_quotes.insert(span.start);
-                }
-            }
-            if let cmarkn::Event::FootnoteReference(_) = event {
-                found_footnote_references.insert(span.start + 1);
-            }
-        }
-    }
-
-    // remove cases where they don't actually differ
-    {
-        pub fn main_body_opts_old() -> cmarko::Options {
-            cmarko::Options::ENABLE_TABLES
-                | cmarko::Options::ENABLE_FOOTNOTES
-                | cmarko::Options::ENABLE_STRIKETHROUGH
-                | cmarko::Options::ENABLE_TASKLISTS
-                | cmarko::Options::ENABLE_SMART_PUNCTUATION
-        }
-        let parser_old = cmarko::Parser::new_ext(dox, main_body_opts_old()).into_offset_iter();
-        for (event, span) in parser_old {
-            if let cmarko::Event::Start(cmarko::Tag::BlockQuote) = event
-                && !dox[span.clone()].starts_with("> ")
-            {
-                spaceless_block_quotes.remove(&span.start);
-            }
-            if let cmarko::Event::FootnoteReference(_) = event
-                && !found_footnote_references.contains(&(span.start + 1))
-            {
-                missing_footnote_references.insert(span.start + 1, span);
-            }
-        }
-    }
-
-    for start in spaceless_block_quotes {
-        let (span, precise) =
-            source_span_for_markdown_range(tcx, dox, &(start..start + 1), &item.attrs.doc_strings)
-                .map(|span| (span, true))
-                .unwrap_or_else(|| (item.attr_span(tcx), false));
-
-        tcx.node_span_lint(crate::lint::UNPORTABLE_MARKDOWN, hir_id, span, |lint| {
-            lint.primary_message("unportable markdown");
-            lint.help("confusing block quote with no space after the `>` marker".to_string());
-            if precise {
-                lint.span_suggestion(
-                    span.shrink_to_hi(),
-                    "if the quote is intended, add a space",
-                    " ",
-                    Applicability::MaybeIncorrect,
-                );
-                lint.span_suggestion(
-                    span.shrink_to_lo(),
-                    "if it should not be a quote, escape it",
-                    "\\",
-                    Applicability::MaybeIncorrect,
-                );
-            }
-        });
-    }
-    for (_caret, span) in missing_footnote_references {
-        let (ref_span, precise) =
-            source_span_for_markdown_range(tcx, dox, &span, &item.attrs.doc_strings)
-                .map(|span| (span, true))
-                .unwrap_or_else(|| (item.attr_span(tcx), false));
-
-        tcx.node_span_lint(crate::lint::UNPORTABLE_MARKDOWN, hir_id, ref_span, |lint| {
-            lint.primary_message("unportable markdown");
-            if precise {
-                lint.span_suggestion(
-                    ref_span.shrink_to_lo(),
-                    "if it should not be a footnote, escape it",
-                    "\\",
-                    Applicability::MaybeIncorrect,
-                );
-            }
-            if dox.as_bytes().get(span.end) == Some(&b'[') {
-                lint.help("confusing footnote reference and link");
-                if precise {
-                    lint.span_suggestion(
-                        ref_span.shrink_to_hi(),
-                        "if the footnote is intended, add a space",
-                        " ",
-                        Applicability::MaybeIncorrect,
-                    );
-                } else {
-                    lint.help("there should be a space between the link and the footnote");
-                }
-            }
-        });
-    }
-}
diff --git a/src/llvm-project b/src/llvm-project
-Subproject a9865ceca08101071e25f3bba97bba8bf0ea971
+Subproject 8448283b4bd34ea00d76fd4f18ec730b549d6e1
diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
index 63859c0396e..6d3e77b6b6e 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -263,7 +263,7 @@ impl<'tcx> NonCopyConst<'tcx> {
     fn is_value_unfrozen_poly(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<'tcx>) -> bool {
         let def_id = body_id.hir_id.owner.to_def_id();
         let args = ty::GenericArgs::identity_for_item(cx.tcx, def_id);
-        let instance = ty::Instance::new(def_id, args);
+        let instance = ty::Instance::new_raw(def_id, args);
         let cid = GlobalId {
             instance,
             promoted: None,
diff --git a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
index 5b3f60ad6ab..45a5dbabeb4 100644
--- a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
+++ b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
@@ -154,7 +154,7 @@ impl LateLintPass<'_> for WildcardImports {
                 (span, false)
             };
 
-            let mut imports = used_imports.items().map(ToString::to_string).into_sorted_stable_ord();
+            let mut imports: Vec<_> = used_imports.iter().map(ToString::to_string).collect();
             let imports_string = if imports.len() == 1 {
                 imports.pop().unwrap()
             } else if braced_glob {
diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs
index 8db9cd593b3..da09edd7f7c 100644
--- a/src/tools/clippy/clippy_utils/src/ty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs
@@ -20,8 +20,8 @@ use rustc_middle::traits::EvaluationResult;
 use rustc_middle::ty::layout::ValidityRequirement;
 use rustc_middle::ty::{
     self, AdtDef, AliasTy, AssocItem, AssocTag, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind, GenericArgsRef,
-    GenericParamDefKind, IntTy, ParamEnv, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
-    TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr,
+    GenericParamDefKind, IntTy, ParamEnv, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
+    TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr,
 };
 use rustc_span::symbol::Ident;
 use rustc_span::{DUMMY_SP, Span, Symbol, sym};
@@ -915,7 +915,7 @@ pub fn for_each_top_level_late_bound_region<B>(
                 ControlFlow::Continue(())
             }
         }
-        fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) -> Self::Result {
+        fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) -> Self::Result {
             self.index += 1;
             let res = t.super_visit_with(self);
             self.index -= 1;
diff --git a/src/tools/clippy/tests/ui/double_ended_iterator_last.fixed b/src/tools/clippy/tests/ui/double_ended_iterator_last.fixed
index 2ce0c04c301..be31ee5fb48 100644
--- a/src/tools/clippy/tests/ui/double_ended_iterator_last.fixed
+++ b/src/tools/clippy/tests/ui/double_ended_iterator_last.fixed
@@ -84,6 +84,19 @@ fn issue_14139() {
 }
 
 fn drop_order() {
+    struct DropDeIterator(std::vec::IntoIter<S>);
+    impl Iterator for DropDeIterator {
+        type Item = S;
+        fn next(&mut self) -> Option<Self::Item> {
+            self.0.next()
+        }
+    }
+    impl DoubleEndedIterator for DropDeIterator {
+        fn next_back(&mut self) -> Option<Self::Item> {
+            self.0.next_back()
+        }
+    }
+
     struct S(&'static str);
     impl std::ops::Drop for S {
         fn drop(&mut self) {
@@ -92,7 +105,7 @@ fn drop_order() {
     }
 
     let v = vec![S("one"), S("two"), S("three")];
-    let mut v = v.into_iter();
+    let mut v = DropDeIterator(v.into_iter());
     println!("Last element is {}", v.next_back().unwrap().0);
     //~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator`
     println!("Done");
diff --git a/src/tools/clippy/tests/ui/double_ended_iterator_last.rs b/src/tools/clippy/tests/ui/double_ended_iterator_last.rs
index a4eb9b3337b..30864e15bce 100644
--- a/src/tools/clippy/tests/ui/double_ended_iterator_last.rs
+++ b/src/tools/clippy/tests/ui/double_ended_iterator_last.rs
@@ -84,6 +84,19 @@ fn issue_14139() {
 }
 
 fn drop_order() {
+    struct DropDeIterator(std::vec::IntoIter<S>);
+    impl Iterator for DropDeIterator {
+        type Item = S;
+        fn next(&mut self) -> Option<Self::Item> {
+            self.0.next()
+        }
+    }
+    impl DoubleEndedIterator for DropDeIterator {
+        fn next_back(&mut self) -> Option<Self::Item> {
+            self.0.next_back()
+        }
+    }
+
     struct S(&'static str);
     impl std::ops::Drop for S {
         fn drop(&mut self) {
@@ -92,7 +105,7 @@ fn drop_order() {
     }
 
     let v = vec![S("one"), S("two"), S("three")];
-    let v = v.into_iter();
+    let v = DropDeIterator(v.into_iter());
     println!("Last element is {}", v.last().unwrap().0);
     //~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator`
     println!("Done");
diff --git a/src/tools/clippy/tests/ui/double_ended_iterator_last.stderr b/src/tools/clippy/tests/ui/double_ended_iterator_last.stderr
index fe8cf2dcb25..72a6ead47a9 100644
--- a/src/tools/clippy/tests/ui/double_ended_iterator_last.stderr
+++ b/src/tools/clippy/tests/ui/double_ended_iterator_last.stderr
@@ -18,7 +18,7 @@ LL |     let _ = DeIterator.last();
    |                        help: try: `next_back()`
 
 error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator
-  --> tests/ui/double_ended_iterator_last.rs:96:36
+  --> tests/ui/double_ended_iterator_last.rs:109:36
    |
 LL |     println!("Last element is {}", v.last().unwrap().0);
    |                                    ^^^^^^^^
@@ -26,7 +26,7 @@ LL |     println!("Last element is {}", v.last().unwrap().0);
    = note: this change will alter drop order which may be undesirable
 help: try
    |
-LL ~     let mut v = v.into_iter();
+LL ~     let mut v = DropDeIterator(v.into_iter());
 LL ~     println!("Last element is {}", v.next_back().unwrap().0);
    |
 
diff --git a/src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.rs b/src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.rs
index 7c5de8832d6..e9218bbb409 100644
--- a/src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.rs
+++ b/src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.rs
@@ -11,6 +11,19 @@ fn main() {
 }
 
 fn drop_order() {
+    struct DropDeIterator(std::vec::IntoIter<S>);
+    impl Iterator for DropDeIterator {
+        type Item = S;
+        fn next(&mut self) -> Option<Self::Item> {
+            self.0.next()
+        }
+    }
+    impl DoubleEndedIterator for DropDeIterator {
+        fn next_back(&mut self) -> Option<Self::Item> {
+            self.0.next_back()
+        }
+    }
+
     struct S(&'static str);
     impl std::ops::Drop for S {
         fn drop(&mut self) {
@@ -19,7 +32,7 @@ fn drop_order() {
     }
 
     let v = vec![S("one"), S("two"), S("three")];
-    let v = (v.into_iter(), 42);
+    let v = (DropDeIterator(v.into_iter()), 42);
     println!("Last element is {}", v.0.last().unwrap().0);
     //~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator`
     println!("Done");
diff --git a/src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.stderr b/src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.stderr
index 845afc11f04..e330a22a354 100644
--- a/src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.stderr
@@ -1,5 +1,5 @@
 error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator
-  --> tests/ui/double_ended_iterator_last_unfixable.rs:23:36
+  --> tests/ui/double_ended_iterator_last_unfixable.rs:36:36
    |
 LL |     println!("Last element is {}", v.0.last().unwrap().0);
    |                                    ^^^^------
@@ -8,7 +8,7 @@ LL |     println!("Last element is {}", v.0.last().unwrap().0);
    |
    = note: this change will alter drop order which may be undesirable
 note: this must be made mutable to use `.next_back()`
-  --> tests/ui/double_ended_iterator_last_unfixable.rs:23:36
+  --> tests/ui/double_ended_iterator_last_unfixable.rs:36:36
    |
 LL |     println!("Last element is {}", v.0.last().unwrap().0);
    |                                    ^^^
diff --git a/src/tools/clippy/tests/ui/wildcard_imports.fixed b/src/tools/clippy/tests/ui/wildcard_imports.fixed
index a26b4a34190..17510683f03 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports.fixed
+++ b/src/tools/clippy/tests/ui/wildcard_imports.fixed
@@ -16,7 +16,7 @@ use crate::fn_mod::foo;
 //~^ wildcard_imports
 use crate::mod_mod::inner_mod;
 //~^ wildcard_imports
-use crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod};
+use crate::multi_fn_mod::{multi_foo, multi_bar, multi_inner_mod};
 //~^ wildcard_imports
 #[macro_use]
 use crate::struct_mod::{A, inner_struct_mod};
@@ -26,7 +26,7 @@ use crate::struct_mod::{A, inner_struct_mod};
 use wildcard_imports_helper::inner::inner_for_self_import;
 use wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar;
 //~^ wildcard_imports
-use wildcard_imports_helper::{ExternA, extern_foo};
+use wildcard_imports_helper::{extern_foo, ExternA};
 //~^ wildcard_imports
 
 use std::io::prelude::*;
@@ -138,7 +138,7 @@ mod in_fn_test {
     fn test_extern() {
         use wildcard_imports_helper::inner::inner_for_self_import::{self, inner_extern_foo};
         //~^ wildcard_imports
-        use wildcard_imports_helper::{ExternA, extern_foo};
+        use wildcard_imports_helper::{extern_foo, ExternA};
         //~^ wildcard_imports
 
         inner_for_self_import::inner_extern_foo();
@@ -160,7 +160,7 @@ mod in_fn_test {
     }
 
     fn test_extern_reexported() {
-        use wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported};
+        use wildcard_imports_helper::{extern_exported, ExternExportedStruct, ExternExportedEnum};
         //~^ wildcard_imports
 
         extern_exported();
@@ -190,7 +190,7 @@ mod in_fn_test {
 }
 
 fn test_reexported() {
-    use crate::in_fn_test::{ExportedEnum, ExportedStruct, exported};
+    use crate::in_fn_test::{exported, ExportedStruct, ExportedEnum};
     //~^ wildcard_imports
 
     exported();
diff --git a/src/tools/clippy/tests/ui/wildcard_imports.stderr b/src/tools/clippy/tests/ui/wildcard_imports.stderr
index f774126102b..26434656a50 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports.stderr
+++ b/src/tools/clippy/tests/ui/wildcard_imports.stderr
@@ -17,7 +17,7 @@ error: usage of wildcard import
   --> tests/ui/wildcard_imports.rs:19:5
    |
 LL | use crate::multi_fn_mod::*;
-   |     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}`
+   |     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_foo, multi_bar, multi_inner_mod}`
 
 error: usage of wildcard import
   --> tests/ui/wildcard_imports.rs:22:5
@@ -35,7 +35,7 @@ error: usage of wildcard import
   --> tests/ui/wildcard_imports.rs:29:5
    |
 LL | use wildcard_imports_helper::*;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_foo, ExternA}`
 
 error: usage of wildcard import
   --> tests/ui/wildcard_imports.rs:100:13
@@ -59,7 +59,7 @@ error: usage of wildcard import
   --> tests/ui/wildcard_imports.rs:141:13
    |
 LL |         use wildcard_imports_helper::*;
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_foo, ExternA}`
 
 error: usage of wildcard import
   --> tests/ui/wildcard_imports.rs:154:20
@@ -77,13 +77,13 @@ error: usage of wildcard import
   --> tests/ui/wildcard_imports.rs:163:13
    |
 LL |         use wildcard_imports_helper::*;
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_exported, ExternExportedStruct, ExternExportedEnum}`
 
 error: usage of wildcard import
   --> tests/ui/wildcard_imports.rs:193:9
    |
 LL |     use crate::in_fn_test::*;
-   |         ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}`
+   |         ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{exported, ExportedStruct, ExportedEnum}`
 
 error: usage of wildcard import
   --> tests/ui/wildcard_imports.rs:203:9
diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed
index a3d1aebba8a..f97b883ea23 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed
+++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed
@@ -14,7 +14,7 @@ use crate::fn_mod::foo;
 //~^ wildcard_imports
 use crate::mod_mod::inner_mod;
 //~^ wildcard_imports
-use crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod};
+use crate::multi_fn_mod::{multi_foo, multi_bar, multi_inner_mod};
 //~^ wildcard_imports
 use crate::struct_mod::{A, inner_struct_mod};
 //~^ wildcard_imports
@@ -23,7 +23,7 @@ use crate::struct_mod::{A, inner_struct_mod};
 use wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar;
 //~^ wildcard_imports
 use wildcard_imports_helper::prelude::v1::*;
-use wildcard_imports_helper::{ExternA, extern_foo};
+use wildcard_imports_helper::{extern_foo, ExternA};
 //~^ wildcard_imports
 
 use std::io::prelude::*;
@@ -132,7 +132,7 @@ mod in_fn_test {
     fn test_extern() {
         use wildcard_imports_helper::inner::inner_for_self_import::{self, inner_extern_foo};
         //~^ wildcard_imports
-        use wildcard_imports_helper::{ExternA, extern_foo};
+        use wildcard_imports_helper::{extern_foo, ExternA};
         //~^ wildcard_imports
 
         inner_for_self_import::inner_extern_foo();
@@ -154,7 +154,7 @@ mod in_fn_test {
     }
 
     fn test_extern_reexported() {
-        use wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported};
+        use wildcard_imports_helper::{extern_exported, ExternExportedStruct, ExternExportedEnum};
         //~^ wildcard_imports
 
         extern_exported();
@@ -184,7 +184,7 @@ mod in_fn_test {
 }
 
 fn test_reexported() {
-    use crate::in_fn_test::{ExportedEnum, ExportedStruct, exported};
+    use crate::in_fn_test::{exported, ExportedStruct, ExportedEnum};
     //~^ wildcard_imports
 
     exported();
diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr
index a1b557f39f0..873ce41b04f 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr
+++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr
@@ -17,7 +17,7 @@ error: usage of wildcard import
   --> tests/ui/wildcard_imports_2021.rs:17:5
    |
 LL | use crate::multi_fn_mod::*;
-   |     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}`
+   |     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_foo, multi_bar, multi_inner_mod}`
 
 error: usage of wildcard import
   --> tests/ui/wildcard_imports_2021.rs:19:5
@@ -35,7 +35,7 @@ error: usage of wildcard import
   --> tests/ui/wildcard_imports_2021.rs:26:5
    |
 LL | use wildcard_imports_helper::*;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_foo, ExternA}`
 
 error: usage of wildcard import
   --> tests/ui/wildcard_imports_2021.rs:95:13
@@ -59,7 +59,7 @@ error: usage of wildcard import
   --> tests/ui/wildcard_imports_2021.rs:135:13
    |
 LL |         use wildcard_imports_helper::*;
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_foo, ExternA}`
 
 error: usage of wildcard import
   --> tests/ui/wildcard_imports_2021.rs:148:20
@@ -77,13 +77,13 @@ error: usage of wildcard import
   --> tests/ui/wildcard_imports_2021.rs:157:13
    |
 LL |         use wildcard_imports_helper::*;
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_exported, ExternExportedStruct, ExternExportedEnum}`
 
 error: usage of wildcard import
   --> tests/ui/wildcard_imports_2021.rs:187:9
    |
 LL |     use crate::in_fn_test::*;
-   |         ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}`
+   |         ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{exported, ExportedStruct, ExportedEnum}`
 
 error: usage of wildcard import
   --> tests/ui/wildcard_imports_2021.rs:197:9
diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed
index a3d1aebba8a..f97b883ea23 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed
+++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed
@@ -14,7 +14,7 @@ use crate::fn_mod::foo;
 //~^ wildcard_imports
 use crate::mod_mod::inner_mod;
 //~^ wildcard_imports
-use crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod};
+use crate::multi_fn_mod::{multi_foo, multi_bar, multi_inner_mod};
 //~^ wildcard_imports
 use crate::struct_mod::{A, inner_struct_mod};
 //~^ wildcard_imports
@@ -23,7 +23,7 @@ use crate::struct_mod::{A, inner_struct_mod};
 use wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar;
 //~^ wildcard_imports
 use wildcard_imports_helper::prelude::v1::*;
-use wildcard_imports_helper::{ExternA, extern_foo};
+use wildcard_imports_helper::{extern_foo, ExternA};
 //~^ wildcard_imports
 
 use std::io::prelude::*;
@@ -132,7 +132,7 @@ mod in_fn_test {
     fn test_extern() {
         use wildcard_imports_helper::inner::inner_for_self_import::{self, inner_extern_foo};
         //~^ wildcard_imports
-        use wildcard_imports_helper::{ExternA, extern_foo};
+        use wildcard_imports_helper::{extern_foo, ExternA};
         //~^ wildcard_imports
 
         inner_for_self_import::inner_extern_foo();
@@ -154,7 +154,7 @@ mod in_fn_test {
     }
 
     fn test_extern_reexported() {
-        use wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported};
+        use wildcard_imports_helper::{extern_exported, ExternExportedStruct, ExternExportedEnum};
         //~^ wildcard_imports
 
         extern_exported();
@@ -184,7 +184,7 @@ mod in_fn_test {
 }
 
 fn test_reexported() {
-    use crate::in_fn_test::{ExportedEnum, ExportedStruct, exported};
+    use crate::in_fn_test::{exported, ExportedStruct, ExportedEnum};
     //~^ wildcard_imports
 
     exported();
diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr
index a1b557f39f0..873ce41b04f 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr
+++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr
@@ -17,7 +17,7 @@ error: usage of wildcard import
   --> tests/ui/wildcard_imports_2021.rs:17:5
    |
 LL | use crate::multi_fn_mod::*;
-   |     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}`
+   |     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_foo, multi_bar, multi_inner_mod}`
 
 error: usage of wildcard import
   --> tests/ui/wildcard_imports_2021.rs:19:5
@@ -35,7 +35,7 @@ error: usage of wildcard import
   --> tests/ui/wildcard_imports_2021.rs:26:5
    |
 LL | use wildcard_imports_helper::*;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_foo, ExternA}`
 
 error: usage of wildcard import
   --> tests/ui/wildcard_imports_2021.rs:95:13
@@ -59,7 +59,7 @@ error: usage of wildcard import
   --> tests/ui/wildcard_imports_2021.rs:135:13
    |
 LL |         use wildcard_imports_helper::*;
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_foo, ExternA}`
 
 error: usage of wildcard import
   --> tests/ui/wildcard_imports_2021.rs:148:20
@@ -77,13 +77,13 @@ error: usage of wildcard import
   --> tests/ui/wildcard_imports_2021.rs:157:13
    |
 LL |         use wildcard_imports_helper::*;
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_exported, ExternExportedStruct, ExternExportedEnum}`
 
 error: usage of wildcard import
   --> tests/ui/wildcard_imports_2021.rs:187:9
    |
 LL |     use crate::in_fn_test::*;
-   |         ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}`
+   |         ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{exported, ExportedStruct, ExportedEnum}`
 
 error: usage of wildcard import
   --> tests/ui/wildcard_imports_2021.rs:197:9
diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs
index 1449e9af19a..5757e422ae2 100644
--- a/src/tools/compiletest/src/directive-list.rs
+++ b/src/tools/compiletest/src/directive-list.rs
@@ -35,6 +35,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "ignore-32bit",
     "ignore-64bit",
     "ignore-aarch64",
+    "ignore-aarch64-pc-windows-msvc",
     "ignore-aarch64-unknown-linux-gnu",
     "ignore-aix",
     "ignore-android",
diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs
index a45f39b036c..b5a2b7feac9 100644
--- a/src/tools/compiletest/src/errors.rs
+++ b/src/tools/compiletest/src/errors.rs
@@ -15,6 +15,7 @@ pub enum ErrorKind {
     Note,
     Suggestion,
     Warning,
+    Raw,
 }
 
 impl ErrorKind {
@@ -39,6 +40,7 @@ impl ErrorKind {
             "NOTE" | "note" | "MONO_ITEM" => ErrorKind::Note,
             "SUGGESTION" => ErrorKind::Suggestion,
             "WARN" | "WARNING" | "warn" | "warning" => ErrorKind::Warning,
+            "RAW" => ErrorKind::Raw,
             _ => panic!(
                 "unexpected diagnostic kind `{s}`, expected \
                  `ERROR`, `WARN`, `NOTE`, `HELP` or `SUGGESTION`"
@@ -55,6 +57,7 @@ impl fmt::Display for ErrorKind {
             ErrorKind::Note => write!(f, "NOTE"),
             ErrorKind::Suggestion => write!(f, "SUGGESTION"),
             ErrorKind::Warning => write!(f, "WARN"),
+            ErrorKind::Raw => write!(f, "RAW"),
         }
     }
 }
diff --git a/src/tools/compiletest/src/json.rs b/src/tools/compiletest/src/json.rs
index 960f5ba5888..6ed2b52c66d 100644
--- a/src/tools/compiletest/src/json.rs
+++ b/src/tools/compiletest/src/json.rs
@@ -7,7 +7,6 @@ use regex::Regex;
 use serde::Deserialize;
 
 use crate::errors::{Error, ErrorKind};
-use crate::runtest::ProcRes;
 
 #[derive(Deserialize)]
 struct Diagnostic {
@@ -140,28 +139,19 @@ pub fn extract_rendered(output: &str) -> String {
         .collect()
 }
 
-pub fn parse_output(file_name: &str, output: &str, proc_res: &ProcRes) -> Vec<Error> {
+pub fn parse_output(file_name: &str, output: &str) -> Vec<Error> {
     let mut errors = Vec::new();
     for line in output.lines() {
-        // The compiler sometimes intermingles non-JSON stuff into the
-        // output.  This hack just skips over such lines. Yuck.
-        if line.starts_with('{') {
-            match serde_json::from_str::<Diagnostic>(line) {
-                Ok(diagnostic) => push_actual_errors(&mut errors, &diagnostic, &[], file_name),
-                Err(error) => {
-                    // Ignore the future compat report message - this is handled
-                    // by `extract_rendered`
-                    if serde_json::from_str::<FutureIncompatReport>(line).is_err() {
-                        proc_res.fatal(
-                        Some(&format!(
-                            "failed to decode compiler output as json: `{}`\nline: {}\noutput: {}",
-                            error, line, output
-                        )),
-                        || (),
-                    );
-                    }
-                }
-            }
+        // Compiler can emit non-json lines in non-`--error-format=json` modes,
+        // and in some situations even in json mode.
+        match serde_json::from_str::<Diagnostic>(line) {
+            Ok(diagnostic) => push_actual_errors(&mut errors, &diagnostic, &[], file_name),
+            Err(_) => errors.push(Error {
+                line_num: None,
+                kind: ErrorKind::Raw,
+                msg: line.to_string(),
+                require_annotation: false,
+            }),
         }
     }
     errors
@@ -181,8 +171,6 @@ fn push_actual_errors(
         .filter(|(_, span)| Path::new(&span.file_name) == Path::new(&file_name))
         .collect();
 
-    let spans_in_this_file: Vec<_> = spans_info_in_this_file.iter().map(|(_, span)| span).collect();
-
     let primary_spans: Vec<_> = spans_info_in_this_file
         .iter()
         .filter(|(is_primary, _)| *is_primary)
@@ -280,7 +268,9 @@ fn push_actual_errors(
                     line_num: Some(span.line_start + index),
                     kind: ErrorKind::Suggestion,
                     msg: line.to_string(),
-                    require_annotation: true,
+                    // Empty suggestions (suggestions to remove something) are common
+                    // and annotating them in source is not useful.
+                    require_annotation: !line.is_empty(),
                 });
             }
         }
@@ -294,13 +284,16 @@ fn push_actual_errors(
     }
 
     // Add notes for any labels that appear in the message.
-    for span in spans_in_this_file.iter().filter(|span| span.label.is_some()) {
-        errors.push(Error {
-            line_num: Some(span.line_start),
-            kind: ErrorKind::Note,
-            msg: span.label.clone().unwrap(),
-            require_annotation: true,
-        });
+    for (_, span) in spans_info_in_this_file {
+        if let Some(label) = &span.label {
+            errors.push(Error {
+                line_num: Some(span.line_start),
+                kind: ErrorKind::Note,
+                msg: label.clone(),
+                // Empty labels (only underlining spans) are common and do not need annotations.
+                require_annotation: !label.is_empty(),
+            });
+        }
     }
 
     // Flatten out the children.
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 97cb82c9e36..40c9f29375b 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -23,7 +23,7 @@ use crate::common::{
     output_base_dir, output_base_name, output_testname_unique,
 };
 use crate::compute_diff::{DiffLine, make_diff, write_diff, write_filtered_diff};
-use crate::errors::{Error, ErrorKind};
+use crate::errors::{Error, ErrorKind, load_errors};
 use crate::header::TestProps;
 use crate::read2::{Truncated, read2_abbreviated};
 use crate::util::{Utf8PathBufExt, add_dylib_path, logv, static_regex};
@@ -577,23 +577,9 @@ impl<'test> TestCx<'test> {
         }
     }
 
-    fn check_all_error_patterns(
-        &self,
-        output_to_check: &str,
-        proc_res: &ProcRes,
-        pm: Option<PassMode>,
-    ) {
-        if self.props.error_patterns.is_empty() && self.props.regex_error_patterns.is_empty() {
-            if pm.is_some() {
-                // FIXME(#65865)
-                return;
-            } else {
-                self.fatal(&format!("no error pattern specified in {}", self.testpaths.file));
-            }
-        }
-
+    /// Check `error-pattern` and `regex-error-pattern` directives.
+    fn check_all_error_patterns(&self, output_to_check: &str, proc_res: &ProcRes) {
         let mut missing_patterns: Vec<String> = Vec::new();
-
         self.check_error_patterns(output_to_check, &mut missing_patterns);
         self.check_regex_error_patterns(output_to_check, proc_res, &mut missing_patterns);
 
@@ -670,7 +656,9 @@ impl<'test> TestCx<'test> {
         }
     }
 
-    fn check_expected_errors(&self, expected_errors: Vec<Error>, proc_res: &ProcRes) {
+    /// Check `//~ KIND message` annotations.
+    fn check_expected_errors(&self, proc_res: &ProcRes) {
+        let expected_errors = load_errors(&self.testpaths.file, self.revision);
         debug!(
             "check_expected_errors: expected_errors={:?} proc_res.status={:?}",
             expected_errors, proc_res.status
@@ -711,11 +699,24 @@ impl<'test> TestCx<'test> {
             .collect();
 
         // Parse the JSON output from the compiler and extract out the messages.
-        let actual_errors = json::parse_output(&diagnostic_file_name, &proc_res.stderr, proc_res);
+        let actual_errors = json::parse_output(&diagnostic_file_name, &self.get_output(proc_res))
+            .into_iter()
+            .map(|e| Error { msg: self.normalize_output(&e.msg, &[]), ..e });
+
         let mut unexpected = Vec::new();
         let mut found = vec![false; expected_errors.len()];
-        for mut actual_error in actual_errors {
-            actual_error.msg = self.normalize_output(&actual_error.msg, &[]);
+        for actual_error in actual_errors {
+            for pattern in &self.props.error_patterns {
+                let pattern = pattern.trim();
+                if actual_error.msg.contains(pattern) {
+                    let q = if actual_error.line_num.is_none() { "?" } else { "" };
+                    self.fatal(&format!(
+                        "error pattern '{pattern}' is found in structured \
+                         diagnostics, use `//~{q} {} {pattern}` instead",
+                        actual_error.kind,
+                    ));
+                }
+            }
 
             let opt_index =
                 expected_errors.iter().enumerate().position(|(index, expected_error)| {
diff --git a/src/tools/compiletest/src/runtest/incremental.rs b/src/tools/compiletest/src/runtest/incremental.rs
index ea985866a05..90cff6bab4d 100644
--- a/src/tools/compiletest/src/runtest/incremental.rs
+++ b/src/tools/compiletest/src/runtest/incremental.rs
@@ -100,16 +100,8 @@ impl TestCx<'_> {
         self.check_no_compiler_crash(&proc_res, self.props.should_ice);
 
         let output_to_check = self.get_output(&proc_res);
-        let expected_errors = errors::load_errors(&self.testpaths.file, self.revision);
-        if !expected_errors.is_empty() {
-            if !self.props.error_patterns.is_empty() || !self.props.regex_error_patterns.is_empty()
-            {
-                self.fatal("both error pattern and expected errors specified");
-            }
-            self.check_expected_errors(expected_errors, &proc_res);
-        } else {
-            self.check_all_error_patterns(&output_to_check, &proc_res, pm);
-        }
+        self.check_expected_errors(&proc_res);
+        self.check_all_error_patterns(&output_to_check, &proc_res);
         if self.props.should_ice {
             match proc_res.status.code() {
                 Some(101) => (),
@@ -137,6 +129,6 @@ impl TestCx<'_> {
 
         let output_to_check = self.get_output(&proc_res);
         self.check_correct_failure_status(&proc_res);
-        self.check_all_error_patterns(&output_to_check, &proc_res, pm);
+        self.check_all_error_patterns(&output_to_check, &proc_res);
     }
 }
diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs
index cf0ae14f81b..cc50a918f75 100644
--- a/src/tools/compiletest/src/runtest/ui.rs
+++ b/src/tools/compiletest/src/runtest/ui.rs
@@ -9,7 +9,7 @@ use super::{
     AllowUnused, Emit, FailMode, LinkToAux, PassMode, TargetLocation, TestCx, TestOutput,
     Truncated, UI_FIXED, WillExecute,
 };
-use crate::{errors, json};
+use crate::json;
 
 impl TestCx<'_> {
     pub(super) fn run_ui_test(&self) {
@@ -127,9 +127,7 @@ impl TestCx<'_> {
             );
         }
 
-        let expected_errors = errors::load_errors(&self.testpaths.file, self.revision);
-
-        if let WillExecute::Yes = should_run {
+        let output_to_check = if let WillExecute::Yes = should_run {
             let proc_res = self.exec_compiled_test();
             let run_output_errors = if self.props.check_run_results {
                 self.load_compare_outputs(&proc_res, TestOutput::Run, explicit)
@@ -150,44 +148,19 @@ impl TestCx<'_> {
                 self.fatal_proc_rec("test run succeeded!", &proc_res);
             }
 
-            let output_to_check = self.get_output(&proc_res);
-            if !self.props.error_patterns.is_empty() || !self.props.regex_error_patterns.is_empty()
-            {
-                // "// error-pattern" comments
-                self.check_all_error_patterns(&output_to_check, &proc_res, pm);
-            }
-            self.check_forbid_output(&output_to_check, &proc_res)
-        }
+            self.get_output(&proc_res)
+        } else {
+            self.get_output(&proc_res)
+        };
 
         debug!(
-            "run_ui_test: explicit={:?} config.compare_mode={:?} expected_errors={:?} \
+            "run_ui_test: explicit={:?} config.compare_mode={:?} \
                proc_res.status={:?} props.error_patterns={:?}",
-            explicit,
-            self.config.compare_mode,
-            expected_errors,
-            proc_res.status,
-            self.props.error_patterns
+            explicit, self.config.compare_mode, proc_res.status, self.props.error_patterns
         );
 
-        if !explicit && self.config.compare_mode.is_none() {
-            // "//~ERROR comments"
-            self.check_expected_errors(expected_errors, &proc_res);
-        } else if explicit && !expected_errors.is_empty() {
-            let msg = format!(
-                "line {}: cannot combine `--error-format` with {} annotations; use `error-pattern` instead",
-                expected_errors[0].line_num_str(),
-                expected_errors[0].kind,
-            );
-            self.fatal(&msg);
-        }
-        let output_to_check = self.get_output(&proc_res);
-        if should_run == WillExecute::No
-            && (!self.props.error_patterns.is_empty()
-                || !self.props.regex_error_patterns.is_empty())
-        {
-            // "// error-pattern" comments
-            self.check_all_error_patterns(&output_to_check, &proc_res, pm);
-        }
+        self.check_expected_errors(&proc_res);
+        self.check_all_error_patterns(&output_to_check, &proc_res);
         self.check_forbid_output(&output_to_check, &proc_res);
 
         if self.props.run_rustfix && self.config.compare_mode.is_none() {
diff --git a/src/tools/coverage-dump/Cargo.toml b/src/tools/coverage-dump/Cargo.toml
index 7f14286b5d0..6f92ac50d96 100644
--- a/src/tools/coverage-dump/Cargo.toml
+++ b/src/tools/coverage-dump/Cargo.toml
@@ -7,6 +7,7 @@ edition = "2021"
 
 [dependencies]
 anyhow = "1.0.71"
+itertools = "0.12"
 leb128 = "0.2.5"
 md5 = { package = "md-5" , version = "0.10.5" }
 miniz_oxide = "0.7.1"
diff --git a/src/tools/coverage-dump/src/covfun.rs b/src/tools/coverage-dump/src/covfun.rs
index 82ebd33d0d1..1cc9f4dc5d6 100644
--- a/src/tools/coverage-dump/src/covfun.rs
+++ b/src/tools/coverage-dump/src/covfun.rs
@@ -1,23 +1,33 @@
 use std::collections::HashMap;
 use std::fmt::{self, Debug, Write as _};
-use std::sync::OnceLock;
+use std::sync::LazyLock;
 
-use anyhow::{Context, anyhow};
+use anyhow::{Context, anyhow, bail, ensure};
+use itertools::Itertools;
 use regex::Regex;
 
-use crate::parser::{Parser, unescape_llvm_string_contents};
+use crate::covmap::FilenameTables;
+use crate::llvm_utils::unescape_llvm_string_contents;
+use crate::parser::Parser;
+
+#[cfg(test)]
+mod tests;
 
 pub(crate) fn dump_covfun_mappings(
     llvm_ir: &str,
+    filename_tables: &FilenameTables,
     function_names: &HashMap<u64, String>,
 ) -> anyhow::Result<()> {
     // Extract function coverage entries from the LLVM IR assembly, and associate
     // each entry with its (demangled) name.
     let mut covfun_entries = llvm_ir
         .lines()
-        .filter_map(covfun_line_data)
-        .map(|line_data| (function_names.get(&line_data.name_hash).map(String::as_str), line_data))
-        .collect::<Vec<_>>();
+        .filter(|line| is_covfun_line(line))
+        .map(parse_covfun_line)
+        .map_ok(|line_data| {
+            (function_names.get(&line_data.name_hash).map(String::as_str), line_data)
+        })
+        .collect::<Result<Vec<_>, _>>()?;
     covfun_entries.sort_by(|a, b| {
         // Sort entries primarily by name, to help make the order consistent
         // across platforms and relatively insensitive to changes.
@@ -41,8 +51,12 @@ pub(crate) fn dump_covfun_mappings(
         println!("Number of files: {num_files}");
 
         for i in 0..num_files {
-            let global_file_id = parser.read_uleb128_u32()?;
-            println!("- file {i} => global file {global_file_id}");
+            let global_file_id = parser.read_uleb128_usize()?;
+            let &CovfunLineData { filenames_hash, .. } = line_data;
+            let Some(filename) = filename_tables.lookup(filenames_hash, global_file_id) else {
+                bail!("couldn't resolve global file: {filenames_hash}, {global_file_id}");
+            };
+            println!("- file {i} => {filename}");
         }
 
         let num_expressions = parser.read_uleb128_u32()?;
@@ -107,36 +121,50 @@ pub(crate) fn dump_covfun_mappings(
     Ok(())
 }
 
+#[derive(Debug, PartialEq, Eq)]
 struct CovfunLineData {
-    name_hash: u64,
     is_used: bool,
+    name_hash: u64,
+    filenames_hash: u64,
     payload: Vec<u8>,
 }
 
-/// Checks a line of LLVM IR assembly to see if it contains an `__llvm_covfun`
-/// entry, and if so extracts relevant data in a `CovfunLineData`.
-fn covfun_line_data(line: &str) -> Option<CovfunLineData> {
-    let re = {
-        // We cheat a little bit and match variable names `@__covrec_[HASH]u`
-        // rather than the section name, because the section name is harder to
-        // extract and differs across Linux/Windows/macOS. We also extract the
-        // symbol name hash from the variable name rather than the data, since
-        // it's easier and both should match.
-        static RE: OnceLock<Regex> = OnceLock::new();
-        RE.get_or_init(|| {
-            Regex::new(
-                r#"^@__covrec_(?<name_hash>[0-9A-Z]+)(?<is_used>u)? = .*\[[0-9]+ x i8\] c"(?<payload>[^"]*)".*$"#,
-            )
-            .unwrap()
-        })
-    };
+fn is_covfun_line(line: &str) -> bool {
+    line.starts_with("@__covrec_")
+}
 
-    let captures = re.captures(line)?;
-    let name_hash = u64::from_str_radix(&captures["name_hash"], 16).unwrap();
+/// Given a line of LLVM IR assembly that should contain an `__llvm_covfun`
+/// entry, parses it to extract relevant data in a `CovfunLineData`.
+fn parse_covfun_line(line: &str) -> anyhow::Result<CovfunLineData> {
+    ensure!(is_covfun_line(line));
+
+    // We cheat a little bit and match variable names `@__covrec_[HASH]u`
+    // rather than the section name, because the section name is harder to
+    // extract and differs across Linux/Windows/macOS.
+    const RE_STRING: &str = r#"(?x)^
+        @__covrec_[0-9A-Z]+(?<is_used>u)?
+        \ = \ # (trailing space)
+        .*
+        <\{
+            \ i64 \ (?<name_hash> -? [0-9]+),
+            \ i32 \ -? [0-9]+, # (length of payload; currently unused)
+            \ i64 \ -? [0-9]+, # (source hash; currently unused)
+            \ i64 \ (?<filenames_hash> -? [0-9]+),
+            \ \[ [0-9]+ \ x \ i8 \] \ c"(?<payload>[^"]*)"
+            \ # (trailing space)
+        }>
+        .*$
+    "#;
+    static RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(RE_STRING).unwrap());
+
+    let captures =
+        RE.captures(line).with_context(|| format!("couldn't parse covfun line: {line:?}"))?;
     let is_used = captures.name("is_used").is_some();
+    let name_hash = i64::from_str_radix(&captures["name_hash"], 10).unwrap() as u64;
+    let filenames_hash = i64::from_str_radix(&captures["filenames_hash"], 10).unwrap() as u64;
     let payload = unescape_llvm_string_contents(&captures["payload"]);
 
-    Some(CovfunLineData { name_hash, is_used, payload })
+    Ok(CovfunLineData { is_used, name_hash, filenames_hash, payload })
 }
 
 // Extra parser methods only needed when parsing `covfun` payloads.
diff --git a/src/tools/coverage-dump/src/covfun/tests.rs b/src/tools/coverage-dump/src/covfun/tests.rs
new file mode 100644
index 00000000000..1ce833784bd
--- /dev/null
+++ b/src/tools/coverage-dump/src/covfun/tests.rs
@@ -0,0 +1,53 @@
+use super::{CovfunLineData, parse_covfun_line};
+
+/// Integers in LLVM IR are not inherently signed/unsigned, and the text format tends
+/// to emit them in signed form, so this helper function converts `i64` to `u64`.
+fn as_u64(x: i64) -> u64 {
+    x as u64
+}
+
+#[test]
+fn parse_covfun_line_data() {
+    struct Case {
+        line: &'static str,
+        expected: CovfunLineData,
+    }
+    let cases = &[
+        // Copied from `trivial.ll`:
+        Case {
+            line: r#"@__covrec_49A9BAAE5F896E81u = linkonce_odr hidden constant <{ i64, i32, i64, i64, [9 x i8] }> <{ i64 5307978893922758273, i32 9, i64 445092354169400020, i64 6343436898695299756, [9 x i8] c"\01\01\00\01\01\03\01\00\0D" }>, section "__LLVM_COV,__llvm_covfun", align 8"#,
+            expected: CovfunLineData {
+                is_used: true,
+                name_hash: as_u64(5307978893922758273),
+                filenames_hash: as_u64(6343436898695299756),
+                payload: b"\x01\x01\x00\x01\x01\x03\x01\x00\x0D".to_vec(),
+            },
+        },
+        // Copied from `on-off-sandwich.ll`:
+        Case {
+            line: r#"@__covrec_D0CE53C5E64F319Au = linkonce_odr hidden constant <{ i64, i32, i64, i64, [14 x i8] }> <{ i64 -3400688559180533350, i32 14, i64 7307957714577672185, i64 892196767019953100, [14 x i8] c"\01\01\00\02\01\10\05\02\10\01\07\05\00\06" }>, section "__LLVM_COV,__llvm_covfun", align 8"#,
+            expected: CovfunLineData {
+                is_used: true,
+                name_hash: as_u64(-3400688559180533350),
+                filenames_hash: as_u64(892196767019953100),
+                payload: b"\x01\x01\x00\x02\x01\x10\x05\x02\x10\x01\x07\x05\x00\x06".to_vec(),
+            },
+        },
+        // Copied from `no-core.ll`:
+        Case {
+            line: r#"@__covrec_F8016FC82D46106u = linkonce_odr hidden constant <{ i64, i32, i64, i64, [9 x i8] }> <{ i64 1116917981370409222, i32 9, i64 -8857254680411629915, i64 -3625186110715410276, [9 x i8] c"\01\01\00\01\01\0C\01\00\0D" }>, section "__LLVM_COV,__llvm_covfun", align 8"#,
+            expected: CovfunLineData {
+                is_used: true,
+                name_hash: as_u64(1116917981370409222),
+                filenames_hash: as_u64(-3625186110715410276),
+                payload: b"\x01\x01\x00\x01\x01\x0C\x01\x00\x0D".to_vec(),
+            },
+        },
+    ];
+
+    for &Case { line, ref expected } in cases {
+        println!("- {line}");
+        let line_data = parse_covfun_line(line).map_err(|e| e.to_string());
+        assert_eq!(line_data.as_ref(), Ok(expected));
+    }
+}
diff --git a/src/tools/coverage-dump/src/covmap.rs b/src/tools/coverage-dump/src/covmap.rs
new file mode 100644
index 00000000000..2246ca2d575
--- /dev/null
+++ b/src/tools/coverage-dump/src/covmap.rs
@@ -0,0 +1,75 @@
+use std::collections::HashMap;
+use std::sync::LazyLock;
+
+use anyhow::{Context, ensure};
+use regex::Regex;
+
+use crate::llvm_utils::{truncated_md5, unescape_llvm_string_contents};
+use crate::parser::Parser;
+
+#[derive(Debug, Default)]
+pub(crate) struct FilenameTables {
+    map: HashMap<u64, Vec<String>>,
+}
+
+impl FilenameTables {
+    pub(crate) fn lookup(&self, filenames_hash: u64, global_file_id: usize) -> Option<&str> {
+        let table = self.map.get(&filenames_hash)?;
+        let filename = table.get(global_file_id)?;
+        Some(filename)
+    }
+}
+
+struct CovmapLineData {
+    payload: Vec<u8>,
+}
+
+pub(crate) fn make_filename_tables(llvm_ir: &str) -> anyhow::Result<FilenameTables> {
+    let mut map = HashMap::default();
+
+    for line in llvm_ir.lines().filter(|line| is_covmap_line(line)) {
+        let CovmapLineData { payload } = parse_covmap_line(line)?;
+
+        let mut parser = Parser::new(&payload);
+        let n_filenames = parser.read_uleb128_usize()?;
+        let uncompressed_bytes = parser.read_chunk_to_uncompressed_bytes()?;
+        parser.ensure_empty()?;
+
+        let mut filenames_table = vec![];
+
+        let mut parser = Parser::new(&uncompressed_bytes);
+        for _ in 0..n_filenames {
+            let len = parser.read_uleb128_usize()?;
+            let bytes = parser.read_n_bytes(len)?;
+            let filename = str::from_utf8(bytes)?;
+            filenames_table.push(filename.to_owned());
+        }
+
+        let filenames_hash = truncated_md5(&payload);
+        map.insert(filenames_hash, filenames_table);
+    }
+
+    Ok(FilenameTables { map })
+}
+
+fn is_covmap_line(line: &str) -> bool {
+    line.starts_with("@__llvm_coverage_mapping ")
+}
+
+fn parse_covmap_line(line: &str) -> anyhow::Result<CovmapLineData> {
+    ensure!(is_covmap_line(line));
+
+    const RE_STRING: &str = r#"(?x)^
+        @__llvm_coverage_mapping \ =
+        .*
+        \[ [0-9]+ \ x \ i8 \] \ c"(?<payload>[^"]*)"
+        .*$
+    "#;
+    static RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(RE_STRING).unwrap());
+
+    let captures =
+        RE.captures(line).with_context(|| format!("couldn't parse covmap line: {line:?}"))?;
+    let payload = unescape_llvm_string_contents(&captures["payload"]);
+
+    Ok(CovmapLineData { payload })
+}
diff --git a/src/tools/coverage-dump/src/llvm_utils.rs b/src/tools/coverage-dump/src/llvm_utils.rs
new file mode 100644
index 00000000000..92322b256a8
--- /dev/null
+++ b/src/tools/coverage-dump/src/llvm_utils.rs
@@ -0,0 +1,85 @@
+use std::borrow::Cow;
+use std::sync::OnceLock;
+
+use anyhow::{anyhow, ensure};
+use regex::bytes;
+
+use crate::parser::Parser;
+
+#[cfg(test)]
+mod tests;
+
+/// Given the raw contents of a string literal in LLVM IR assembly, decodes any
+/// backslash escapes and returns a vector containing the resulting byte string.
+pub(crate) fn unescape_llvm_string_contents(contents: &str) -> Vec<u8> {
+    let escape_re = {
+        static RE: OnceLock<bytes::Regex> = OnceLock::new();
+        // LLVM IR supports two string escapes: `\\` and `\xx`.
+        RE.get_or_init(|| bytes::Regex::new(r"\\\\|\\([0-9A-Za-z]{2})").unwrap())
+    };
+
+    fn u8_from_hex_digits(digits: &[u8]) -> u8 {
+        // We know that the input contains exactly 2 hex digits, so these calls
+        // should never fail.
+        assert_eq!(digits.len(), 2);
+        let digits = std::str::from_utf8(digits).unwrap();
+        u8::from_str_radix(digits, 16).unwrap()
+    }
+
+    escape_re
+        .replace_all(contents.as_bytes(), |captures: &bytes::Captures<'_>| {
+            let byte = match captures.get(1) {
+                None => b'\\',
+                Some(hex_digits) => u8_from_hex_digits(hex_digits.as_bytes()),
+            };
+            [byte]
+        })
+        .into_owned()
+}
+
+/// LLVM's profiler/coverage metadata often uses an MD5 hash truncated to
+/// 64 bits as a way to associate data stored in different tables/sections.
+pub(crate) fn truncated_md5(bytes: &[u8]) -> u64 {
+    use md5::{Digest, Md5};
+    let mut hasher = Md5::new();
+    hasher.update(bytes);
+    let hash: [u8; 8] = hasher.finalize().as_slice()[..8].try_into().unwrap();
+    // The truncated hash is explicitly little-endian, regardless of host
+    // or target platform. (See `MD5Result::low` in LLVM's `MD5.h`.)
+    u64::from_le_bytes(hash)
+}
+
+impl<'a> Parser<'a> {
+    /// Reads a sequence of:
+    /// - Length of uncompressed data in bytes, as ULEB128
+    /// - Length of compressed data in bytes (or 0), as ULEB128
+    /// - The indicated number of compressed or uncompressed bytes
+    ///
+    /// If the number of compressed bytes is 0, the subsequent bytes are
+    /// uncompressed. Otherwise, the subsequent bytes are compressed, and will
+    /// be decompressed.
+    ///
+    /// Returns the uncompressed bytes that were read directly or decompressed.
+    pub(crate) fn read_chunk_to_uncompressed_bytes(&mut self) -> anyhow::Result<Cow<'a, [u8]>> {
+        let uncompressed_len = self.read_uleb128_usize()?;
+        let compressed_len = self.read_uleb128_usize()?;
+
+        if compressed_len == 0 {
+            // The bytes are uncompressed, so read them directly.
+            let uncompressed_bytes = self.read_n_bytes(uncompressed_len)?;
+            Ok(Cow::Borrowed(uncompressed_bytes))
+        } else {
+            // The bytes are compressed, so read and decompress them.
+            let compressed_bytes = self.read_n_bytes(compressed_len)?;
+
+            let uncompressed_bytes = miniz_oxide::inflate::decompress_to_vec_zlib_with_limit(
+                compressed_bytes,
+                uncompressed_len,
+            )
+            .map_err(|e| anyhow!("{e:?}"))?;
+            ensure!(uncompressed_bytes.len() == uncompressed_len);
+
+            Ok(Cow::Owned(uncompressed_bytes))
+        }
+    }
+}
diff --git a/src/tools/coverage-dump/src/parser/tests.rs b/src/tools/coverage-dump/src/llvm_utils/tests.rs
index a673606b9c4..506b0a6200b 100644
--- a/src/tools/coverage-dump/src/parser/tests.rs
+++ b/src/tools/coverage-dump/src/llvm_utils/tests.rs
@@ -1,9 +1,5 @@
 use super::unescape_llvm_string_contents;
 
-// WARNING: These tests don't necessarily run in CI, and were mainly used to
-// help track down problems when originally developing this tool.
-// (The tool is still tested indirectly by snapshot tests that rely on it.)
-
 // Tests for `unescape_llvm_string_contents`:
 
 #[test]
diff --git a/src/tools/coverage-dump/src/main.rs b/src/tools/coverage-dump/src/main.rs
index b21e3e292f2..2c76d2f2460 100644
--- a/src/tools/coverage-dump/src/main.rs
+++ b/src/tools/coverage-dump/src/main.rs
@@ -1,4 +1,6 @@
 mod covfun;
+mod covmap;
+mod llvm_utils;
 mod parser;
 mod prf_names;
 
@@ -17,8 +19,9 @@ fn main() -> anyhow::Result<()> {
     let llvm_ir_path = args.get(1).context("LLVM IR file not specified")?;
     let llvm_ir = std::fs::read_to_string(llvm_ir_path).context("couldn't read LLVM IR file")?;
 
+    let filename_tables = covmap::make_filename_tables(&llvm_ir)?;
     let function_names = crate::prf_names::make_function_names_table(&llvm_ir)?;
-    crate::covfun::dump_covfun_mappings(&llvm_ir, &function_names)?;
+    crate::covfun::dump_covfun_mappings(&llvm_ir, &filename_tables, &function_names)?;
 
     Ok(())
 }
diff --git a/src/tools/coverage-dump/src/parser.rs b/src/tools/coverage-dump/src/parser.rs
index 0bd4abdae3e..f26a57b43b3 100644
--- a/src/tools/coverage-dump/src/parser.rs
+++ b/src/tools/coverage-dump/src/parser.rs
@@ -1,38 +1,4 @@
-#[cfg(test)]
-mod tests;
-
-use std::sync::OnceLock;
-
 use anyhow::ensure;
-use regex::bytes;
-
-/// Given the raw contents of a string literal in LLVM IR assembly, decodes any
-/// backslash escapes and returns a vector containing the resulting byte string.
-pub(crate) fn unescape_llvm_string_contents(contents: &str) -> Vec<u8> {
-    let escape_re = {
-        static RE: OnceLock<bytes::Regex> = OnceLock::new();
-        // LLVM IR supports two string escapes: `\\` and `\xx`.
-        RE.get_or_init(|| bytes::Regex::new(r"\\\\|\\([0-9A-Za-z]{2})").unwrap())
-    };
-
-    fn u8_from_hex_digits(digits: &[u8]) -> u8 {
-        // We know that the input contains exactly 2 hex digits, so these calls
-        // should never fail.
-        assert_eq!(digits.len(), 2);
-        let digits = std::str::from_utf8(digits).unwrap();
-        u8::from_str_radix(digits, 16).unwrap()
-    }
-
-    escape_re
-        .replace_all(contents.as_bytes(), |captures: &bytes::Captures<'_>| {
-            let byte = match captures.get(1) {
-                None => b'\\',
-                Some(hex_digits) => u8_from_hex_digits(hex_digits.as_bytes()),
-            };
-            [byte]
-        })
-        .into_owned()
-}
 
 pub(crate) struct Parser<'a> {
     rest: &'a [u8],
diff --git a/src/tools/coverage-dump/src/prf_names.rs b/src/tools/coverage-dump/src/prf_names.rs
index 96d097c79a3..f9ab35deba5 100644
--- a/src/tools/coverage-dump/src/prf_names.rs
+++ b/src/tools/coverage-dump/src/prf_names.rs
@@ -1,10 +1,10 @@
 use std::collections::HashMap;
 use std::sync::OnceLock;
 
-use anyhow::{anyhow, ensure};
 use regex::Regex;
 
-use crate::parser::{Parser, unescape_llvm_string_contents};
+use crate::llvm_utils::{truncated_md5, unescape_llvm_string_contents};
+use crate::parser::Parser;
 
 /// Scans through the contents of an LLVM IR assembly file to find `__llvm_prf_names`
 /// entries, decodes them, and creates a table that maps name hash values to
@@ -25,18 +25,6 @@ pub(crate) fn make_function_names_table(llvm_ir: &str) -> anyhow::Result<HashMap
         Some(payload)
     }
 
-    /// LLVM's profiler/coverage metadata often uses an MD5 hash truncated to
-    /// 64 bits as a way to associate data stored in different tables/sections.
-    fn truncated_md5(bytes: &[u8]) -> u64 {
-        use md5::{Digest, Md5};
-        let mut hasher = Md5::new();
-        hasher.update(bytes);
-        let hash: [u8; 8] = hasher.finalize().as_slice()[..8].try_into().unwrap();
-        // The truncated hash is explicitly little-endian, regardless of host
-        // or target platform. (See `MD5Result::low` in LLVM's `MD5.h`.)
-        u64::from_le_bytes(hash)
-    }
-
     fn demangle_if_able(symbol_name_bytes: &[u8]) -> anyhow::Result<String> {
         // In practice, raw symbol names should always be ASCII.
         let symbol_name_str = std::str::from_utf8(symbol_name_bytes)?;
@@ -54,26 +42,8 @@ pub(crate) fn make_function_names_table(llvm_ir: &str) -> anyhow::Result<HashMap
     for payload in llvm_ir.lines().filter_map(prf_names_payload).map(unescape_llvm_string_contents)
     {
         let mut parser = Parser::new(&payload);
-        let uncompressed_len = parser.read_uleb128_usize()?;
-        let compressed_len = parser.read_uleb128_usize()?;
-
-        let uncompressed_bytes_vec;
-        let uncompressed_bytes: &[u8] = if compressed_len == 0 {
-            // The symbol name bytes are uncompressed, so read them directly.
-            parser.read_n_bytes(uncompressed_len)?
-        } else {
-            // The symbol name bytes are compressed, so read and decompress them.
-            let compressed_bytes = parser.read_n_bytes(compressed_len)?;
-
-            uncompressed_bytes_vec = miniz_oxide::inflate::decompress_to_vec_zlib_with_limit(
-                compressed_bytes,
-                uncompressed_len,
-            )
-            .map_err(|e| anyhow!("{e:?}"))?;
-            ensure!(uncompressed_bytes_vec.len() == uncompressed_len);
-
-            &uncompressed_bytes_vec
-        };
+        let uncompressed_bytes = parser.read_chunk_to_uncompressed_bytes()?;
+        parser.ensure_empty()?;
 
         // Symbol names in the payload are separated by `0x01` bytes.
         for raw_name in uncompressed_bytes.split(|&b| b == 0x01) {
@@ -81,8 +51,6 @@ pub(crate) fn make_function_names_table(llvm_ir: &str) -> anyhow::Result<HashMap
             let demangled = demangle_if_able(raw_name)?;
             map.insert(hash, demangled);
         }
-
-        parser.ensure_empty()?;
     }
 
     Ok(map)
diff --git a/src/tools/features-status-dump/Cargo.toml b/src/tools/features-status-dump/Cargo.toml
index 35be71a46e5..b2976f14a01 100644
--- a/src/tools/features-status-dump/Cargo.toml
+++ b/src/tools/features-status-dump/Cargo.toml
@@ -5,7 +5,7 @@ license = "MIT OR Apache-2.0"
 edition = "2021"
 
 [dependencies]
-anyhow = { version = "1", features = ["backtrace"] }
+anyhow = { version = "1" }
 clap = { version = "4", features = ["derive"] }
 serde = { version = "1.0.125", features = [ "derive" ] }
 serde_json = "1.0.59"
diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs
index d6c69d39e17..cacce01675f 100644
--- a/src/tools/lint-docs/src/lib.rs
+++ b/src/tools/lint-docs/src/lib.rs
@@ -312,6 +312,7 @@ impl<'a> LintExtractor<'a> {
         if matches!(
             lint.name.as_str(),
             "unused_features" // broken lint
+            | "soft_unstable" // cannot have a stable example
         ) {
             return Ok(());
         }
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 97bc826b57a..9afbd3aa635 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-2ad5f8607d0e192b60b130e5cc416b477b351c18
+fd9fad6dbcc1bae3cba2a8634339ffa620a49f28
diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs
index 7aaf9c2624f..731d8b57763 100644
--- a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs
+++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs
@@ -1,5 +1,6 @@
 // We're testing x86 target specific features
 //@only-target: x86_64 i686
+#![allow(unnecessary_transmutes)]
 
 #[cfg(target_arch = "x86")]
 use std::arch::x86::*;
diff --git a/src/tools/opt-dist/Cargo.toml b/src/tools/opt-dist/Cargo.toml
index cea234cc74c..dfa884bc3f7 100644
--- a/src/tools/opt-dist/Cargo.toml
+++ b/src/tools/opt-dist/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "opt-dist"
 version = "0.1.0"
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 build_helper = { path = "../../build_helper" }
@@ -10,12 +10,11 @@ log = "0.4"
 anyhow = "1"
 humantime = "2"
 humansize = "2"
-sysinfo = { version = "0.31.2", default-features = false, features = ["disk"] }
+sysinfo = { version = "0.35.0", default-features = false, features = ["disk"] }
 fs_extra = "1"
 camino = "1"
 tar = "0.4"
 xz = { version = "0.1", package = "xz2" }
-serde = { version = "1", features = ["derive"] }
 serde_json = "1"
 glob = "0.3"
 tempfile = "3.5"
diff --git a/src/tools/opt-dist/src/environment.rs b/src/tools/opt-dist/src/environment.rs
index 9342d164be4..946e926a3c0 100644
--- a/src/tools/opt-dist/src/environment.rs
+++ b/src/tools/opt-dist/src/environment.rs
@@ -26,6 +26,7 @@ pub struct Environment {
     use_bolt: bool,
     shared_llvm: bool,
     run_tests: bool,
+    fast_try_build: bool,
 }
 
 impl Environment {
@@ -106,6 +107,10 @@ impl Environment {
     pub fn run_tests(&self) -> bool {
         self.run_tests
     }
+
+    pub fn is_fast_try_build(&self) -> bool {
+        self.fast_try_build
+    }
 }
 
 /// What is the extension of binary executables on this platform?
diff --git a/src/tools/opt-dist/src/exec.rs b/src/tools/opt-dist/src/exec.rs
index deff69a7f9c..64ce5cc3775 100644
--- a/src/tools/opt-dist/src/exec.rs
+++ b/src/tools/opt-dist/src/exec.rs
@@ -113,13 +113,16 @@ impl Bootstrap {
             "library/std",
         ])
         .env("RUST_BACKTRACE", "full");
+        let cmd = add_shared_x_flags(env, cmd);
+
         Self { cmd, metrics_path }
     }
 
     pub fn dist(env: &Environment, dist_args: &[String]) -> Self {
         let metrics_path = env.build_root().join("build").join("metrics.json");
-        let cmd = cmd(&dist_args.iter().map(|arg| arg.as_str()).collect::<Vec<_>>())
-            .env("RUST_BACKTRACE", "full");
+        let args = dist_args.iter().map(|arg| arg.as_str()).collect::<Vec<_>>();
+        let cmd = cmd(&args).env("RUST_BACKTRACE", "full");
+        let cmd = add_shared_x_flags(env, cmd);
         Self { cmd, metrics_path }
     }
 
@@ -184,3 +187,7 @@ impl Bootstrap {
         Ok(())
     }
 }
+
+fn add_shared_x_flags(env: &Environment, cmd: CmdBuilder) -> CmdBuilder {
+    if env.is_fast_try_build() { cmd.arg("--set").arg("rust.deny-warnings=false") } else { cmd }
+}
diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs
index d5e6640fb43..d2827ec01ca 100644
--- a/src/tools/opt-dist/src/main.rs
+++ b/src/tools/opt-dist/src/main.rs
@@ -95,7 +95,7 @@ enum EnvironmentCmd {
         #[arg(long)]
         benchmark_cargo_config: Vec<String>,
 
-        /// Perform tests after final build if it's not a try build
+        /// Perform tests after final build if it's not a fast try build
         #[arg(long)]
         run_tests: bool,
     },
@@ -111,11 +111,14 @@ enum EnvironmentCmd {
     },
 }
 
-fn is_try_build() -> bool {
+/// For a fast try build, we want to only build the bare minimum of components to get a
+/// working toolchain, and not run any tests.
+fn is_fast_try_build() -> bool {
     std::env::var("DIST_TRY_BUILD").unwrap_or_else(|_| "0".to_string()) != "0"
 }
 
 fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)> {
+    let is_fast_try_build = is_fast_try_build();
     let (env, args) = match args.env {
         EnvironmentCmd::Local {
             target_triple,
@@ -144,6 +147,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
                 .skipped_tests(skipped_tests)
                 .benchmark_cargo_config(benchmark_cargo_config)
                 .run_tests(run_tests)
+                .fast_try_build(is_fast_try_build)
                 .build()?;
 
             (env, shared.build_args)
@@ -167,6 +171,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
                 .use_bolt(!is_aarch64)
                 .skipped_tests(vec![])
                 .run_tests(true)
+                .fast_try_build(is_fast_try_build)
                 .build()?;
 
             (env, shared.build_args)
@@ -187,6 +192,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
                 .use_bolt(false)
                 .skipped_tests(vec![])
                 .run_tests(true)
+                .fast_try_build(is_fast_try_build)
                 .build()?;
 
             (env, shared.build_args)
@@ -350,9 +356,8 @@ fn execute_pipeline(
 
     // After dist has finished, run a subset of the test suite on the optimized artifacts to discover
     // possible regressions.
-    // The tests are not executed for try builds, which can be in various broken states, so we don't
-    // want to gatekeep them with tests.
-    if !is_try_build() && env.run_tests() {
+    // The tests are not executed for fast try builds, which can be broken and might not pass them.
+    if !is_fast_try_build() && env.run_tests() {
         timer.section("Run tests", |_| run_tests(env))?;
     }
 
@@ -361,7 +366,10 @@ fn execute_pipeline(
 
 fn main() -> anyhow::Result<()> {
     // Make sure that we get backtraces for easier debugging in CI
-    std::env::set_var("RUST_BACKTRACE", "1");
+    unsafe {
+        // SAFETY: we are the only thread running at this point
+        std::env::set_var("RUST_BACKTRACE", "1");
+    }
 
     env_logger::builder()
         .filter_level(LevelFilter::Info)
@@ -393,9 +401,9 @@ fn main() -> anyhow::Result<()> {
 
     let (env, mut build_args) = create_environment(args).context("Cannot create environment")?;
 
-    // Skip components that are not needed for try builds to speed them up
-    if is_try_build() {
-        log::info!("Skipping building of unimportant components for a try build");
+    // Skip components that are not needed for fast try builds to speed them up
+    if is_fast_try_build() {
+        log::info!("Skipping building of unimportant components for a fast try build");
         for target in [
             "rust-docs",
             "rustc-docs",
diff --git a/src/tools/run-make-support/src/external_deps/cargo.rs b/src/tools/run-make-support/src/external_deps/cargo.rs
index e91d101cb99..8da9f002c41 100644
--- a/src/tools/run-make-support/src/external_deps/cargo.rs
+++ b/src/tools/run-make-support/src/external_deps/cargo.rs
@@ -1,8 +1,11 @@
 use crate::command::Command;
 use crate::env_var;
+use crate::util::set_host_compiler_dylib_path;
 
 /// Returns a command that can be used to invoke cargo. The cargo is provided by compiletest
 /// through the `CARGO` env var.
 pub fn cargo() -> Command {
-    Command::new(env_var("CARGO"))
+    let mut cmd = Command::new(env_var("CARGO"));
+    set_host_compiler_dylib_path(&mut cmd);
+    cmd
 }
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index 9f6b80c6379..8d6c8284e44 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -85,6 +85,7 @@ dependencies = [
  "query-group-macro",
  "rustc-hash 2.1.1",
  "salsa",
+ "salsa-macros",
  "semver",
  "span",
  "syntax",
@@ -630,6 +631,7 @@ dependencies = [
  "rustc-hash 2.1.1",
  "rustc_apfloat",
  "salsa",
+ "salsa-macros",
  "smallvec",
  "span",
  "stdx",
@@ -660,6 +662,7 @@ dependencies = [
  "query-group-macro",
  "rustc-hash 2.1.1",
  "salsa",
+ "salsa-macros",
  "smallvec",
  "span",
  "stdx",
@@ -700,6 +703,7 @@ dependencies = [
  "rustc-hash 2.1.1",
  "rustc_apfloat",
  "salsa",
+ "salsa-macros",
  "scoped-tls",
  "smallvec",
  "span",
@@ -936,6 +940,7 @@ dependencies = [
  "rayon",
  "rustc-hash 2.1.1",
  "salsa",
+ "salsa-macros",
  "span",
  "stdx",
  "syntax",
@@ -1729,6 +1734,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "salsa",
+ "salsa-macros",
  "syn",
 ]
 
@@ -2033,9 +2039,9 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
 
 [[package]]
 name = "salsa"
-version = "0.20.0"
+version = "0.21.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1be22155f8d9732518b2db2bf379fe6f0b2375e76b08b7c8fe6c1b887d548c24"
+checksum = "6f80d5cf3c3fcab2cef898012f242a670477a1baa609267376af9cb4409026c5"
 dependencies = [
  "boxcar",
  "crossbeam-queue",
@@ -2056,15 +2062,15 @@ dependencies = [
 
 [[package]]
 name = "salsa-macro-rules"
-version = "0.20.0"
+version = "0.21.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f55a7ef0a84e336f7c5f0332d81727f5629fe042d2aa556c75307afebc9f78a5"
+checksum = "05303d72606fbf2b9c9523cda2039bb8ecb00304027a3cd7e52b02a65c7d9185"
 
 [[package]]
 name = "salsa-macros"
-version = "0.20.0"
+version = "0.21.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d0e88a9c0c0d231a63f83dcd1a2c5e5d11044fac4b65bc9ad3b68ab48b0a0ab"
+checksum = "eb2f0e2a30c65cb3cd63440c491dde68d9af7e1be2b77832ac7057141107db50"
 dependencies = [
  "heck",
  "proc-macro2",
diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml
index 6fa171702dd..c4c2fdf34ba 100644
--- a/src/tools/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/Cargo.toml
@@ -131,7 +131,9 @@ process-wrap = { version = "8.2.0", features = ["std"] }
 pulldown-cmark-to-cmark = "10.0.4"
 pulldown-cmark = { version = "0.9.6", default-features = false }
 rayon = "1.10.0"
-salsa = "0.20.0"
+rowan = "=0.15.15"
+salsa = { version = "0.21.1", default-features = false, features = ["rayon","salsa_unstable"] }
+salsa-macros = "0.21.1"
 semver = "1.0.26"
 serde = { version = "1.0.219" }
 serde_derive = { version = "1.0.219" }
diff --git a/src/tools/rust-analyzer/crates/base-db/Cargo.toml b/src/tools/rust-analyzer/crates/base-db/Cargo.toml
index 441434504c2..e2e3253773f 100644
--- a/src/tools/rust-analyzer/crates/base-db/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/base-db/Cargo.toml
@@ -15,6 +15,7 @@ rust-version.workspace = true
 la-arena.workspace = true
 dashmap.workspace = true
 salsa.workspace = true
+salsa-macros.workspace = true
 query-group.workspace = true
 rustc-hash.workspace = true
 triomphe.workspace = true
diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs
index 499c9b3716b..9660e6e87cc 100644
--- a/src/tools/rust-analyzer/crates/base-db/src/input.rs
+++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs
@@ -392,7 +392,7 @@ impl BuiltDependency {
 
 pub type CratesIdMap = FxHashMap<CrateBuilderId, Crate>;
 
-#[salsa::input]
+#[salsa_macros::input]
 #[derive(Debug)]
 pub struct Crate {
     #[return_ref]
diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs
index 7f7a712577e..a67fbf75c02 100644
--- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs
@@ -1,9 +1,13 @@
 //! base_db defines basic database traits. The concrete DB is defined by ide.
+
+pub use salsa;
+pub use salsa_macros;
+
 // FIXME: Rename this crate, base db is non descriptive
 mod change;
 mod input;
 
-use std::hash::BuildHasherDefault;
+use std::{cell::RefCell, hash::BuildHasherDefault, panic, sync::Once};
 
 pub use crate::{
     change::FileChange,
@@ -17,7 +21,6 @@ pub use crate::{
 use dashmap::{DashMap, mapref::entry::Entry};
 pub use query_group::{self};
 use rustc_hash::{FxHashSet, FxHasher};
-pub use salsa::{self};
 use salsa::{Durability, Setter};
 pub use semver::{BuildMetadata, Prerelease, Version, VersionReq};
 use span::Edition;
@@ -28,7 +31,7 @@ pub use vfs::{AnchoredPath, AnchoredPathBuf, FileId, VfsPath, file_set::FileSet}
 #[macro_export]
 macro_rules! impl_intern_key {
     ($id:ident, $loc:ident) => {
-        #[salsa::interned(no_lifetime)]
+        #[salsa_macros::interned(no_lifetime)]
         pub struct $id {
             pub loc: $loc,
         }
@@ -57,7 +60,12 @@ pub struct Files {
 
 impl Files {
     pub fn file_text(&self, file_id: vfs::FileId) -> FileText {
-        *self.files.get(&file_id).expect("Unable to fetch file; this is a bug")
+        match self.files.get(&file_id) {
+            Some(text) => *text,
+            None => {
+                panic!("Unable to fetch file text for `vfs::FileId`: {file_id:?}; this is a bug")
+            }
+        }
     }
 
     pub fn set_file_text(&self, db: &mut dyn SourceDatabase, file_id: vfs::FileId, text: &str) {
@@ -93,10 +101,12 @@ impl Files {
 
     /// Source root of the file.
     pub fn source_root(&self, source_root_id: SourceRootId) -> SourceRootInput {
-        let source_root = self
-            .source_roots
-            .get(&source_root_id)
-            .expect("Unable to fetch source root id; this is a bug");
+        let source_root = match self.source_roots.get(&source_root_id) {
+            Some(source_root) => source_root,
+            None => panic!(
+                "Unable to fetch `SourceRootInput` with `SourceRootId` ({source_root_id:?}); this is a bug"
+            ),
+        };
 
         *source_root
     }
@@ -121,10 +131,12 @@ impl Files {
     }
 
     pub fn file_source_root(&self, id: vfs::FileId) -> FileSourceRootInput {
-        let file_source_root = self
-            .file_source_roots
-            .get(&id)
-            .expect("Unable to fetch FileSourceRootInput; this is a bug");
+        let file_source_root = match self.file_source_roots.get(&id) {
+            Some(file_source_root) => file_source_root,
+            None => panic!(
+                "Unable to get `FileSourceRootInput` with `vfs::FileId` ({id:?}); this is a bug",
+            ),
+        };
         *file_source_root
     }
 
@@ -152,7 +164,7 @@ impl Files {
     }
 }
 
-#[salsa::interned(no_lifetime, debug, constructor=from_span)]
+#[salsa_macros::interned(no_lifetime, debug, constructor=from_span)]
 pub struct EditionedFileId {
     pub editioned_file_id: span::EditionedFileId,
 }
@@ -187,18 +199,18 @@ impl EditionedFileId {
     }
 }
 
-#[salsa::input(debug)]
+#[salsa_macros::input(debug)]
 pub struct FileText {
     pub text: Arc<str>,
     pub file_id: vfs::FileId,
 }
 
-#[salsa::input(debug)]
+#[salsa_macros::input(debug)]
 pub struct FileSourceRootInput {
     pub source_root_id: SourceRootId,
 }
 
-#[salsa::input(debug)]
+#[salsa_macros::input(debug)]
 pub struct SourceRootInput {
     pub source_root: Arc<SourceRoot>,
 }
@@ -265,7 +277,7 @@ pub fn transitive_deps(db: &dyn SourceDatabase, crate_id: Crate) -> FxHashSet<Cr
     deps
 }
 
-#[salsa::db]
+#[salsa_macros::db]
 pub trait SourceDatabase: salsa::Database {
     /// Text of the file.
     fn file_text(&self, file_id: vfs::FileId) -> FileText;
@@ -344,7 +356,7 @@ fn parse(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Parse<ast::SourceFil
 }
 
 fn parse_errors(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Option<&[SyntaxError]> {
-    #[salsa::tracked(return_ref)]
+    #[salsa_macros::tracked(return_ref)]
     fn parse_errors(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Option<Box<[SyntaxError]>> {
         let errors = db.parse(file_id).errors();
         match &*errors {
@@ -373,3 +385,49 @@ fn relevant_crates(db: &dyn RootQueryDb, file_id: FileId) -> Arc<[Crate]> {
     let source_root = db.file_source_root(file_id);
     db.source_root_crates(source_root.source_root_id(db))
 }
+
+#[must_use]
+#[non_exhaustive]
+pub struct DbPanicContext;
+
+impl Drop for DbPanicContext {
+    fn drop(&mut self) {
+        Self::with_ctx(|ctx| assert!(ctx.pop().is_some()));
+    }
+}
+
+impl DbPanicContext {
+    pub fn enter(frame: String) -> DbPanicContext {
+        #[expect(clippy::print_stderr, reason = "already panicking anyway")]
+        fn set_hook() {
+            let default_hook = panic::take_hook();
+            panic::set_hook(Box::new(move |panic_info| {
+                default_hook(panic_info);
+                if let Some(backtrace) = salsa::Backtrace::capture() {
+                    eprintln!("{backtrace:#}");
+                }
+                DbPanicContext::with_ctx(|ctx| {
+                    if !ctx.is_empty() {
+                        eprintln!("additional context:");
+                        for (idx, frame) in ctx.iter().enumerate() {
+                            eprintln!("{idx:>4}: {frame}\n");
+                        }
+                    }
+                });
+            }));
+        }
+
+        static SET_HOOK: Once = Once::new();
+        SET_HOOK.call_once(set_hook);
+
+        Self::with_ctx(|ctx| ctx.push(frame));
+        DbPanicContext
+    }
+
+    fn with_ctx(f: impl FnOnce(&mut Vec<String>)) {
+        thread_local! {
+            static CTX: RefCell<Vec<String>> = const { RefCell::new(Vec::new()) };
+        }
+        CTX.with(|ctx| f(&mut ctx.borrow_mut()));
+    }
+}
diff --git a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml
index f97597ffe5a..c1c89e8d1cc 100644
--- a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml
@@ -28,6 +28,7 @@ triomphe.workspace = true
 rustc_apfloat = "0.2.2"
 text-size.workspace = true
 salsa.workspace = true
+salsa-macros.workspace = true
 query-group.workspace = true
 
 ra-ap-rustc_parse_format.workspace = true
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs
index a80313aba3e..bb6222b1d46 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs
@@ -1,6 +1,6 @@
 //! A higher level attributes based on TokenTree, with also some shortcuts.
 
-use std::{borrow::Cow, hash::Hash, ops};
+use std::{borrow::Cow, convert::identity, hash::Hash, ops};
 
 use base_db::Crate;
 use cfg::{CfgExpr, CfgOptions};
@@ -8,6 +8,7 @@ use either::Either;
 use hir_expand::{
     HirFileId, InFile,
     attrs::{Attr, AttrId, RawAttrs, collect_attrs},
+    span_map::SpanMapRef,
 };
 use intern::{Symbol, sym};
 use la_arena::{ArenaMap, Idx, RawIdx};
@@ -45,8 +46,27 @@ impl Attrs {
         (**self).iter().find(|attr| attr.id == id)
     }
 
-    pub(crate) fn filter(db: &dyn DefDatabase, krate: Crate, raw_attrs: RawAttrs) -> Attrs {
-        Attrs(raw_attrs.filter(db, krate))
+    pub(crate) fn expand_cfg_attr(
+        db: &dyn DefDatabase,
+        krate: Crate,
+        raw_attrs: RawAttrs,
+    ) -> Attrs {
+        Attrs(raw_attrs.expand_cfg_attr(db, krate))
+    }
+
+    pub(crate) fn is_cfg_enabled_for(
+        db: &dyn DefDatabase,
+        owner: &dyn ast::HasAttrs,
+        span_map: SpanMapRef<'_>,
+        cfg_options: &CfgOptions,
+    ) -> Result<(), CfgExpr> {
+        RawAttrs::attrs_iter_expanded::<false>(db, owner, span_map, cfg_options)
+            .filter_map(|attr| attr.cfg())
+            .find_map(|cfg| match cfg_options.check(&cfg).is_none_or(identity) {
+                true => None,
+                false => Some(cfg),
+            })
+            .map_or(Ok(()), Err)
     }
 }
 
@@ -522,38 +542,41 @@ impl AttrsWithOwner {
                 GenericParamId::ConstParamId(it) => {
                     let src = it.parent().child_source(db);
                     // FIXME: We should be never getting `None` here.
-                    match src.value.get(it.local_id()) {
-                        Some(val) => RawAttrs::from_attrs_owner(
+                    return Attrs(match src.value.get(it.local_id()) {
+                        Some(val) => RawAttrs::new_expanded(
                             db,
-                            src.with_value(val),
+                            val,
                             db.span_map(src.file_id).as_ref(),
+                            def.krate(db).cfg_options(db),
                         ),
                         None => RawAttrs::EMPTY,
-                    }
+                    });
                 }
                 GenericParamId::TypeParamId(it) => {
                     let src = it.parent().child_source(db);
                     // FIXME: We should be never getting `None` here.
-                    match src.value.get(it.local_id()) {
-                        Some(val) => RawAttrs::from_attrs_owner(
+                    return Attrs(match src.value.get(it.local_id()) {
+                        Some(val) => RawAttrs::new_expanded(
                             db,
-                            src.with_value(val),
+                            val,
                             db.span_map(src.file_id).as_ref(),
+                            def.krate(db).cfg_options(db),
                         ),
                         None => RawAttrs::EMPTY,
-                    }
+                    });
                 }
                 GenericParamId::LifetimeParamId(it) => {
                     let src = it.parent.child_source(db);
                     // FIXME: We should be never getting `None` here.
-                    match src.value.get(it.local_id) {
-                        Some(val) => RawAttrs::from_attrs_owner(
+                    return Attrs(match src.value.get(it.local_id) {
+                        Some(val) => RawAttrs::new_expanded(
                             db,
-                            src.with_value(val),
+                            val,
                             db.span_map(src.file_id).as_ref(),
+                            def.krate(db).cfg_options(db),
                         ),
                         None => RawAttrs::EMPTY,
-                    }
+                    });
                 }
             },
             AttrDefId::ExternBlockId(it) => attrs_from_item_tree_loc(db, it),
@@ -561,7 +584,7 @@ impl AttrsWithOwner {
             AttrDefId::UseId(it) => attrs_from_item_tree_loc(db, it),
         };
 
-        let attrs = raw_attrs.filter(db, def.krate(db));
+        let attrs = raw_attrs.expand_cfg_attr(db, def.krate(db));
         Attrs(attrs)
     }
 
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs
index 34cf42d02bd..2cbdbe16f9b 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs
@@ -22,7 +22,7 @@ use crate::{
     hir::generics::GenericParams,
     import_map::ImportMap,
     item_tree::{AttrOwner, ItemTree},
-    lang_item::{self, LangItem, LangItemTarget, LangItems},
+    lang_item::{self, LangItem},
     nameres::{
         DefMap, LocalDefMap,
         assoc::{ImplItems, TraitItems},
@@ -325,9 +325,6 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase {
 
     // endregion:attrs
 
-    #[salsa::invoke(LangItems::lang_item_query)]
-    fn lang_item(&self, start_crate: Crate, item: LangItem) -> Option<LangItemTarget>;
-
     #[salsa::invoke(ImportMap::import_map_query)]
     fn import_map(&self, krate: Crate) -> Arc<ImportMap>;
 
@@ -349,9 +346,6 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase {
 
     // endregion:visibilities
 
-    #[salsa::invoke(LangItems::crate_lang_items_query)]
-    fn crate_lang_items(&self, krate: Crate) -> Option<Arc<LangItems>>;
-
     #[salsa::invoke(crate::lang_item::notable_traits_in_deps)]
     fn notable_traits_in_deps(&self, krate: Crate) -> Arc<[Arc<[TraitId]>]>;
     #[salsa::invoke(crate::lang_item::crate_notable_traits)]
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs
index 7eec913dd65..3823fb5a1e7 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs
@@ -3,21 +3,24 @@
 use std::mem;
 
 use base_db::Crate;
+use cfg::CfgOptions;
 use drop_bomb::DropBomb;
+use hir_expand::AstId;
 use hir_expand::{
     ExpandError, ExpandErrorKind, ExpandResult, HirFileId, InFile, Lookup, MacroCallId,
-    attrs::RawAttrs, eager::EagerCallBackFn, mod_path::ModPath, span_map::SpanMap,
+    eager::EagerCallBackFn, mod_path::ModPath, span_map::SpanMap,
 };
 use span::{AstIdMap, Edition, SyntaxContext};
 use syntax::ast::HasAttrs;
-use syntax::{Parse, ast};
+use syntax::{AstNode, Parse, ast};
 use triomphe::Arc;
 use tt::TextRange;
 
 use crate::attr::Attrs;
 use crate::expr_store::HygieneId;
+use crate::macro_call_as_call_id;
 use crate::nameres::DefMap;
-use crate::{AsMacroCall, MacroId, UnresolvedMacro, db::DefDatabase};
+use crate::{MacroId, UnresolvedMacro, db::DefDatabase};
 
 #[derive(Debug)]
 pub(super) struct Expander {
@@ -64,22 +67,13 @@ impl Expander {
         }
     }
 
-    pub(super) fn attrs(
-        &self,
-        db: &dyn DefDatabase,
-        krate: Crate,
-        has_attrs: &dyn HasAttrs,
-    ) -> Attrs {
-        Attrs::filter(db, krate, RawAttrs::new(db, has_attrs, self.span_map.as_ref()))
-    }
-
     pub(super) fn is_cfg_enabled(
         &self,
         db: &dyn DefDatabase,
-        krate: Crate,
         has_attrs: &dyn HasAttrs,
-    ) -> bool {
-        self.attrs(db, krate, has_attrs).is_cfg_enabled(krate.cfg_options(db))
+        cfg_options: &CfgOptions,
+    ) -> Result<(), cfg::CfgExpr> {
+        Attrs::is_cfg_enabled_for(db, has_attrs, self.span_map.as_ref(), cfg_options)
     }
 
     pub(super) fn call_syntax_ctx(&self) -> SyntaxContext {
@@ -100,8 +94,31 @@ impl Expander {
 
         let result = self.within_limit(db, |this| {
             let macro_call = this.in_file(&macro_call);
-            match macro_call.as_call_id_with_errors(
+
+            let expands_to = hir_expand::ExpandTo::from_call_site(macro_call.value);
+            let ast_id = AstId::new(macro_call.file_id, this.ast_id_map().ast_id(macro_call.value));
+            let path = macro_call.value.path().and_then(|path| {
+                let range = path.syntax().text_range();
+                let mod_path = ModPath::from_src(db, path, &mut |range| {
+                    this.span_map.span_for_range(range).ctx
+                })?;
+                let call_site = this.span_map.span_for_range(range);
+                Some((call_site, mod_path))
+            });
+
+            let Some((call_site, path)) = path else {
+                return ExpandResult::only_err(ExpandError::other(
+                    this.span_map.span_for_range(macro_call.value.syntax().text_range()),
+                    "malformed macro invocation",
+                ));
+            };
+
+            match macro_call_as_call_id(
                 db,
+                ast_id,
+                &path,
+                call_site.ctx,
+                expands_to,
                 krate,
                 |path| resolver(path).map(|it| db.macro_def(it)),
                 eager_callback,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs
index 7f907fdba8e..50505d54ba2 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs
@@ -7,6 +7,7 @@ mod path;
 
 use std::mem;
 
+use cfg::CfgOptions;
 use either::Either;
 use hir_expand::{
     HirFileId, InFile, Lookup, MacroDefId,
@@ -81,8 +82,6 @@ pub(super) fn lower_body(
     // even though they should be the same. Also, when the body comes from multiple expansions, their
     // hygiene is different.
 
-    let krate = module.krate();
-
     let mut self_param = None;
     let mut source_map_self_param = None;
     let mut params = vec![];
@@ -100,9 +99,8 @@ pub(super) fn lower_body(
     // and skip the body.
     if skip_body {
         if let Some(param_list) = parameters {
-            if let Some(self_param_syn) = param_list
-                .self_param()
-                .filter(|self_param| collector.expander.is_cfg_enabled(db, krate, self_param))
+            if let Some(self_param_syn) =
+                param_list.self_param().filter(|self_param| collector.check_cfg(self_param))
             {
                 let is_mutable =
                     self_param_syn.mut_token().is_some() && self_param_syn.amp_token().is_none();
@@ -119,10 +117,7 @@ pub(super) fn lower_body(
                 source_map_self_param =
                     Some(collector.expander.in_file(AstPtr::new(&self_param_syn)));
             }
-            let count = param_list
-                .params()
-                .filter(|it| collector.expander.is_cfg_enabled(db, krate, it))
-                .count();
+            let count = param_list.params().filter(|it| collector.check_cfg(it)).count();
             params = (0..count).map(|_| collector.missing_pat()).collect();
         };
         let body_expr = collector.missing_expr();
@@ -138,9 +133,7 @@ pub(super) fn lower_body(
     }
 
     if let Some(param_list) = parameters {
-        if let Some(self_param_syn) =
-            param_list.self_param().filter(|it| collector.expander.is_cfg_enabled(db, krate, it))
-        {
+        if let Some(self_param_syn) = param_list.self_param().filter(|it| collector.check_cfg(it)) {
             let is_mutable =
                 self_param_syn.mut_token().is_some() && self_param_syn.amp_token().is_none();
             let hygiene = self_param_syn
@@ -157,7 +150,7 @@ pub(super) fn lower_body(
         }
 
         for param in param_list.params() {
-            if collector.expander.is_cfg_enabled(db, krate, &param) {
+            if collector.check_cfg(&param) {
                 let param_pat = collector.collect_pat_top(param.pat());
                 params.push(param_pat);
             }
@@ -346,7 +339,7 @@ pub(crate) fn lower_function(
     collector.collect_impl_trait(&mut expr_collector, |collector, mut impl_trait_lower_fn| {
         if let Some(param_list) = fn_.value.param_list() {
             if let Some(param) = param_list.self_param() {
-                let enabled = collector.expander.is_cfg_enabled(db, module.krate(), &param);
+                let enabled = collector.check_cfg(&param);
                 if enabled {
                     has_self_param = true;
                     params.push(match param.ty() {
@@ -381,7 +374,7 @@ pub(crate) fn lower_function(
             }
             let p = param_list
                 .params()
-                .filter(|param| collector.expander.is_cfg_enabled(db, module.krate(), param))
+                .filter(|param| collector.check_cfg(param))
                 .filter(|param| {
                     let is_variadic = param.dotdotdot_token().is_some();
                     has_variadic |= is_variadic;
@@ -441,6 +434,7 @@ pub(crate) fn lower_function(
 
 pub struct ExprCollector<'db> {
     db: &'db dyn DefDatabase,
+    cfg_options: &'db CfgOptions,
     expander: Expander,
     def_map: Arc<DefMap>,
     local_def_map: Arc<LocalDefMap>,
@@ -553,6 +547,7 @@ impl ExprCollector<'_> {
         let expander = Expander::new(db, current_file_id, &def_map);
         ExprCollector {
             db,
+            cfg_options: module.krate().cfg_options(db),
             module,
             def_map,
             local_def_map,
@@ -1026,7 +1021,9 @@ impl ExprCollector<'_> {
     /// Returns `None` if and only if the expression is `#[cfg]`d out.
     fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option<ExprId> {
         let syntax_ptr = AstPtr::new(&expr);
-        self.check_cfg(&expr)?;
+        if !self.check_cfg(&expr) {
+            return None;
+        }
 
         // FIXME: Move some of these arms out into separate methods for clarity
         Some(match expr {
@@ -1114,6 +1111,7 @@ impl ExprCollector<'_> {
             ast::Expr::WhileExpr(e) => self.collect_while_loop(syntax_ptr, e),
             ast::Expr::ForExpr(e) => self.collect_for_loop(syntax_ptr, e),
             ast::Expr::CallExpr(e) => {
+                // FIXME: Remove this once we drop support for <1.86, https://github.com/rust-lang/rust/commit/ac9cb908ac4301dfc25e7a2edee574320022ae2c
                 let is_rustc_box = {
                     let attrs = e.attrs();
                     attrs.filter_map(|it| it.as_simple_atom()).any(|it| it == "rustc_box")
@@ -1156,13 +1154,17 @@ impl ExprCollector<'_> {
                     match_arm_list
                         .arms()
                         .filter_map(|arm| {
-                            self.check_cfg(&arm).map(|()| MatchArm {
-                                pat: self.collect_pat_top(arm.pat()),
-                                expr: self.collect_expr_opt(arm.expr()),
-                                guard: arm
-                                    .guard()
-                                    .map(|guard| self.collect_expr_opt(guard.condition())),
-                            })
+                            if self.check_cfg(&arm) {
+                                Some(MatchArm {
+                                    pat: self.collect_pat_top(arm.pat()),
+                                    expr: self.collect_expr_opt(arm.expr()),
+                                    guard: arm
+                                        .guard()
+                                        .map(|guard| self.collect_expr_opt(guard.condition())),
+                                })
+                            } else {
+                                None
+                            }
                         })
                         .collect()
                 } else {
@@ -1230,7 +1232,9 @@ impl ExprCollector<'_> {
                     let fields = nfl
                         .fields()
                         .filter_map(|field| {
-                            self.check_cfg(&field)?;
+                            if !self.check_cfg(&field) {
+                                return None;
+                            }
 
                             let name = field.field_name()?.as_name();
 
@@ -1483,7 +1487,9 @@ impl ExprCollector<'_> {
     }
 
     fn maybe_collect_expr_as_pat(&mut self, expr: &ast::Expr) -> Option<PatId> {
-        self.check_cfg(expr)?;
+        if !self.check_cfg(expr) {
+            return None;
+        }
         let syntax_ptr = AstPtr::new(expr);
 
         let result = match expr {
@@ -1558,7 +1564,9 @@ impl ExprCollector<'_> {
                 let args = record_field_list
                     .fields()
                     .filter_map(|f| {
-                        self.check_cfg(&f)?;
+                        if !self.check_cfg(&f) {
+                            return None;
+                        }
                         let field_expr = f.expr()?;
                         let pat = self.collect_expr_as_pat(field_expr);
                         let name = f.field_name()?.as_name();
@@ -2044,7 +2052,7 @@ impl ExprCollector<'_> {
     fn collect_stmt(&mut self, statements: &mut Vec<Statement>, s: ast::Stmt) {
         match s {
             ast::Stmt::LetStmt(stmt) => {
-                if self.check_cfg(&stmt).is_none() {
+                if !self.check_cfg(&stmt) {
                     return;
                 }
                 let pat = self.collect_pat_top(stmt.pat());
@@ -2059,7 +2067,7 @@ impl ExprCollector<'_> {
             ast::Stmt::ExprStmt(stmt) => {
                 let expr = stmt.expr();
                 match &expr {
-                    Some(expr) if self.check_cfg(expr).is_none() => return,
+                    Some(expr) if !self.check_cfg(expr) => return,
                     _ => (),
                 }
                 let has_semi = stmt.semicolon_token().is_some();
@@ -2074,7 +2082,7 @@ impl ExprCollector<'_> {
                 }
             }
             ast::Stmt::Item(ast::Item::MacroDef(macro_)) => {
-                if self.check_cfg(&macro_).is_none() {
+                if !self.check_cfg(&macro_) {
                     return;
                 }
                 let Some(name) = macro_.name() else {
@@ -2086,7 +2094,7 @@ impl ExprCollector<'_> {
                 self.collect_macro_def(statements, macro_id);
             }
             ast::Stmt::Item(ast::Item::MacroRules(macro_)) => {
-                if self.check_cfg(&macro_).is_none() {
+                if !self.check_cfg(&macro_) {
                     return;
                 }
                 let Some(name) = macro_.name() else {
@@ -2360,7 +2368,9 @@ impl ExprCollector<'_> {
                 let args = record_pat_field_list
                     .fields()
                     .filter_map(|f| {
-                        self.check_cfg(&f)?;
+                        if !self.check_cfg(&f) {
+                            return None;
+                        }
                         let ast_pat = f.pat()?;
                         let pat = self.collect_pat(ast_pat, binding_list);
                         let name = f.field_name()?.as_name();
@@ -2536,25 +2546,18 @@ impl ExprCollector<'_> {
 
     /// Returns `None` (and emits diagnostics) when `owner` if `#[cfg]`d out, and `Some(())` when
     /// not.
-    fn check_cfg(&mut self, owner: &dyn ast::HasAttrs) -> Option<()> {
-        let attrs = self.expander.attrs(self.db, self.module.krate(), owner);
-        match attrs.cfg() {
-            Some(cfg) => {
-                let cfg_options = self.module.krate().cfg_options(self.db);
-
-                if cfg_options.check(&cfg) != Some(false) {
-                    return Some(());
-                }
-
+    fn check_cfg(&mut self, owner: &dyn ast::HasAttrs) -> bool {
+        let enabled = self.expander.is_cfg_enabled(self.db, owner, self.cfg_options);
+        match enabled {
+            Ok(()) => true,
+            Err(cfg) => {
                 self.source_map.diagnostics.push(ExpressionStoreDiagnostics::InactiveCode {
                     node: self.expander.in_file(SyntaxNodePtr::new(owner.syntax())),
                     cfg,
-                    opts: cfg_options.clone(),
+                    opts: self.cfg_options.clone(),
                 });
-
-                None
+                false
             }
-            None => Some(()),
         }
     }
 
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs
index 9ef03065651..d36e5205c73 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/asm.rs
@@ -224,7 +224,7 @@ impl ExprCollector<'_> {
 
                     curarg = parser.curarg;
 
-                    let to_span = |inner_span: rustc_parse_format::InnerSpan| {
+                    let to_span = |inner_span: std::ops::Range<usize>| {
                         is_direct_literal.then(|| {
                             TextRange::new(
                                 inner_span.start.try_into().unwrap(),
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs
index 9485e703d9c..02a1d274fb5 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs
@@ -110,7 +110,7 @@ impl GenericParamsCollector {
 
     fn lower_param_list(&mut self, ec: &mut ExprCollector<'_>, params: ast::GenericParamList) {
         for generic_param in params.generic_params() {
-            let enabled = ec.expander.is_cfg_enabled(ec.db, ec.module.krate(), &generic_param);
+            let enabled = ec.check_cfg(&generic_param);
             if !enabled {
                 continue;
             }
@@ -270,7 +270,7 @@ impl GenericParamsCollector {
         let self_ = Name::new_symbol_root(sym::Self_);
         let idx = self.type_or_consts.alloc(
             TypeParamData {
-                name: Some(self_.clone()),
+                name: Some(self_),
                 default: None,
                 provenance: TypeParamProvenance::TraitSelf,
             }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs
index 2fd21bb0ed3..f27a4062a63 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs
@@ -214,7 +214,7 @@ pub(crate) fn parse(
         };
     }
 
-    let to_span = |inner_span: parse::InnerSpan| {
+    let to_span = |inner_span: std::ops::Range<usize>| {
         is_source_literal.then(|| {
             TextRange::new(inner_span.start.try_into().unwrap(), inner_span.end.try_into().unwrap())
         })
@@ -297,7 +297,7 @@ pub(crate) fn parse(
                     unfinished_literal.clear();
                 }
 
-                let span = parser.arg_places.get(placeholder_index).and_then(|&s| to_span(s));
+                let span = parser.arg_places.get(placeholder_index).and_then(|s| to_span(s.clone()));
                 placeholder_index += 1;
 
                 let position_span = to_span(position_span);
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
index bece940950d..5362c0588db 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
@@ -167,7 +167,7 @@ pub struct ItemScope {
     // the resolutions of the imports of this scope
     use_imports_types: FxHashMap<ImportOrExternCrate, ImportOrDef>,
     use_imports_values: FxHashMap<ImportOrGlob, ImportOrDef>,
-    use_imports_macros: FxHashMap<ImportOrGlob, ImportOrDef>,
+    use_imports_macros: FxHashMap<ImportOrExternCrate, ImportOrDef>,
 
     use_decls: Vec<UseId>,
     extern_crate_decls: Vec<ExternCrateId>,
@@ -242,7 +242,7 @@ impl ItemScope {
         self.types.iter().map(|(n, &i)| (n, i))
     }
 
-    pub fn macros(&self) -> impl Iterator<Item = (&Name, Item<MacroId, ImportOrGlob>)> + '_ {
+    pub fn macros(&self) -> impl Iterator<Item = (&Name, Item<MacroId, ImportOrExternCrate>)> + '_ {
         self.macros.iter().map(|(n, &i)| (n, i))
     }
 
@@ -250,9 +250,9 @@ impl ItemScope {
         self.use_imports_types
             .keys()
             .copied()
+            .chain(self.use_imports_macros.keys().copied())
             .filter_map(ImportOrExternCrate::import_or_glob)
             .chain(self.use_imports_values.keys().copied())
-            .chain(self.use_imports_macros.keys().copied())
             .filter_map(ImportOrGlob::into_import)
             .sorted()
             .dedup()
@@ -263,7 +263,7 @@ impl ItemScope {
 
         let mut def_map;
         let mut scope = self;
-        while let Some(&m) = scope.use_imports_macros.get(&ImportOrGlob::Import(import)) {
+        while let Some(&m) = scope.use_imports_macros.get(&ImportOrExternCrate::Import(import)) {
             match m {
                 ImportOrDef::Import(i) => {
                     let module_id = i.use_.lookup(db).container;
@@ -682,7 +682,6 @@ impl ItemScope {
                         }
                         _ => _ = glob_imports.macros.remove(&lookup),
                     }
-                    let import = import.and_then(ImportOrExternCrate::import_or_glob);
                     let prev = std::mem::replace(&mut fld.import, import);
                     if let Some(import) = import {
                         self.use_imports_macros.insert(
@@ -698,7 +697,6 @@ impl ItemScope {
                 {
                     if glob_imports.macros.remove(&lookup) {
                         cov_mark::hit!(import_shadowed);
-                        let import = import.and_then(ImportOrExternCrate::import_or_glob);
                         let prev = std::mem::replace(&mut fld.import, import);
                         if let Some(import) = import {
                             self.use_imports_macros.insert(
@@ -783,8 +781,9 @@ impl ItemScope {
             if let Some(Item { import, .. }) = def.macros {
                 buf.push_str(" m");
                 match import {
-                    Some(ImportOrGlob::Import(_)) => buf.push('i'),
-                    Some(ImportOrGlob::Glob(_)) => buf.push('g'),
+                    Some(ImportOrExternCrate::Import(_)) => buf.push('i'),
+                    Some(ImportOrExternCrate::Glob(_)) => buf.push('g'),
+                    Some(ImportOrExternCrate::ExternCrate(_)) => buf.push('e'),
                     None => (),
                 }
             }
@@ -893,9 +892,7 @@ impl PerNs {
             ModuleDefId::TraitAliasId(_) => PerNs::types(def, v, import),
             ModuleDefId::TypeAliasId(_) => PerNs::types(def, v, import),
             ModuleDefId::BuiltinType(_) => PerNs::types(def, v, import),
-            ModuleDefId::MacroId(mac) => {
-                PerNs::macros(mac, v, import.and_then(ImportOrExternCrate::import_or_glob))
-            }
+            ModuleDefId::MacroId(mac) => PerNs::macros(mac, v, import),
         }
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
index 01d340cea6d..1b97eb72b6f 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
@@ -179,7 +179,7 @@ impl ItemTree {
 
     /// Returns the inner attributes of the source file.
     pub fn top_level_attrs(&self, db: &dyn DefDatabase, krate: Crate) -> Attrs {
-        Attrs::filter(
+        Attrs::expand_cfg_attr(
             db,
             krate,
             self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&RawAttrs::EMPTY).clone(),
@@ -191,7 +191,7 @@ impl ItemTree {
     }
 
     pub(crate) fn attrs(&self, db: &dyn DefDatabase, krate: Crate, of: AttrOwner) -> Attrs {
-        Attrs::filter(db, krate, self.raw_attrs(of).clone())
+        Attrs::expand_cfg_attr(db, krate, self.raw_attrs(of).clone())
     }
 
     /// Returns a count of a few, expensive items.
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
index 5431ec9679c..51a833b5f15 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
@@ -83,104 +83,99 @@ impl LangItemTarget {
     }
 }
 
-#[derive(Default, Debug, Clone, PartialEq, Eq)]
-pub struct LangItems {
-    items: FxHashMap<LangItem, LangItemTarget>,
-}
+/// Salsa query. This will look for lang items in a specific crate.
+#[salsa_macros::tracked(return_ref)]
+pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> Option<Box<LangItems>> {
+    let _p = tracing::info_span!("crate_lang_items_query").entered();
 
-impl LangItems {
-    pub fn target(&self, item: LangItem) -> Option<LangItemTarget> {
-        self.items.get(&item).copied()
-    }
+    let mut lang_items = LangItems::default();
 
-    /// Salsa query. This will look for lang items in a specific crate.
-    pub(crate) fn crate_lang_items_query(
-        db: &dyn DefDatabase,
-        krate: Crate,
-    ) -> Option<Arc<LangItems>> {
-        let _p = tracing::info_span!("crate_lang_items_query").entered();
-
-        let mut lang_items = LangItems::default();
+    let crate_def_map = db.crate_def_map(krate);
 
-        let crate_def_map = db.crate_def_map(krate);
+    for (_, module_data) in crate_def_map.modules() {
+        for impl_def in module_data.scope.impls() {
+            lang_items.collect_lang_item(db, impl_def, LangItemTarget::ImplDef);
+            for &(_, assoc) in db.impl_items(impl_def).items.iter() {
+                match assoc {
+                    AssocItemId::FunctionId(f) => {
+                        lang_items.collect_lang_item(db, f, LangItemTarget::Function)
+                    }
+                    AssocItemId::TypeAliasId(t) => {
+                        lang_items.collect_lang_item(db, t, LangItemTarget::TypeAlias)
+                    }
+                    AssocItemId::ConstId(_) => (),
+                }
+            }
+        }
 
-        for (_, module_data) in crate_def_map.modules() {
-            for impl_def in module_data.scope.impls() {
-                lang_items.collect_lang_item(db, impl_def, LangItemTarget::ImplDef);
-                for &(_, assoc) in db.impl_items(impl_def).items.iter() {
-                    match assoc {
+        for def in module_data.scope.declarations() {
+            match def {
+                ModuleDefId::TraitId(trait_) => {
+                    lang_items.collect_lang_item(db, trait_, LangItemTarget::Trait);
+                    db.trait_items(trait_).items.iter().for_each(|&(_, assoc_id)| match assoc_id {
                         AssocItemId::FunctionId(f) => {
-                            lang_items.collect_lang_item(db, f, LangItemTarget::Function)
+                            lang_items.collect_lang_item(db, f, LangItemTarget::Function);
                         }
-                        AssocItemId::TypeAliasId(t) => {
-                            lang_items.collect_lang_item(db, t, LangItemTarget::TypeAlias)
+                        AssocItemId::TypeAliasId(alias) => {
+                            lang_items.collect_lang_item(db, alias, LangItemTarget::TypeAlias)
                         }
-                        AssocItemId::ConstId(_) => (),
-                    }
+                        AssocItemId::ConstId(_) => {}
+                    });
                 }
-            }
-
-            for def in module_data.scope.declarations() {
-                match def {
-                    ModuleDefId::TraitId(trait_) => {
-                        lang_items.collect_lang_item(db, trait_, LangItemTarget::Trait);
-                        db.trait_items(trait_).items.iter().for_each(
-                            |&(_, assoc_id)| match assoc_id {
-                                AssocItemId::FunctionId(f) => {
-                                    lang_items.collect_lang_item(db, f, LangItemTarget::Function);
-                                }
-                                AssocItemId::TypeAliasId(alias) => lang_items.collect_lang_item(
-                                    db,
-                                    alias,
-                                    LangItemTarget::TypeAlias,
-                                ),
-                                AssocItemId::ConstId(_) => {}
-                            },
-                        );
-                    }
-                    ModuleDefId::AdtId(AdtId::EnumId(e)) => {
-                        lang_items.collect_lang_item(db, e, LangItemTarget::EnumId);
-                        db.enum_variants(e).variants.iter().for_each(|&(id, _)| {
-                            lang_items.collect_lang_item(db, id, LangItemTarget::EnumVariant);
-                        });
-                    }
-                    ModuleDefId::AdtId(AdtId::StructId(s)) => {
-                        lang_items.collect_lang_item(db, s, LangItemTarget::Struct);
-                    }
-                    ModuleDefId::AdtId(AdtId::UnionId(u)) => {
-                        lang_items.collect_lang_item(db, u, LangItemTarget::Union);
-                    }
-                    ModuleDefId::FunctionId(f) => {
-                        lang_items.collect_lang_item(db, f, LangItemTarget::Function);
-                    }
-                    ModuleDefId::StaticId(s) => {
-                        lang_items.collect_lang_item(db, s, LangItemTarget::Static);
-                    }
-                    ModuleDefId::TypeAliasId(t) => {
-                        lang_items.collect_lang_item(db, t, LangItemTarget::TypeAlias);
-                    }
-                    _ => {}
+                ModuleDefId::AdtId(AdtId::EnumId(e)) => {
+                    lang_items.collect_lang_item(db, e, LangItemTarget::EnumId);
+                    db.enum_variants(e).variants.iter().for_each(|&(id, _)| {
+                        lang_items.collect_lang_item(db, id, LangItemTarget::EnumVariant);
+                    });
+                }
+                ModuleDefId::AdtId(AdtId::StructId(s)) => {
+                    lang_items.collect_lang_item(db, s, LangItemTarget::Struct);
+                }
+                ModuleDefId::AdtId(AdtId::UnionId(u)) => {
+                    lang_items.collect_lang_item(db, u, LangItemTarget::Union);
                 }
+                ModuleDefId::FunctionId(f) => {
+                    lang_items.collect_lang_item(db, f, LangItemTarget::Function);
+                }
+                ModuleDefId::StaticId(s) => {
+                    lang_items.collect_lang_item(db, s, LangItemTarget::Static);
+                }
+                ModuleDefId::TypeAliasId(t) => {
+                    lang_items.collect_lang_item(db, t, LangItemTarget::TypeAlias);
+                }
+                _ => {}
             }
         }
+    }
 
-        if lang_items.items.is_empty() { None } else { Some(Arc::new(lang_items)) }
+    if lang_items.items.is_empty() { None } else { Some(Box::new(lang_items)) }
+}
+
+/// Salsa query. Look for a lang item, starting from the specified crate and recursively
+/// traversing its dependencies.
+#[salsa_macros::tracked]
+pub fn lang_item(
+    db: &dyn DefDatabase,
+    start_crate: Crate,
+    item: LangItem,
+) -> Option<LangItemTarget> {
+    let _p = tracing::info_span!("lang_item_query").entered();
+    if let Some(target) =
+        crate_lang_items(db, start_crate).as_ref().and_then(|it| it.items.get(&item).copied())
+    {
+        return Some(target);
     }
+    start_crate.data(db).dependencies.iter().find_map(|dep| lang_item(db, dep.crate_id, item))
+}
 
-    /// Salsa query. Look for a lang item, starting from the specified crate and recursively
-    /// traversing its dependencies.
-    pub(crate) fn lang_item_query(
-        db: &dyn DefDatabase,
-        start_crate: Crate,
-        item: LangItem,
-    ) -> Option<LangItemTarget> {
-        let _p = tracing::info_span!("lang_item_query").entered();
-        if let Some(target) =
-            db.crate_lang_items(start_crate).and_then(|it| it.items.get(&item).copied())
-        {
-            return Some(target);
-        }
-        start_crate.data(db).dependencies.iter().find_map(|dep| db.lang_item(dep.crate_id, item))
+#[derive(Default, Debug, Clone, PartialEq, Eq)]
+pub struct LangItems {
+    items: FxHashMap<LangItem, LangItemTarget>,
+}
+
+impl LangItems {
+    pub fn target(&self, item: LangItem) -> Option<LangItemTarget> {
+        self.items.get(&item).copied()
     }
 
     fn collect_lang_item<T>(
@@ -269,18 +264,38 @@ macro_rules! language_item_table {
 }
 
 impl LangItem {
+    pub fn resolve_function(self, db: &dyn DefDatabase, start_crate: Crate) -> Option<FunctionId> {
+        lang_item(db, start_crate, self).and_then(|t| t.as_function())
+    }
+
+    pub fn resolve_trait(self, db: &dyn DefDatabase, start_crate: Crate) -> Option<TraitId> {
+        lang_item(db, start_crate, self).and_then(|t| t.as_trait())
+    }
+
+    pub fn resolve_enum(self, db: &dyn DefDatabase, start_crate: Crate) -> Option<EnumId> {
+        lang_item(db, start_crate, self).and_then(|t| t.as_enum())
+    }
+
+    pub fn resolve_type_alias(
+        self,
+        db: &dyn DefDatabase,
+        start_crate: Crate,
+    ) -> Option<TypeAliasId> {
+        lang_item(db, start_crate, self).and_then(|t| t.as_type_alias())
+    }
+
     /// Opposite of [`LangItem::name`]
     pub fn from_name(name: &hir_expand::name::Name) -> Option<Self> {
         Self::from_symbol(name.symbol())
     }
 
     pub fn path(&self, db: &dyn DefDatabase, start_crate: Crate) -> Option<Path> {
-        let t = db.lang_item(start_crate, *self)?;
+        let t = lang_item(db, start_crate, *self)?;
         Some(Path::LangItem(t, None))
     }
 
     pub fn ty_rel_path(&self, db: &dyn DefDatabase, start_crate: Crate, seg: Name) -> Option<Path> {
-        let t = db.lang_item(start_crate, *self)?;
+        let t = lang_item(db, start_crate, *self)?;
         Some(Path::LangItem(t, Some(seg)))
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
index 737941dba07..28011bda7c5 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
@@ -64,8 +64,8 @@ use std::hash::{Hash, Hasher};
 
 use base_db::{Crate, impl_intern_key};
 use hir_expand::{
-    AstId, ExpandError, ExpandResult, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind,
-    MacroDefId, MacroDefKind,
+    AstId, ExpandResult, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId,
+    MacroDefKind,
     builtin::{BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander},
     db::ExpandDatabase,
     eager::expand_eager_macro_input,
@@ -79,7 +79,7 @@ use la_arena::Idx;
 use nameres::DefMap;
 use span::{AstIdNode, Edition, FileAstId, SyntaxContext};
 use stdx::impl_from;
-use syntax::{AstNode, ast};
+use syntax::ast;
 
 pub use hir_expand::{Intern, Lookup, tt};
 
@@ -554,7 +554,7 @@ pub enum ItemContainerId {
 impl_from!(ModuleId for ItemContainerId);
 
 /// A Data Type
-#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
+#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
 pub enum AdtId {
     StructId(StructId),
     UnionId(UnionId),
@@ -563,7 +563,7 @@ pub enum AdtId {
 impl_from!(StructId, UnionId, EnumId for AdtId);
 
 /// A macro
-#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
+#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
 pub enum MacroId {
     Macro2Id(Macro2Id),
     MacroRulesId(MacroRulesId),
@@ -619,7 +619,7 @@ impl_from!(
 
 /// A constant, which might appears as a const item, an anonymous const block in expressions
 /// or patterns, or as a constant in types with const generics.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
 pub enum GeneralConstId {
     ConstId(ConstId),
     StaticId(StaticId),
@@ -656,7 +656,7 @@ impl GeneralConstId {
 }
 
 /// The defs which have a body (have root expressions for type inference).
-#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
+#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
 pub enum DefWithBodyId {
     FunctionId(FunctionId),
     StaticId(StaticId),
@@ -701,7 +701,7 @@ pub enum AssocItemId {
 // casting them, and somehow making the constructors private, which would be annoying.
 impl_from!(FunctionId, ConstId, TypeAliasId for AssocItemId);
 
-#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
+#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
 pub enum GenericDefId {
     AdtId(AdtId),
     // consts can have type parameters from their parents (i.e. associated consts of traits)
@@ -790,7 +790,7 @@ impl From<AssocItemId> for GenericDefId {
     }
 }
 
-#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
+#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
 pub enum CallableDefId {
     FunctionId(FunctionId),
     StructId(StructId),
@@ -906,7 +906,7 @@ impl From<VariantId> for AttrDefId {
     }
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
 pub enum VariantId {
     EnumVariantId(EnumVariantId),
     StructId(StructId),
@@ -1166,66 +1166,6 @@ impl ModuleDefId {
         })
     }
 }
-
-// FIXME: Replace this with a plain function, it only has one impl
-/// A helper trait for converting to MacroCallId
-trait AsMacroCall {
-    fn as_call_id_with_errors(
-        &self,
-        db: &dyn ExpandDatabase,
-        krate: Crate,
-        resolver: impl Fn(&ModPath) -> Option<MacroDefId> + Copy,
-        eager_callback: &mut dyn FnMut(
-            InFile<(syntax::AstPtr<ast::MacroCall>, span::FileAstId<ast::MacroCall>)>,
-            MacroCallId,
-        ),
-    ) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro>;
-}
-
-impl AsMacroCall for InFile<&ast::MacroCall> {
-    fn as_call_id_with_errors(
-        &self,
-        db: &dyn ExpandDatabase,
-        krate: Crate,
-        resolver: impl Fn(&ModPath) -> Option<MacroDefId> + Copy,
-        eager_callback: &mut dyn FnMut(
-            InFile<(syntax::AstPtr<ast::MacroCall>, span::FileAstId<ast::MacroCall>)>,
-            MacroCallId,
-        ),
-    ) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
-        let expands_to = hir_expand::ExpandTo::from_call_site(self.value);
-        let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value));
-        let span_map = db.span_map(self.file_id);
-        let path = self.value.path().and_then(|path| {
-            let range = path.syntax().text_range();
-            let mod_path = ModPath::from_src(db, path, &mut |range| {
-                span_map.as_ref().span_for_range(range).ctx
-            })?;
-            let call_site = span_map.span_for_range(range);
-            Some((call_site, mod_path))
-        });
-
-        let Some((call_site, path)) = path else {
-            return Ok(ExpandResult::only_err(ExpandError::other(
-                span_map.span_for_range(self.value.syntax().text_range()),
-                "malformed macro invocation",
-            )));
-        };
-
-        macro_call_as_call_id_with_eager(
-            db,
-            ast_id,
-            &path,
-            call_site.ctx,
-            expands_to,
-            krate,
-            resolver,
-            resolver,
-            eager_callback,
-        )
-    }
-}
-
 /// Helper wrapper for `AstId` with `ModPath`
 #[derive(Clone, Debug, Eq, PartialEq)]
 struct AstIdWithPath<T: AstIdNode> {
@@ -1239,41 +1179,14 @@ impl<T: AstIdNode> AstIdWithPath<T> {
     }
 }
 
-fn macro_call_as_call_id(
-    db: &dyn ExpandDatabase,
-    call: &AstIdWithPath<ast::MacroCall>,
-    call_site: SyntaxContext,
-    expand_to: ExpandTo,
-    krate: Crate,
-    resolver: impl Fn(&ModPath) -> Option<MacroDefId> + Copy,
-    eager_callback: &mut dyn FnMut(
-        InFile<(syntax::AstPtr<ast::MacroCall>, span::FileAstId<ast::MacroCall>)>,
-        MacroCallId,
-    ),
-) -> Result<Option<MacroCallId>, UnresolvedMacro> {
-    macro_call_as_call_id_with_eager(
-        db,
-        call.ast_id,
-        &call.path,
-        call_site,
-        expand_to,
-        krate,
-        resolver,
-        resolver,
-        eager_callback,
-    )
-    .map(|res| res.value)
-}
-
-fn macro_call_as_call_id_with_eager(
+pub fn macro_call_as_call_id(
     db: &dyn ExpandDatabase,
     ast_id: AstId<ast::MacroCall>,
     path: &ModPath,
     call_site: SyntaxContext,
     expand_to: ExpandTo,
     krate: Crate,
-    resolver: impl FnOnce(&ModPath) -> Option<MacroDefId>,
-    eager_resolver: impl Fn(&ModPath) -> Option<MacroDefId>,
+    resolver: impl Fn(&ModPath) -> Option<MacroDefId> + Copy,
     eager_callback: &mut dyn FnMut(
         InFile<(syntax::AstPtr<ast::MacroCall>, span::FileAstId<ast::MacroCall>)>,
         MacroCallId,
@@ -1289,7 +1202,7 @@ fn macro_call_as_call_id_with_eager(
             ast_id,
             def,
             call_site,
-            &|path| eager_resolver(path).filter(MacroDefId::is_fn_like),
+            &|path| resolver(path).filter(MacroDefId::is_fn_like),
             eager_callback,
         ),
         _ if def.is_fn_like() => ExpandResult {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
index a3b48831a0b..e21d1415aa2 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
@@ -285,8 +285,6 @@ fn main() {
     /* parse error: expected expression */
 builtin #format_args (x = );
     /* parse error: expected expression */
-/* parse error: expected R_PAREN */
-/* parse error: expected expression, item or let statement */
 builtin #format_args (x = , x = 2);
     /* parse error: expected expression */
 builtin #format_args ("{}", x = );
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs
index abb5bd5ed72..38fc4b3d118 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs
@@ -2001,8 +2001,9 @@ macro_rules! bug {
         true
     };
 }
-
-let _ = bug!(a;;;test);
+fn f() {
+    let _ = bug!(a;;;test);
+}
     "#,
         expect![[r#"
 macro_rules! bug {
@@ -2022,8 +2023,9 @@ macro_rules! bug {
         true
     };
 }
-
-let _ = true;
+fn f() {
+    let _ = true;
+}
     "#]],
     );
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs
index 143b5df7730..800c96ebdae 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs
@@ -19,7 +19,7 @@ use std::{iter, ops::Range, sync};
 use base_db::RootQueryDb;
 use expect_test::Expect;
 use hir_expand::{
-    InFile, MacroCallKind, MacroKind,
+    AstId, InFile, MacroCallId, MacroCallKind, MacroKind,
     db::ExpandDatabase,
     proc_macro::{ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind},
     span_map::SpanMapRef,
@@ -29,7 +29,7 @@ use itertools::Itertools;
 use span::{Edition, Span};
 use stdx::{format_to, format_to_acc};
 use syntax::{
-    AstNode,
+    AstNode, AstPtr,
     SyntaxKind::{COMMENT, EOF, IDENT, LIFETIME_IDENT},
     SyntaxNode, T,
     ast::{self, edit::IndentLevel},
@@ -37,10 +37,9 @@ use syntax::{
 use test_fixture::WithFixture;
 
 use crate::{
-    AdtId, AsMacroCall, Lookup, ModuleDefId,
+    AdtId, Lookup, ModuleDefId,
     db::DefDatabase,
-    nameres::{DefMap, MacroSubNs, ModuleSource},
-    resolver::HasResolver,
+    nameres::{DefMap, ModuleSource},
     src::HasSource,
     test_db::TestDB,
     tt::TopSubtree,
@@ -78,7 +77,6 @@ fn check_errors(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect)
     expect.assert_eq(&errors);
 }
 
-#[track_caller]
 fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, mut expect: Expect) {
     let extra_proc_macros = vec![(
         r#"
@@ -95,54 +93,59 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
             disabled: false,
         },
     )];
+
+    fn resolve(
+        db: &dyn DefDatabase,
+        def_map: &DefMap,
+        ast_id: AstId<ast::MacroCall>,
+        ast_ptr: InFile<AstPtr<ast::MacroCall>>,
+    ) -> Option<MacroCallId> {
+        def_map.modules().find_map(|module| {
+            for decl in
+                module.1.scope.declarations().chain(module.1.scope.unnamed_consts().map(Into::into))
+            {
+                let body = match decl {
+                    ModuleDefId::FunctionId(it) => it.into(),
+                    ModuleDefId::ConstId(it) => it.into(),
+                    ModuleDefId::StaticId(it) => it.into(),
+                    _ => continue,
+                };
+
+                let (body, sm) = db.body_with_source_map(body);
+                if let Some(it) =
+                    body.blocks(db).find_map(|block| resolve(db, &block.1, ast_id, ast_ptr))
+                {
+                    return Some(it);
+                }
+                if let Some((_, res)) = sm.macro_calls().find(|it| it.0 == ast_ptr) {
+                    return Some(res);
+                }
+            }
+            module.1.scope.macro_invoc(ast_id)
+        })
+    }
+
     let db = TestDB::with_files_extra_proc_macros(ra_fixture, extra_proc_macros);
     let krate = db.fetch_test_crate();
     let def_map = db.crate_def_map(krate);
     let local_id = DefMap::ROOT;
-    let module = def_map.module_id(local_id);
-    let resolver = module.resolver(&db);
     let source = def_map[local_id].definition_source(&db);
     let source_file = match source.value {
         ModuleSource::SourceFile(it) => it,
         ModuleSource::Module(_) | ModuleSource::BlockExpr(_) => panic!(),
     };
 
-    // What we want to do is to replace all macros (fn-like, derive, attr) with
-    // their expansions. Turns out, we don't actually store enough information
-    // to do this precisely though! Specifically, if a macro expands to nothing,
-    // it leaves zero traces in def-map, so we can't get its expansion after the
-    // fact.
-    //
-    // This is the usual
-    // <https://github.com/rust-lang/rust-analyzer/issues/3407>
-    // resolve/record tension!
-    //
-    // So here we try to do a resolve, which is necessary a heuristic. For macro
-    // calls, we use `as_call_id_with_errors`. For derives, we look at the impls
-    // in the module and assume that, if impls's source is a different
-    // `HirFileId`, than it came from macro expansion.
-
     let mut text_edits = Vec::new();
     let mut expansions = Vec::new();
 
-    for macro_call in source_file.syntax().descendants().filter_map(ast::MacroCall::cast) {
-        let macro_call = InFile::new(source.file_id, &macro_call);
-        let res = macro_call
-            .as_call_id_with_errors(
-                &db,
-                krate,
-                |path| {
-                    resolver
-                        .resolve_path_as_macro(&db, path, Some(MacroSubNs::Bang))
-                        .map(|(it, _)| db.macro_def(it))
-                },
-                &mut |_, _| (),
-            )
-            .unwrap();
-        let macro_call_id = res.value.unwrap();
-        let mut expansion_result = db.parse_macro_expansion(macro_call_id);
-        expansion_result.err = expansion_result.err.or(res.err);
-        expansions.push((macro_call.value.clone(), expansion_result));
+    for macro_call_node in source_file.syntax().descendants().filter_map(ast::MacroCall::cast) {
+        let ast_id = db.ast_id_map(source.file_id).ast_id(&macro_call_node);
+        let ast_id = InFile::new(source.file_id, ast_id);
+        let ptr = InFile::new(source.file_id, AstPtr::new(&macro_call_node));
+        let macro_call_id = resolve(&db, &def_map, ast_id, ptr)
+            .unwrap_or_else(|| panic!("unable to find semantic macro call {macro_call_node}"));
+        let expansion_result = db.parse_macro_expansion(macro_call_id);
+        expansions.push((macro_call_node.clone(), expansion_result));
     }
 
     for (call, exp) in expansions.into_iter().rev() {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs
index b0970655294..448b908936a 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs
@@ -259,7 +259,8 @@ impl<'a> AssocItemCollector<'a> {
                 };
                 match macro_call_as_call_id(
                     self.db,
-                    &AstIdWithPath::new(tree_id.file_id(), ast_id, Clone::clone(path)),
+                    InFile::new(tree_id.file_id(), ast_id),
+                    path,
                     ctxt,
                     expand_to,
                     self.module_id.krate(),
@@ -268,12 +269,15 @@ impl<'a> AssocItemCollector<'a> {
                         self.macro_calls.push((ptr.map(|(_, it)| it.upcast()), call_id))
                     },
                 ) {
-                    Ok(Some(call_id)) => {
-                        self.macro_calls
-                            .push((InFile::new(tree_id.file_id(), ast_id.upcast()), call_id));
-                        self.collect_macro_items(call_id);
-                    }
-                    Ok(None) => (),
+                    // FIXME: Expansion error?
+                    Ok(call_id) => match call_id.value {
+                        Some(call_id) => {
+                            self.macro_calls
+                                .push((InFile::new(tree_id.file_id(), ast_id.upcast()), call_id));
+                            self.collect_macro_items(call_id);
+                        }
+                        None => (),
+                    },
                     Err(_) => {
                         self.diagnostics.push(DefDiagnostic::unresolved_macro_call(
                             self.module_id.local_id,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
index 77effbcc880..8df0f092cd0 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
@@ -39,7 +39,7 @@ use crate::{
         ItemTreeId, ItemTreeNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId,
         UseTreeKind,
     },
-    macro_call_as_call_id, macro_call_as_call_id_with_eager,
+    macro_call_as_call_id,
     nameres::{
         BuiltinShadowMode, DefMap, LocalDefMap, MacroSubNs, ModuleData, ModuleOrigin, ResolveMode,
         attr_resolution::{attr_macro_as_call_id, derive_macro_as_call_id},
@@ -1256,7 +1256,8 @@ impl DefCollector<'_> {
                 MacroDirectiveKind::FnLike { ast_id, expand_to, ctxt: call_site } => {
                     let call_id = macro_call_as_call_id(
                         self.db,
-                        ast_id,
+                        ast_id.ast_id,
+                        &ast_id.path,
                         *call_site,
                         *expand_to,
                         self.def_map.krate,
@@ -1265,15 +1266,18 @@ impl DefCollector<'_> {
                             eager_callback_buffer.push((directive.module_id, ptr, call_id));
                         },
                     );
-                    if let Ok(Some(call_id)) = call_id {
-                        self.def_map.modules[directive.module_id]
-                            .scope
-                            .add_macro_invoc(ast_id.ast_id, call_id);
+                    if let Ok(call_id) = call_id {
+                        // FIXME: Expansion error
+                        if let Some(call_id) = call_id.value {
+                            self.def_map.modules[directive.module_id]
+                                .scope
+                                .add_macro_invoc(ast_id.ast_id, call_id);
 
-                        push_resolved(directive, call_id);
+                            push_resolved(directive, call_id);
 
-                        res = ReachedFixedPoint::No;
-                        return Resolved::Yes;
+                            res = ReachedFixedPoint::No;
+                            return Resolved::Yes;
+                        }
                     }
                 }
                 MacroDirectiveKind::Derive {
@@ -1542,7 +1546,8 @@ impl DefCollector<'_> {
                     // FIXME: we shouldn't need to re-resolve the macro here just to get the unresolved error!
                     let macro_call_as_call_id = macro_call_as_call_id(
                         self.db,
-                        ast_id,
+                        ast_id.ast_id,
+                        &ast_id.path,
                         *call_site,
                         *expand_to,
                         self.def_map.krate,
@@ -2420,7 +2425,7 @@ impl ModCollector<'_, '_> {
 
         let mut eager_callback_buffer = vec![];
         // Case 1: try to resolve macro calls with single-segment name and expand macro_rules
-        if let Ok(res) = macro_call_as_call_id_with_eager(
+        if let Ok(res) = macro_call_as_call_id(
             db,
             ast_id.ast_id,
             &ast_id.path,
@@ -2445,21 +2450,6 @@ impl ModCollector<'_, '_> {
                         .map(|it| self.def_collector.db.macro_def(it))
                 })
             },
-            |path| {
-                let resolved_res = self.def_collector.def_map.resolve_path_fp_with_macro(
-                    self.def_collector
-                        .crate_local_def_map
-                        .as_deref()
-                        .unwrap_or(&self.def_collector.local_def_map),
-                    db,
-                    ResolveMode::Other,
-                    self.module_id,
-                    path,
-                    BuiltinShadowMode::Module,
-                    Some(MacroSubNs::Bang),
-                );
-                resolved_res.resolved_def.take_macros().map(|it| db.macro_def(it))
-            },
             &mut |ptr, call_id| eager_callback_buffer.push((ptr, call_id)),
         ) {
             for (ptr, call_id) in eager_callback_buffer {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs
index d6c9f5a00c9..0c50f13edfb 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs
@@ -86,7 +86,7 @@ impl ModDir {
                 let dir_path = if root_dir_owner {
                     DirPath::empty()
                 } else {
-                    DirPath::new(format!("{}/", name))
+                    DirPath::new(format!("{name}/"))
                 };
                 if let Some(mod_dir) = self.child(dir_path, !root_dir_owner) {
                     return Ok((
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs
index f8b2c73a8f6..a49155d878c 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs
@@ -673,12 +673,11 @@ impl DefMap {
     }
 
     fn resolve_in_macro_use_prelude(&self, name: &Name) -> PerNs {
-        self.macro_use_prelude.get(name).map_or(PerNs::none(), |&(it, _extern_crate)| {
+        self.macro_use_prelude.get(name).map_or(PerNs::none(), |&(it, extern_crate)| {
             PerNs::macros(
                 it,
                 Visibility::Public,
-                // FIXME?
-                None, // extern_crate.map(ImportOrExternCrate::ExternCrate),
+                extern_crate.map(ImportOrExternCrate::ExternCrate),
             )
         })
     }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs b/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs
index 1f7dd6f0c40..8721cd65dba 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs
@@ -37,7 +37,8 @@ pub struct Item<Def, Import = ImportId> {
 
 pub type TypesItem = Item<ModuleDefId, ImportOrExternCrate>;
 pub type ValuesItem = Item<ModuleDefId, ImportOrGlob>;
-pub type MacrosItem = Item<MacroId, ImportOrGlob>;
+// May be Externcrate for `[macro_use]`'d macros
+pub type MacrosItem = Item<MacroId, ImportOrExternCrate>;
 
 #[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
 pub struct PerNs {
@@ -84,7 +85,7 @@ impl PerNs {
         }
     }
 
-    pub fn macros(def: MacroId, vis: Visibility, import: Option<ImportOrGlob>) -> PerNs {
+    pub fn macros(def: MacroId, vis: Visibility, import: Option<ImportOrExternCrate>) -> PerNs {
         PerNs { types: None, values: None, macros: Some(Item { def, vis, import }) }
     }
 
@@ -116,7 +117,7 @@ impl PerNs {
         self.macros.map(|it| it.def)
     }
 
-    pub fn take_macros_import(self) -> Option<(MacroId, Option<ImportOrGlob>)> {
+    pub fn take_macros_import(self) -> Option<(MacroId, Option<ImportOrExternCrate>)> {
         self.macros.map(|it| (it.def, it.import))
     }
 
@@ -158,9 +159,6 @@ impl PerNs {
                 self.values
                     .map(|it| (ItemInNs::Values(it.def), it.import.map(ImportOrExternCrate::from))),
             )
-            .chain(
-                self.macros
-                    .map(|it| (ItemInNs::Macros(it.def), it.import.map(ImportOrExternCrate::from))),
-            )
+            .chain(self.macros.map(|it| (ItemInNs::Macros(it.def), it.import)))
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
index 46c12574fde..8a8d17018c1 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
@@ -493,7 +493,7 @@ impl Resolver {
         db: &dyn DefDatabase,
         path: &ModPath,
         expected_macro_kind: Option<MacroSubNs>,
-    ) -> Option<(MacroId, Option<ImportOrGlob>)> {
+    ) -> Option<(MacroId, Option<ImportOrExternCrate>)> {
         let (item_map, item_local_map, module) = self.item_scope_();
         item_map
             .resolve_path(
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs b/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs
index 2f7675134ca..47097548295 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs
@@ -19,7 +19,7 @@ use crate::{
     src::HasSource,
 };
 
-#[salsa::db]
+#[salsa_macros::db]
 #[derive(Clone)]
 pub(crate) struct TestDB {
     storage: salsa::Storage<Self>,
@@ -44,7 +44,7 @@ impl Default for TestDB {
     }
 }
 
-#[salsa::db]
+#[salsa_macros::db]
 impl salsa::Database for TestDB {
     fn salsa_event(&self, event: &dyn std::ops::Fn() -> salsa::Event) {
         let mut events = self.events.lock().unwrap();
@@ -63,7 +63,7 @@ impl fmt::Debug for TestDB {
 
 impl panic::RefUnwindSafe for TestDB {}
 
-#[salsa::db]
+#[salsa_macros::db]
 impl SourceDatabase for TestDB {
     fn file_text(&self, file_id: base_db::FileId) -> FileText {
         self.files.file_text(file_id)
diff --git a/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml b/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml
index b83efca2552..ed818c5be3f 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml
@@ -21,6 +21,7 @@ smallvec.workspace = true
 triomphe.workspace = true
 query-group.workspace = true
 salsa.workspace = true
+salsa-macros.workspace = true
 
 # local deps
 stdx.workspace = true
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs
index 5dae27f7a16..bb17eb06276 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs
@@ -2,7 +2,7 @@
 use std::{borrow::Cow, fmt, ops};
 
 use base_db::Crate;
-use cfg::CfgExpr;
+use cfg::{CfgExpr, CfgOptions};
 use either::Either;
 use intern::{Interned, Symbol, sym};
 
@@ -14,11 +14,10 @@ use syntax::{AstNode, AstToken, SyntaxNode, ast, match_ast};
 use syntax_bridge::{DocCommentDesugarMode, desugar_doc_comment_text, syntax_node_to_token_tree};
 use triomphe::ThinArc;
 
-use crate::name::Name;
 use crate::{
-    InFile,
     db::ExpandDatabase,
     mod_path::ModPath,
+    name::Name,
     span_map::SpanMapRef,
     tt::{self, TopSubtree, token_to_literal},
 };
@@ -49,29 +48,7 @@ impl RawAttrs {
         owner: &dyn ast::HasAttrs,
         span_map: SpanMapRef<'_>,
     ) -> Self {
-        let entries: Vec<_> = collect_attrs(owner)
-            .filter_map(|(id, attr)| match attr {
-                Either::Left(attr) => {
-                    attr.meta().and_then(|meta| Attr::from_src(db, meta, span_map, id))
-                }
-                Either::Right(comment) => comment.doc_comment().map(|doc| {
-                    let span = span_map.span_for_range(comment.syntax().text_range());
-                    let (text, kind) =
-                        desugar_doc_comment_text(doc, DocCommentDesugarMode::ProcMacro);
-                    Attr {
-                        id,
-                        input: Some(Box::new(AttrInput::Literal(tt::Literal {
-                            symbol: text,
-                            span,
-                            kind,
-                            suffix: None,
-                        }))),
-                        path: Interned::new(ModPath::from(Name::new_symbol(sym::doc, span.ctx))),
-                        ctxt: span.ctx,
-                    }
-                }),
-            })
-            .collect();
+        let entries: Vec<_> = Self::attrs_iter::<true>(db, owner, span_map).collect();
 
         let entries = if entries.is_empty() {
             None
@@ -82,12 +59,61 @@ impl RawAttrs {
         RawAttrs { entries }
     }
 
-    pub fn from_attrs_owner(
+    /// A [`RawAttrs`] that has its `#[cfg_attr(...)]` attributes expanded.
+    pub fn new_expanded(
         db: &dyn ExpandDatabase,
-        owner: InFile<&dyn ast::HasAttrs>,
+        owner: &dyn ast::HasAttrs,
         span_map: SpanMapRef<'_>,
+        cfg_options: &CfgOptions,
     ) -> Self {
-        Self::new(db, owner.value, span_map)
+        let entries: Vec<_> =
+            Self::attrs_iter_expanded::<true>(db, owner, span_map, cfg_options).collect();
+
+        let entries = if entries.is_empty() {
+            None
+        } else {
+            Some(ThinArc::from_header_and_iter((), entries.into_iter()))
+        };
+
+        RawAttrs { entries }
+    }
+
+    pub fn attrs_iter<const DESUGAR_COMMENTS: bool>(
+        db: &dyn ExpandDatabase,
+        owner: &dyn ast::HasAttrs,
+        span_map: SpanMapRef<'_>,
+    ) -> impl Iterator<Item = Attr> {
+        collect_attrs(owner).filter_map(move |(id, attr)| match attr {
+            Either::Left(attr) => {
+                attr.meta().and_then(|meta| Attr::from_src(db, meta, span_map, id))
+            }
+            Either::Right(comment) if DESUGAR_COMMENTS => comment.doc_comment().map(|doc| {
+                let span = span_map.span_for_range(comment.syntax().text_range());
+                let (text, kind) = desugar_doc_comment_text(doc, DocCommentDesugarMode::ProcMacro);
+                Attr {
+                    id,
+                    input: Some(Box::new(AttrInput::Literal(tt::Literal {
+                        symbol: text,
+                        span,
+                        kind,
+                        suffix: None,
+                    }))),
+                    path: Interned::new(ModPath::from(Name::new_symbol(sym::doc, span.ctx))),
+                    ctxt: span.ctx,
+                }
+            }),
+            Either::Right(_) => None,
+        })
+    }
+
+    pub fn attrs_iter_expanded<const DESUGAR_COMMENTS: bool>(
+        db: &dyn ExpandDatabase,
+        owner: &dyn ast::HasAttrs,
+        span_map: SpanMapRef<'_>,
+        cfg_options: &CfgOptions,
+    ) -> impl Iterator<Item = Attr> {
+        Self::attrs_iter::<DESUGAR_COMMENTS>(db, owner, span_map)
+            .flat_map(|attr| attr.expand_cfg_attr(db, cfg_options))
     }
 
     pub fn merge(&self, other: Self) -> Self {
@@ -114,9 +140,8 @@ impl RawAttrs {
         }
     }
 
-    /// Processes `cfg_attr`s, returning the resulting semantic `Attrs`.
-    // FIXME: This should return a different type, signaling it was filtered?
-    pub fn filter(self, db: &dyn ExpandDatabase, krate: Crate) -> RawAttrs {
+    /// Processes `cfg_attr`s
+    pub fn expand_cfg_attr(self, db: &dyn ExpandDatabase, krate: Crate) -> RawAttrs {
         let has_cfg_attrs =
             self.iter().any(|attr| attr.path.as_ident().is_some_and(|name| *name == sym::cfg_attr));
         if !has_cfg_attrs {
@@ -126,37 +151,8 @@ impl RawAttrs {
         let cfg_options = krate.cfg_options(db);
         let new_attrs = self
             .iter()
-            .flat_map(|attr| -> SmallVec<[_; 1]> {
-                let is_cfg_attr = attr.path.as_ident().is_some_and(|name| *name == sym::cfg_attr);
-                if !is_cfg_attr {
-                    return smallvec![attr.clone()];
-                }
-
-                let subtree = match attr.token_tree_value() {
-                    Some(it) => it,
-                    _ => return smallvec![attr.clone()],
-                };
-
-                let (cfg, parts) = match parse_cfg_attr_input(subtree) {
-                    Some(it) => it,
-                    None => return smallvec![attr.clone()],
-                };
-                let index = attr.id;
-                let attrs = parts
-                    .enumerate()
-                    .take(1 << AttrId::CFG_ATTR_BITS)
-                    .filter_map(|(idx, attr)| Attr::from_tt(db, attr, index.with_cfg_attr(idx)));
-
-                let cfg = TopSubtree::from_token_trees(subtree.top_subtree().delimiter, cfg);
-                let cfg = CfgExpr::parse(&cfg);
-                if cfg_options.check(&cfg) == Some(false) {
-                    smallvec![]
-                } else {
-                    cov_mark::hit!(cfg_attr_active);
-
-                    attrs.collect()
-                }
-            })
+            .cloned()
+            .flat_map(|attr| attr.expand_cfg_attr(db, cfg_options))
             .collect::<Vec<_>>();
         let entries = if new_attrs.is_empty() {
             None
@@ -316,6 +312,42 @@ impl Attr {
     pub fn path(&self) -> &ModPath {
         &self.path
     }
+
+    pub fn expand_cfg_attr(
+        self,
+        db: &dyn ExpandDatabase,
+        cfg_options: &CfgOptions,
+    ) -> impl IntoIterator<Item = Self> {
+        let is_cfg_attr = self.path.as_ident().is_some_and(|name| *name == sym::cfg_attr);
+        if !is_cfg_attr {
+            return smallvec![self];
+        }
+
+        let subtree = match self.token_tree_value() {
+            Some(it) => it,
+            _ => return smallvec![self.clone()],
+        };
+
+        let (cfg, parts) = match parse_cfg_attr_input(subtree) {
+            Some(it) => it,
+            None => return smallvec![self.clone()],
+        };
+        let index = self.id;
+        let attrs = parts
+            .enumerate()
+            .take(1 << AttrId::CFG_ATTR_BITS)
+            .filter_map(|(idx, attr)| Attr::from_tt(db, attr, index.with_cfg_attr(idx)));
+
+        let cfg = TopSubtree::from_token_trees(subtree.top_subtree().delimiter, cfg);
+        let cfg = CfgExpr::parse(&cfg);
+        if cfg_options.check(&cfg) == Some(false) {
+            smallvec![]
+        } else {
+            cov_mark::hit!(cfg_attr_active);
+
+            attrs.collect::<SmallVec<[_; 1]>>()
+        }
+    }
 }
 
 impl Attr {
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/change.rs b/src/tools/rust-analyzer/crates/hir-expand/src/change.rs
index 6873cb7eaf9..3959741e6f1 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/change.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/change.rs
@@ -1,7 +1,6 @@
 //! Defines a unit of change that can applied to the database to get the next
 //! state. Changes are transactional.
-use base_db::{CrateGraphBuilder, FileChange, SourceRoot};
-use salsa::Durability;
+use base_db::{CrateGraphBuilder, FileChange, SourceRoot, salsa::Durability};
 use span::FileId;
 use triomphe::Arc;
 
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs
index 29b7b33fd0f..7cb1b6c0207 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs
@@ -18,10 +18,7 @@ use crate::{
     cfg_process,
     declarative::DeclarativeMacroExpander,
     fixup::{self, SyntaxFixupUndoInfo},
-    hygiene::{
-        SyntaxContextExt as _, span_with_call_site_ctxt, span_with_def_site_ctxt,
-        span_with_mixed_site_ctxt,
-    },
+    hygiene::{span_with_call_site_ctxt, span_with_def_site_ctxt, span_with_mixed_site_ctxt},
     proc_macro::{CrateProcMacros, CustomProcMacroExpander, ProcMacros},
     span_map::{ExpansionSpanMap, RealSpanMap, SpanMap, SpanMapRef},
     tt,
@@ -147,7 +144,7 @@ pub trait ExpandDatabase: RootQueryDb {
     fn syntax_context(&self, file: HirFileId, edition: Edition) -> SyntaxContext;
 }
 
-#[salsa::interned(no_lifetime, id = span::SyntaxContext)]
+#[salsa_macros::interned(no_lifetime, id = span::SyntaxContext)]
 pub struct SyntaxContextWrapper {
     pub data: SyntaxContext,
 }
@@ -752,8 +749,7 @@ fn check_tt_count(tt: &tt::TopSubtree) -> Result<(), ExpandResult<()>> {
             err: Some(ExpandError::other(
                 tt.delimiter.open,
                 format!(
-                    "macro invocation exceeds token limit: produced {} tokens, limit is {}",
-                    count, TOKEN_LIMIT,
+                    "macro invocation exceeds token limit: produced {count} tokens, limit is {TOKEN_LIMIT}",
                 ),
             )),
         })
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs
index 1fa682ce3a2..0d100c1364a 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs
@@ -82,7 +82,7 @@ impl DeclarativeMacroExpander {
 
         let transparency = |node| {
             // ... would be nice to have the item tree here
-            let attrs = RawAttrs::new(db, node, map.as_ref()).filter(db, def_crate);
+            let attrs = RawAttrs::new_expanded(db, node, map.as_ref(), def_crate.cfg_options(db));
             match attrs
                 .iter()
                 .find(|it| {
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs b/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs
index e7856920bc4..28800c6fabd 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs
@@ -22,7 +22,7 @@
 // FIXME: Move this into the span crate? Not quite possible today as that depends on `MacroCallLoc`
 // which contains a bunch of unrelated things
 
-use std::{convert::identity, iter};
+use std::convert::identity;
 
 use span::{Edition, MacroCallId, Span, SyntaxContext};
 
@@ -141,61 +141,3 @@ fn apply_mark_internal(
         |_| opaque_and_semitransparent,
     )
 }
-
-pub trait SyntaxContextExt {
-    fn normalize_to_macro_rules(self, db: &dyn ExpandDatabase) -> span::SyntaxContext;
-    fn normalize_to_macros_2_0(self, db: &dyn ExpandDatabase) -> span::SyntaxContext;
-    fn parent_ctxt(self, db: &dyn ExpandDatabase) -> span::SyntaxContext;
-    fn remove_mark(&mut self, db: &dyn ExpandDatabase)
-    -> (Option<span::MacroCallId>, Transparency);
-    fn outer_mark(self, db: &dyn ExpandDatabase) -> (Option<span::MacroCallId>, Transparency);
-    fn marks(self, db: &dyn ExpandDatabase) -> Vec<(span::MacroCallId, Transparency)>;
-    fn is_opaque(self, db: &dyn ExpandDatabase) -> bool;
-}
-
-impl SyntaxContextExt for SyntaxContext {
-    fn normalize_to_macro_rules(self, db: &dyn ExpandDatabase) -> span::SyntaxContext {
-        self.opaque_and_semitransparent(db)
-    }
-    fn normalize_to_macros_2_0(self, db: &dyn ExpandDatabase) -> span::SyntaxContext {
-        self.opaque(db)
-    }
-    fn parent_ctxt(self, db: &dyn ExpandDatabase) -> span::SyntaxContext {
-        self.parent(db)
-    }
-    fn outer_mark(self, db: &dyn ExpandDatabase) -> (Option<span::MacroCallId>, Transparency) {
-        let data = self;
-        (data.outer_expn(db), data.outer_transparency(db))
-    }
-    fn remove_mark(
-        &mut self,
-        db: &dyn ExpandDatabase,
-    ) -> (Option<span::MacroCallId>, Transparency) {
-        let data = *self;
-        *self = data.parent(db);
-        (data.outer_expn(db), data.outer_transparency(db))
-    }
-    fn marks(self, db: &dyn ExpandDatabase) -> Vec<(span::MacroCallId, Transparency)> {
-        let mut marks = marks_rev(self, db).collect::<Vec<_>>();
-        marks.reverse();
-        marks
-    }
-    fn is_opaque(self, db: &dyn ExpandDatabase) -> bool {
-        !self.is_root() && self.outer_transparency(db).is_opaque()
-    }
-}
-
-// FIXME: Make this a SyntaxContextExt method once we have RPIT
-pub fn marks_rev(
-    ctxt: SyntaxContext,
-    db: &dyn ExpandDatabase,
-) -> impl Iterator<Item = (span::MacroCallId, Transparency)> + '_ {
-    iter::successors(Some(ctxt), move |&mark| Some(mark.parent_ctxt(db)))
-        .take_while(|&it| !it.is_root())
-        .map(|ctx| {
-            let mark = ctx.outer_mark(db);
-            // We stop before taking the root expansion, as such we cannot encounter a `None` outer
-            // expansion, as only the ROOT has it.
-            (mark.0.unwrap(), mark.1)
-        })
-}
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
index f0a9a2ad52c..d844d8f41ee 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
@@ -206,8 +206,7 @@ impl ExpandErrorKind {
                     },
                     None => RenderedExpandError {
                         message: format!(
-                            "internal error: proc-macro map is missing error entry for crate {:?}",
-                            def_crate
+                            "internal error: proc-macro map is missing error entry for crate {def_crate:?}"
                         ),
                         error: true,
                         kind: RenderedExpandError::GENERAL_KIND,
@@ -1051,7 +1050,7 @@ impl ExpandTo {
 
 intern::impl_internable!(ModPath, attrs::AttrInput);
 
-#[salsa::interned(no_lifetime, debug)]
+#[salsa_macros::interned(no_lifetime, debug)]
 #[doc(alias = "MacroFileId")]
 pub struct MacroCallId {
     pub loc: MacroCallLoc,
@@ -1071,7 +1070,7 @@ impl From<MacroCallId> for span::MacroCallId {
     }
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
 pub enum HirFileId {
     FileId(EditionedFileId),
     MacroFile(MacroCallId),
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs
index 72a5627636b..9f1e3879e1e 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs
@@ -7,7 +7,7 @@ use std::{
 
 use crate::{
     db::ExpandDatabase,
-    hygiene::{SyntaxContextExt, Transparency, marks_rev},
+    hygiene::Transparency,
     name::{AsName, Name},
     tt,
 };
@@ -340,7 +340,7 @@ pub fn resolve_crate_root(db: &dyn ExpandDatabase, mut ctxt: SyntaxContext) -> O
     // definitions actually produced by `macro` and `macro` definitions produced by
     // `macro_rules!`, but at least such configurations are not stable yet.
     ctxt = ctxt.normalize_to_macro_rules(db);
-    let mut iter = marks_rev(ctxt, db).peekable();
+    let mut iter = ctxt.marks_rev(db).peekable();
     let mut result_mark = None;
     // Find the last opaque mark from the end if it exists.
     while let Some(&(mark, Transparency::Opaque)) = iter.peek() {
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs
index d43ef38f291..217d991d110 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs
@@ -191,7 +191,7 @@ impl Name {
     // FIXME: Remove this in favor of `display`, see fixme on `as_str`
     #[doc(hidden)]
     pub fn display_no_db(&self, edition: Edition) -> impl fmt::Display + '_ {
-        Display { name: self, needs_escaping: is_raw_identifier(self.symbol.as_str(), edition) }
+        Display { name: self, edition }
     }
 
     pub fn symbol(&self) -> &Symbol {
@@ -201,15 +201,28 @@ impl Name {
 
 struct Display<'a> {
     name: &'a Name,
-    needs_escaping: bool,
+    edition: Edition,
 }
 
 impl fmt::Display for Display<'_> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        if self.needs_escaping {
-            write!(f, "r#")?;
+        let mut symbol = self.name.symbol.as_str();
+
+        if symbol == "'static" {
+            // FIXME: '`static` can also be a label, and there it does need escaping.
+            // But knowing where it is will require adding a parameter to `display()`,
+            // and that is an infectious change.
+            return f.write_str(symbol);
+        }
+
+        if let Some(s) = symbol.strip_prefix('\'') {
+            f.write_str("'")?;
+            symbol = s;
+        }
+        if is_raw_identifier(symbol, self.edition) {
+            f.write_str("r#")?;
         }
-        fmt::Display::fmt(self.name.symbol.as_str(), f)
+        f.write_str(symbol)
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml
index 69ad7703c2c..efa544cf396 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml
@@ -34,6 +34,7 @@ indexmap.workspace = true
 rustc_apfloat = "0.2.2"
 query-group.workspace = true
 salsa.workspace = true
+salsa-macros.workspace = true
 
 ra-ap-rustc_abi.workspace = true
 ra-ap-rustc_index.workspace = true
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs b/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs
index 71154454568..7acc9456ec9 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs
@@ -198,15 +198,13 @@ pub(crate) fn deref_by_trait(
         // blanked impl on `Deref`.
         #[expect(clippy::overly_complex_bool_expr)]
         if use_receiver_trait && false {
-            if let Some(receiver) =
-                db.lang_item(table.trait_env.krate, LangItem::Receiver).and_then(|l| l.as_trait())
-            {
+            if let Some(receiver) = LangItem::Receiver.resolve_trait(db, table.trait_env.krate) {
                 return Some(receiver);
             }
         }
         // Old rustc versions might not have `Receiver` trait.
         // Fallback to `Deref` if they don't
-        db.lang_item(table.trait_env.krate, LangItem::Deref).and_then(|l| l.as_trait())
+        LangItem::Deref.resolve_trait(db, table.trait_env.krate)
     };
     let trait_id = trait_id()?;
     let target =
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 2aa9401eefa..cd799c03ddf 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
@@ -16,7 +16,7 @@ use hir_def::{
     AssocItemId, BlockId, CallableDefId, GenericDefId, HasModule, ItemContainerId, Lookup,
     TypeAliasId, VariantId,
     hir::Movability,
-    lang_item::{LangItem, LangItemTarget},
+    lang_item::LangItem,
     signatures::{ImplFlags, StructFlags, TraitFlags},
 };
 
@@ -262,10 +262,7 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
         well_known_trait: rust_ir::WellKnownTrait,
     ) -> Option<chalk_ir::TraitId<Interner>> {
         let lang_attr = lang_item_from_well_known_trait(well_known_trait);
-        let trait_ = match self.db.lang_item(self.krate, lang_attr) {
-            Some(LangItemTarget::Trait(trait_)) => trait_,
-            _ => return None,
-        };
+        let trait_ = lang_attr.resolve_trait(self.db, self.krate)?;
         Some(to_chalk_trait_id(trait_))
     }
 
@@ -306,11 +303,8 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
                 chalk_ir::Binders::new(binders, bound)
             }
             crate::ImplTraitId::AsyncBlockTypeImplTrait(..) => {
-                if let Some((future_trait, future_output)) = self
-                    .db
-                    .lang_item(self.krate, LangItem::Future)
-                    .and_then(|item| item.as_trait())
-                    .and_then(|trait_| {
+                if let Some((future_trait, future_output)) =
+                    LangItem::Future.resolve_trait(self.db, self.krate).and_then(|trait_| {
                         let alias = self
                             .db
                             .trait_items(trait_)
@@ -338,10 +332,7 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
                     });
                     let mut binder = vec![];
                     binder.push(crate::wrap_empty_binders(impl_bound));
-                    let sized_trait = self
-                        .db
-                        .lang_item(self.krate, LangItem::Sized)
-                        .and_then(|item| item.as_trait());
+                    let sized_trait = LangItem::Sized.resolve_trait(self.db, self.krate);
                     if let Some(sized_trait_) = sized_trait {
                         let sized_bound = WhereClause::Implemented(TraitRef {
                             trait_id: to_chalk_trait_id(sized_trait_),
@@ -646,7 +637,10 @@ pub(crate) fn associated_ty_data_query(
         .fill_with_bound_vars(crate::DebruijnIndex::INNERMOST, 0)
         .build();
     let pro_ty = TyBuilder::assoc_type_projection(db, type_alias, Some(trait_subst))
-        .fill_with_bound_vars(crate::DebruijnIndex::INNERMOST, generic_params.len_self())
+        .fill_with_bound_vars(
+            crate::DebruijnIndex::INNERMOST,
+            generic_params.parent_generics().map_or(0, |it| it.len()),
+        )
         .build();
     let self_ty = TyKind::Alias(AliasTy::Projection(pro_ty)).intern(Interner);
 
@@ -660,9 +654,8 @@ pub(crate) fn associated_ty_data_query(
     }
 
     if !ctx.unsized_types.contains(&self_ty) {
-        let sized_trait = db
-            .lang_item(resolver.krate(), LangItem::Sized)
-            .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
+        let sized_trait =
+            LangItem::Sized.resolve_trait(db, resolver.krate()).map(to_chalk_trait_id);
         let sized_bound = sized_trait.into_iter().map(|sized_trait| {
             let trait_bound =
                 rust_ir::TraitBound { trait_id: sized_trait, args_no_self: Default::default() };
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs
index 0f0cf6ae7ae..aabc4c4234d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs
@@ -251,9 +251,7 @@ impl TyExt for Ty {
                 match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) {
                     ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => {
                         let krate = def.module(db).krate();
-                        if let Some(future_trait) =
-                            db.lang_item(krate, LangItem::Future).and_then(|item| item.as_trait())
-                        {
+                        if let Some(future_trait) = LangItem::Future.resolve_trait(db, krate) {
                             // This is only used by type walking.
                             // Parameters will be walked outside, and projection predicate is not used.
                             // So just provide the Future trait.
@@ -364,8 +362,7 @@ impl TyExt for Ty {
 
     fn is_copy(self, db: &dyn HirDatabase, owner: DefWithBodyId) -> bool {
         let crate_id = owner.module(db).krate();
-        let Some(copy_trait) = db.lang_item(crate_id, LangItem::Copy).and_then(|it| it.as_trait())
-        else {
+        let Some(copy_trait) = LangItem::Copy.resolve_trait(db, crate_id) else {
             return false;
         };
         let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(self).build();
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs
index c24ef16b496..980ee264b02 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs
@@ -283,8 +283,9 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
 
     #[salsa::invoke(crate::variance::variances_of)]
     #[salsa::cycle(
-        cycle_fn = crate::variance::variances_of_cycle_fn,
-        cycle_initial = crate::variance::variances_of_cycle_initial,
+        // cycle_fn = crate::variance::variances_of_cycle_fn,
+        // cycle_initial = crate::variance::variances_of_cycle_initial,
+        cycle_result = crate::variance::variances_of_cycle_initial,
     )]
     fn variances_of(&self, def: GenericDefId) -> Option<Arc<[crate::variance::Variance]>>;
 
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs
index 5e3d8805896..57106412765 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs
@@ -482,9 +482,8 @@ struct FilterMapNextChecker {
 impl FilterMapNextChecker {
     fn new(resolver: &hir_def::resolver::Resolver, db: &dyn HirDatabase) -> Self {
         // Find and store the FunctionIds for Iterator::filter_map and Iterator::next
-        let (next_function_id, filter_map_function_id) = match db
-            .lang_item(resolver.krate(), LangItem::IteratorNext)
-            .and_then(|it| it.as_function())
+        let (next_function_id, filter_map_function_id) = match LangItem::IteratorNext
+            .resolve_function(db, resolver.krate())
         {
             Some(next_function_id) => (
                 Some(next_function_id),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
index 6323d8b71b7..068fc22f2ca 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
@@ -301,6 +301,7 @@ impl<'db> MatchCheckCtx<'db> {
             // ignore this issue.
             Ref => PatKind::Deref { subpattern: subpatterns.next().unwrap() },
             Slice(_) => unimplemented!(),
+            DerefPattern(_) => unimplemented!(),
             &Str(void) => match void {},
             Wildcard | NonExhaustive | Hidden | PrivateUninhabited => PatKind::Wild,
             Never => PatKind::Never,
@@ -351,6 +352,7 @@ impl PatCx for MatchCheckCtx<'_> {
             },
             Ref => 1,
             Slice(..) => unimplemented!(),
+            DerefPattern(..) => unimplemented!(),
             Never | Bool(..) | IntRange(..) | F16Range(..) | F32Range(..) | F64Range(..)
             | F128Range(..) | Str(..) | Opaque(..) | NonExhaustive | PrivateUninhabited
             | Hidden | Missing | Wildcard => 0,
@@ -411,6 +413,7 @@ impl PatCx for MatchCheckCtx<'_> {
                 }
             },
             Slice(_) => unreachable!("Found a `Slice` constructor in match checking"),
+            DerefPattern(_) => unreachable!("Found a `DerefPattern` constructor in match checking"),
             Never | Bool(..) | IntRange(..) | F16Range(..) | F32Range(..) | F64Range(..)
             | F128Range(..) | Str(..) | Opaque(..) | NonExhaustive | PrivateUninhabited
             | Hidden | Missing | Wildcard => {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
index f62e4bb4f80..f0989d9de91 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -19,7 +19,7 @@ use hir_def::{
     hir::generics::{TypeOrConstParamData, TypeParamProvenance, WherePredicate},
     item_scope::ItemInNs,
     item_tree::FieldsShape,
-    lang_item::{LangItem, LangItemTarget},
+    lang_item::LangItem,
     nameres::DefMap,
     signatures::VariantFields,
     type_ref::{
@@ -90,11 +90,26 @@ pub struct HirFormatter<'a> {
     show_container_bounds: bool,
     omit_verbose_types: bool,
     closure_style: ClosureStyle,
+    display_lifetimes: DisplayLifetime,
     display_kind: DisplayKind,
     display_target: DisplayTarget,
     bounds_formatting_ctx: BoundsFormattingCtx,
 }
 
+// FIXME: To consider, ref and dyn trait lifetimes can be omitted if they are `'_`, path args should
+// not be when in signatures
+// So this enum does not encode this well enough
+// Also 'static can be omitted for ref and dyn trait lifetimes in static/const item types
+// FIXME: Also named lifetimes may be rendered in places where their name is not in scope?
+#[derive(Copy, Clone)]
+pub enum DisplayLifetime {
+    Always,
+    OnlyStatic,
+    OnlyNamed,
+    OnlyNamedOrStatic,
+    Never,
+}
+
 #[derive(Default)]
 enum BoundsFormattingCtx {
     Entered {
@@ -155,6 +170,21 @@ impl HirFormatter<'_> {
             }
         }
     }
+
+    fn render_lifetime(&self, lifetime: &Lifetime) -> bool {
+        match self.display_lifetimes {
+            DisplayLifetime::Always => true,
+            DisplayLifetime::OnlyStatic => matches!(***lifetime.interned(), LifetimeData::Static),
+            DisplayLifetime::OnlyNamed => {
+                matches!(***lifetime.interned(), LifetimeData::Placeholder(_))
+            }
+            DisplayLifetime::OnlyNamedOrStatic => matches!(
+                ***lifetime.interned(),
+                LifetimeData::Static | LifetimeData::Placeholder(_)
+            ),
+            DisplayLifetime::Never => false,
+        }
+    }
 }
 
 pub trait HirDisplay {
@@ -189,6 +219,7 @@ pub trait HirDisplay {
             display_kind,
             closure_style,
             show_container_bounds,
+            display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
         }
     }
 
@@ -212,6 +243,7 @@ pub trait HirDisplay {
             display_target,
             display_kind: DisplayKind::Diagnostics,
             show_container_bounds: false,
+            display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
         }
     }
 
@@ -236,6 +268,7 @@ pub trait HirDisplay {
             display_target,
             display_kind: DisplayKind::Diagnostics,
             show_container_bounds: false,
+            display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
         }
     }
 
@@ -260,6 +293,7 @@ pub trait HirDisplay {
             display_target,
             display_kind: DisplayKind::Diagnostics,
             show_container_bounds: false,
+            display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
         }
     }
 
@@ -284,6 +318,7 @@ pub trait HirDisplay {
             display_target: DisplayTarget::from_crate(db, module_id.krate()),
             display_kind: DisplayKind::SourceCode { target_module_id: module_id, allow_opaque },
             show_container_bounds: false,
+            display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
             bounds_formatting_ctx: Default::default(),
         }) {
             Ok(()) => {}
@@ -312,6 +347,7 @@ pub trait HirDisplay {
             display_target,
             display_kind: DisplayKind::Test,
             show_container_bounds: false,
+            display_lifetimes: DisplayLifetime::Always,
         }
     }
 
@@ -336,6 +372,7 @@ pub trait HirDisplay {
             display_target,
             display_kind: DisplayKind::Diagnostics,
             show_container_bounds,
+            display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
         }
     }
 }
@@ -480,6 +517,7 @@ pub struct HirDisplayWrapper<'a, T> {
     display_kind: DisplayKind,
     display_target: DisplayTarget,
     show_container_bounds: bool,
+    display_lifetimes: DisplayLifetime,
 }
 
 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -502,7 +540,7 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
         self.t.hir_fmt(&mut HirFormatter {
             db: self.db,
             fmt: f,
-            buf: String::with_capacity(20),
+            buf: String::with_capacity(self.max_size.unwrap_or(20)),
             curr_size: 0,
             max_size: self.max_size,
             entity_limit: self.limited_size,
@@ -511,6 +549,7 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
             display_target: self.display_target,
             closure_style: self.closure_style,
             show_container_bounds: self.show_container_bounds,
+            display_lifetimes: self.display_lifetimes,
             bounds_formatting_ctx: Default::default(),
         })
     }
@@ -519,6 +558,11 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
         self.closure_style = c;
         self
     }
+
+    pub fn with_lifetime_display(mut self, l: DisplayLifetime) -> Self {
+        self.display_lifetimes = l;
+        self
+    }
 }
 
 impl<T> fmt::Display for HirDisplayWrapper<'_, T>
@@ -1022,9 +1066,7 @@ impl HirDisplay for Ty {
             kind @ (TyKind::Raw(m, t) | TyKind::Ref(m, _, t)) => {
                 if let TyKind::Ref(_, l, _) = kind {
                     f.write_char('&')?;
-                    if cfg!(test) {
-                        // rendering these unconditionally is probably too much (at least for inlay
-                        // hints) so we gate it to testing only for the time being
+                    if f.render_lifetime(l) {
                         l.hir_fmt(f)?;
                         f.write_char(' ')?;
                     }
@@ -1055,9 +1097,10 @@ impl HirDisplay for Ty {
                     })
                 };
                 let (preds_to_print, has_impl_fn_pred) = match t.kind(Interner) {
-                    TyKind::Dyn(dyn_ty) if dyn_ty.bounds.skip_binders().interned().len() > 1 => {
+                    TyKind::Dyn(dyn_ty) => {
                         let bounds = dyn_ty.bounds.skip_binders().interned();
-                        (bounds.len(), contains_impl_fn(bounds))
+                        let render_lifetime = f.render_lifetime(&dyn_ty.lifetime);
+                        (bounds.len() + render_lifetime as usize, contains_impl_fn(bounds))
                     }
                     TyKind::Alias(AliasTy::Opaque(OpaqueTy {
                         opaque_ty_id,
@@ -1348,9 +1391,8 @@ impl HirDisplay for Ty {
                         )?;
                     }
                     ImplTraitId::AsyncBlockTypeImplTrait(body, ..) => {
-                        let future_trait = db
-                            .lang_item(body.module(db).krate(), LangItem::Future)
-                            .and_then(LangItemTarget::as_trait);
+                        let future_trait =
+                            LangItem::Future.resolve_trait(db, body.module(db).krate());
                         let output = future_trait.and_then(|t| {
                             db.trait_items(t)
                                 .associated_type_by_name(&Name::new_symbol_root(sym::Output))
@@ -1480,7 +1522,7 @@ impl HirDisplay for Ty {
             TyKind::BoundVar(idx) => idx.hir_fmt(f)?,
             TyKind::Dyn(dyn_ty) => {
                 // Reorder bounds to satisfy `write_bounds_like_dyn_trait()`'s expectation.
-                // FIXME: `Iterator::partition_in_place()` or `Vec::drain_filter()` may make it
+                // FIXME: `Iterator::partition_in_place()` or `Vec::extract_if()` may make it
                 // more efficient when either of them hits stable.
                 let mut bounds: SmallVec<[_; 4]> =
                     dyn_ty.bounds.skip_binders().iter(Interner).cloned().collect();
@@ -1489,6 +1531,17 @@ impl HirDisplay for Ty {
                 bounds.extend(others);
                 bounds.extend(auto_traits);
 
+                if f.render_lifetime(&dyn_ty.lifetime) {
+                    // we skip the binders in `write_bounds_like_dyn_trait_with_prefix`
+                    bounds.push(Binders::empty(
+                        Interner,
+                        chalk_ir::WhereClause::TypeOutlives(chalk_ir::TypeOutlives {
+                            ty: self.clone(),
+                            lifetime: dyn_ty.lifetime.clone(),
+                        }),
+                    ));
+                }
+
                 write_bounds_like_dyn_trait_with_prefix(
                     f,
                     "dyn",
@@ -1728,9 +1781,7 @@ impl SizedByDefault {
         match self {
             Self::NotSized => false,
             Self::Sized { anchor } => {
-                let sized_trait = db
-                    .lang_item(anchor, LangItem::Sized)
-                    .and_then(|lang_item| lang_item.as_trait());
+                let sized_trait = LangItem::Sized.resolve_trait(db, anchor);
                 Some(trait_) == sized_trait
             }
         }
@@ -1895,8 +1946,7 @@ fn write_bounds_like_dyn_trait(
         write!(f, ">")?;
     }
     if let SizedByDefault::Sized { anchor } = default_sized {
-        let sized_trait =
-            f.db.lang_item(anchor, LangItem::Sized).and_then(|lang_item| lang_item.as_trait());
+        let sized_trait = LangItem::Sized.resolve_trait(f.db, anchor);
         if !is_sized {
             if !first {
                 write!(f, " + ")?;
@@ -1993,7 +2043,6 @@ impl HirDisplay for LifetimeData {
                 write!(f, "{}", param_data.name.display(f.db, f.edition()))?;
                 Ok(())
             }
-            _ if f.display_kind.is_source_code() => write!(f, "'_"),
             LifetimeData::BoundVar(idx) => idx.hir_fmt(f),
             LifetimeData::InferenceVar(_) => write!(f, "_"),
             LifetimeData::Static => write!(f, "'static"),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs
index 9823c854d5b..70763759ef0 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs
@@ -19,9 +19,7 @@ fn has_destructor(db: &dyn HirDatabase, adt: AdtId) -> bool {
         AdtId::StructId(id) => db.lookup_intern_struct(id).container,
         AdtId::UnionId(id) => db.lookup_intern_union(id).container,
     };
-    let Some(drop_trait) =
-        db.lang_item(module.krate(), LangItem::Drop).and_then(|it| it.as_trait())
-    else {
+    let Some(drop_trait) = LangItem::Drop.resolve_trait(db, module.krate()) else {
         return false;
     };
     let impls = match module.containing_block() {
@@ -181,8 +179,7 @@ fn projection_has_drop_glue(
 }
 
 fn is_copy(db: &dyn HirDatabase, ty: Ty, env: Arc<TraitEnvironment>) -> bool {
-    let Some(copy_trait) = db.lang_item(env.krate, LangItem::Copy).and_then(|it| it.as_trait())
-    else {
+    let Some(copy_trait) = LangItem::Copy.resolve_trait(db, env.krate) else {
         return false;
     };
     let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(ty).build();
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 80b18473907..106b996b13e 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
@@ -124,7 +124,7 @@ pub fn dyn_compatibility_of_trait_query(
 
 fn generics_require_sized_self(db: &dyn HirDatabase, def: GenericDefId) -> bool {
     let krate = def.module(db).krate();
-    let Some(sized) = db.lang_item(krate, LangItem::Sized).and_then(|l| l.as_trait()) else {
+    let Some(sized) = LangItem::Sized.resolve_trait(db, krate) else {
         return false;
     };
 
@@ -491,8 +491,8 @@ fn receiver_is_dispatchable(
 
     let krate = func.module(db).krate();
     let traits = (
-        db.lang_item(krate, LangItem::Unsize).and_then(|it| it.as_trait()),
-        db.lang_item(krate, LangItem::DispatchFromDyn).and_then(|it| it.as_trait()),
+        LangItem::Unsize.resolve_trait(db, krate),
+        LangItem::DispatchFromDyn.resolve_trait(db, krate),
     );
     let (Some(unsize_did), Some(dispatch_from_dyn_did)) = traits else {
         return false;
@@ -515,7 +515,7 @@ fn receiver_is_dispatchable(
         trait_id: to_chalk_trait_id(trait_),
         substitution: Substitution::from_iter(
             Interner,
-            std::iter::once(unsized_self_ty.clone().cast(Interner))
+            std::iter::once(unsized_self_ty.cast(Interner))
                 .chain(placeholder_subst.iter(Interner).skip(1).cloned()),
         ),
     });
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
index 790914fdaf2..f0ec31db8bb 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
@@ -39,7 +39,7 @@ use hir_def::{
     builtin_type::{BuiltinInt, BuiltinType, BuiltinUint},
     expr_store::{Body, ExpressionStore, HygieneId, path::Path},
     hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId},
-    lang_item::{LangItem, LangItemTarget},
+    lang_item::{LangItem, LangItemTarget, lang_item},
     layout::Integer,
     resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
     signatures::{ConstSignature, StaticSignature},
@@ -1801,7 +1801,7 @@ impl<'a> InferenceContext<'a> {
 
     fn resolve_lang_item(&self, item: LangItem) -> Option<LangItemTarget> {
         let krate = self.resolver.krate();
-        self.db.lang_item(krate, item)
+        lang_item(self.db, krate, item)
     }
 
     fn resolve_output_on(&self, trait_: TraitId) -> Option<TypeAliasId> {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
index cf3b15d2a67..800897c6fc3 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
@@ -127,7 +127,7 @@ impl InferenceContext<'_> {
         let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
         let prev_closure = mem::replace(&mut self.current_closure, id);
         let prev_ret_ty = mem::replace(&mut self.return_ty, body_ret_ty.clone());
-        let prev_ret_coercion = self.return_coercion.replace(CoerceMany::new(body_ret_ty.clone()));
+        let prev_ret_coercion = self.return_coercion.replace(CoerceMany::new(body_ret_ty));
         let prev_resume_yield_tys = mem::replace(&mut self.resume_yield_tys, resume_yield_tys);
 
         self.with_breakable_ctx(BreakableKind::Border, None, None, |this| {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs
index 847dd43a02d..39bd90849fe 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs
@@ -8,10 +8,7 @@
 use std::iter;
 
 use chalk_ir::{BoundVar, Goal, Mutability, TyKind, TyVariableKind, cast::Cast};
-use hir_def::{
-    hir::ExprId,
-    lang_item::{LangItem, LangItemTarget},
-};
+use hir_def::{hir::ExprId, lang_item::LangItem};
 use stdx::always;
 use triomphe::Arc;
 
@@ -701,8 +698,8 @@ impl InferenceTable<'_> {
             reborrow.as_ref().map_or_else(|| from_ty.clone(), |(_, adj)| adj.target.clone());
 
         let krate = self.trait_env.krate;
-        let coerce_unsized_trait = match self.db.lang_item(krate, LangItem::CoerceUnsized) {
-            Some(LangItemTarget::Trait(trait_)) => trait_,
+        let coerce_unsized_trait = match LangItem::CoerceUnsized.resolve_trait(self.db, krate) {
+            Some(trait_) => trait_,
             _ => return Err(TypeError),
         };
 
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
index 5468254ab91..8084b394d04 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
@@ -827,9 +827,9 @@ impl InferenceContext<'_> {
                     }
                     let assoc = self.resolve_ops_index_output();
                     self.resolve_associated_type_with_params(
-                        self_ty.clone(),
+                        self_ty,
                         assoc,
-                        &[index_ty.clone().cast(Interner)],
+                        &[index_ty.cast(Interner)],
                     )
                 } else {
                     self.err_ty()
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs
index cf0152ecd26..ac450c0b559 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs
@@ -126,10 +126,8 @@ impl InferenceContext<'_> {
             &Expr::Index { base, index } => {
                 if mutability == Mutability::Mut {
                     if let Some((f, _)) = self.result.method_resolutions.get_mut(&tgt_expr) {
-                        if let Some(index_trait) = self
-                            .db
-                            .lang_item(self.table.trait_env.krate, LangItem::IndexMut)
-                            .and_then(|l| l.as_trait())
+                        if let Some(index_trait) =
+                            LangItem::IndexMut.resolve_trait(self.db, self.table.trait_env.krate)
                         {
                             if let Some(index_fn) = self
                                 .db
@@ -183,10 +181,8 @@ impl InferenceContext<'_> {
                 let mut mutability = mutability;
                 if let Some((f, _)) = self.result.method_resolutions.get_mut(&tgt_expr) {
                     if mutability == Mutability::Mut {
-                        if let Some(deref_trait) = self
-                            .db
-                            .lang_item(self.table.trait_env.krate, LangItem::DerefMut)
-                            .and_then(|l| l.as_trait())
+                        if let Some(deref_trait) =
+                            LangItem::DerefMut.resolve_trait(self.db, self.table.trait_env.krate)
                         {
                             let ty = self.result.type_of_expr.get(*expr);
                             let is_mut_ptr = ty.is_some_and(|ty| {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
index dc1de3b9e85..a9a3265858e 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
@@ -435,7 +435,7 @@ impl InferenceContext<'_> {
         decl: Option<DeclContext>,
     ) -> Ty {
         let (expectation_type, expectation_lt) = match expected.as_reference() {
-            Some((inner_ty, lifetime, _exp_mut)) => (inner_ty.clone(), lifetime.clone()),
+            Some((inner_ty, lifetime, _exp_mut)) => (inner_ty.clone(), lifetime),
             None => {
                 let inner_ty = self.table.new_type_var();
                 let inner_lt = self.table.new_lifetime_var();
@@ -597,7 +597,7 @@ impl InferenceContext<'_> {
         let size = consteval::usize_const(self.db, Some(len as u128), self.owner.krate(self.db));
 
         let elem_ty = self.table.new_type_var();
-        let array_ty = TyKind::Array(elem_ty.clone(), size).intern(Interner);
+        let array_ty = TyKind::Array(elem_ty, size).intern(Interner);
         Some(array_ty)
     }
 
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
index 60aa9b5a17a..631b571465f 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
@@ -1024,16 +1024,12 @@ impl<'a> InferenceTable<'a> {
             }
         }
 
-        let Some(sized) = self
-            .db
-            .lang_item(self.trait_env.krate, LangItem::Sized)
-            .and_then(|sized| sized.as_trait())
-        else {
+        let Some(sized) = LangItem::Sized.resolve_trait(self.db, self.trait_env.krate) else {
             return false;
         };
         let sized_pred = WhereClause::Implemented(TraitRef {
             trait_id: to_chalk_trait_id(sized),
-            substitution: Substitution::from1(Interner, ty.clone()),
+            substitution: Substitution::from1(Interner, ty),
         });
         let goal = GoalData::DomainGoal(chalk_ir::DomainGoal::Holds(sized_pred)).intern(Interner);
         matches!(self.try_obligation(goal), Some(Solution::Unique(_)))
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
index e4688d044e9..9def39d5f97 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
@@ -590,10 +590,7 @@ impl<'a> TyLoweringContext<'a> {
                 }
             }
             &TypeBound::Path(path, TraitBoundModifier::Maybe) => {
-                let sized_trait = self
-                    .db
-                    .lang_item(self.resolver.krate(), LangItem::Sized)
-                    .and_then(|lang_item| lang_item.as_trait());
+                let sized_trait = LangItem::Sized.resolve_trait(self.db, self.resolver.krate());
                 // Don't lower associated type bindings as the only possible relaxed trait bound
                 // `?Sized` has no of them.
                 // If we got another trait here ignore the bound completely.
@@ -736,10 +733,8 @@ impl<'a> TyLoweringContext<'a> {
             }
 
             if !ctx.unsized_types.contains(&self_ty) {
-                let sized_trait = ctx
-                    .db
-                    .lang_item(krate, LangItem::Sized)
-                    .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
+                let sized_trait =
+                    LangItem::Sized.resolve_trait(ctx.db, krate).map(to_chalk_trait_id);
                 let sized_clause = sized_trait.map(|trait_id| {
                     let clause = WhereClause::Implemented(TraitRef {
                         trait_id,
@@ -1188,9 +1183,7 @@ fn implicitly_sized_clauses<'a, 'subst: 'a>(
     substitution: &'subst Substitution,
     resolver: &Resolver,
 ) -> Option<impl Iterator<Item = WhereClause> + Captures<'a> + Captures<'subst>> {
-    let sized_trait = db
-        .lang_item(resolver.krate(), LangItem::Sized)
-        .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id))?;
+    let sized_trait = LangItem::Sized.resolve_trait(db, resolver.krate()).map(to_chalk_trait_id)?;
 
     let trait_self_idx = trait_self_param_idx(db, def);
 
@@ -1475,7 +1468,7 @@ fn type_for_enum_variant_constructor(
     }
 }
 
-#[salsa::tracked(cycle_result = type_for_adt_cycle_result)]
+#[salsa_macros::tracked(cycle_result = type_for_adt_cycle_result)]
 fn type_for_adt_tracked(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
     type_for_adt(db, adt)
 }
@@ -1540,7 +1533,7 @@ pub enum TyDefId {
 }
 impl_from!(BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId for TyDefId);
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
 pub enum ValueTyDefId {
     FunctionId(FunctionId),
     StructId(StructId),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs
index 8f8e26eca2a..8e549ca0cbd 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs
@@ -515,9 +515,15 @@ impl From<Option<BlockId>> for VisibleFromModule {
     }
 }
 
+#[derive(Debug, Clone)]
+pub enum AutorefOrPtrAdjustment {
+    Autoref(Mutability),
+    ToConstPtr,
+}
+
 #[derive(Debug, Clone, Default)]
 pub struct ReceiverAdjustments {
-    autoref: Option<Mutability>,
+    autoref: Option<AutorefOrPtrAdjustment>,
     autoderefs: usize,
     unsize_array: bool,
 }
@@ -535,10 +541,15 @@ impl ReceiverAdjustments {
                 }
                 Some((kind, new_ty)) => {
                     ty = new_ty.clone();
+                    let mutbl = match self.autoref {
+                        Some(AutorefOrPtrAdjustment::Autoref(m)) => Some(m),
+                        Some(AutorefOrPtrAdjustment::ToConstPtr) => Some(Mutability::Not),
+                        // FIXME should we know the mutability here, when autoref is `None`?
+                        None => None,
+                    };
                     adjust.push(Adjustment {
                         kind: Adjust::Deref(match kind {
-                            // FIXME should we know the mutability here, when autoref is `None`?
-                            AutoderefKind::Overloaded => Some(OverloadedDeref(self.autoref)),
+                            AutoderefKind::Overloaded => Some(OverloadedDeref(mutbl)),
                             AutoderefKind::Builtin => None,
                         }),
                         target: new_ty,
@@ -546,11 +557,27 @@ impl ReceiverAdjustments {
                 }
             }
         }
-        if let Some(m) = self.autoref {
+        if let Some(autoref) = &self.autoref {
             let lt = table.new_lifetime_var();
-            let a = Adjustment::borrow(m, ty, lt);
-            ty = a.target.clone();
-            adjust.push(a);
+            match autoref {
+                AutorefOrPtrAdjustment::Autoref(m) => {
+                    let a = Adjustment::borrow(*m, ty, lt);
+                    ty = a.target.clone();
+                    adjust.push(a);
+                }
+                AutorefOrPtrAdjustment::ToConstPtr => {
+                    if let TyKind::Raw(Mutability::Mut, pointee) = ty.kind(Interner) {
+                        let a = Adjustment {
+                            kind: Adjust::Pointer(PointerCast::MutToConstPointer),
+                            target: TyKind::Raw(Mutability::Not, pointee.clone()).intern(Interner),
+                        };
+                        ty = a.target.clone();
+                        adjust.push(a);
+                    } else {
+                        never!("`ToConstPtr` target is not a raw mutable pointer");
+                    }
+                }
+            };
         }
         if self.unsize_array {
             ty = 'it: {
@@ -575,8 +602,8 @@ impl ReceiverAdjustments {
         (ty, adjust)
     }
 
-    fn with_autoref(&self, m: Mutability) -> ReceiverAdjustments {
-        Self { autoref: Some(m), ..*self }
+    fn with_autoref(&self, a: AutorefOrPtrAdjustment) -> ReceiverAdjustments {
+        Self { autoref: Some(a), ..*self }
     }
 }
 
@@ -1051,7 +1078,7 @@ fn iterate_method_candidates_with_autoref(
     let mut maybe_reborrowed = first_adjustment.clone();
     if let Some((_, _, m)) = receiver_ty.value.as_reference() {
         // Prefer reborrow of references to move
-        maybe_reborrowed.autoref = Some(m);
+        maybe_reborrowed.autoref = Some(AutorefOrPtrAdjustment::Autoref(m));
         maybe_reborrowed.autoderefs += 1;
     }
 
@@ -1063,15 +1090,34 @@ fn iterate_method_candidates_with_autoref(
         binders: receiver_ty.binders.clone(),
     };
 
-    iterate_method_candidates_by_receiver(refed, first_adjustment.with_autoref(Mutability::Not))?;
+    iterate_method_candidates_by_receiver(
+        refed,
+        first_adjustment.with_autoref(AutorefOrPtrAdjustment::Autoref(Mutability::Not)),
+    )?;
 
     let ref_muted = Canonical {
         value: TyKind::Ref(Mutability::Mut, error_lifetime(), receiver_ty.value.clone())
             .intern(Interner),
-        binders: receiver_ty.binders,
+        binders: receiver_ty.binders.clone(),
     };
 
-    iterate_method_candidates_by_receiver(ref_muted, first_adjustment.with_autoref(Mutability::Mut))
+    iterate_method_candidates_by_receiver(
+        ref_muted,
+        first_adjustment.with_autoref(AutorefOrPtrAdjustment::Autoref(Mutability::Mut)),
+    )?;
+
+    if let Some((ty, Mutability::Mut)) = receiver_ty.value.as_raw_ptr() {
+        let const_ptr_ty = Canonical {
+            value: TyKind::Raw(Mutability::Not, ty.clone()).intern(Interner),
+            binders: receiver_ty.binders,
+        };
+        iterate_method_candidates_by_receiver(
+            const_ptr_ty,
+            first_adjustment.with_autoref(AutorefOrPtrAdjustment::ToConstPtr),
+        )?;
+    }
+
+    ControlFlow::Continue(())
 }
 
 pub trait MethodCandidateCallback {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs
index 6dc20203e0e..bf80ed7967a 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs
@@ -77,7 +77,14 @@ pub struct Local {
 /// currently implements it, but it seems like this may be something to check against in the
 /// validator.
 #[derive(Debug, PartialEq, Eq, Clone)]
-pub enum Operand {
+pub struct Operand {
+    kind: OperandKind,
+    // FIXME : This should actually just be of type `MirSpan`.
+    span: Option<MirSpan>,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone)]
+pub enum OperandKind {
     /// Creates a value by loading the given place.
     ///
     /// Before drop elaboration, the type of the place must be `Copy`. After drop elaboration there
@@ -101,7 +108,13 @@ pub enum Operand {
 
 impl Operand {
     fn from_concrete_const(data: Box<[u8]>, memory_map: MemoryMap, ty: Ty) -> Self {
-        Operand::Constant(intern_const_scalar(ConstScalar::Bytes(data, memory_map), ty))
+        Operand {
+            kind: OperandKind::Constant(intern_const_scalar(
+                ConstScalar::Bytes(data, memory_map),
+                ty,
+            )),
+            span: None,
+        }
     }
 
     fn from_bytes(data: Box<[u8]>, ty: Ty) -> Self {
@@ -1076,11 +1089,11 @@ impl MirBody {
             f: &mut impl FnMut(&mut Place, &mut ProjectionStore),
             store: &mut ProjectionStore,
         ) {
-            match op {
-                Operand::Copy(p) | Operand::Move(p) => {
+            match &mut op.kind {
+                OperandKind::Copy(p) | OperandKind::Move(p) => {
                     f(p, store);
                 }
-                Operand::Constant(_) | Operand::Static(_) => (),
+                OperandKind::Constant(_) | OperandKind::Static(_) => (),
             }
         }
         for (_, block) in self.basic_blocks.iter_mut() {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs
index eca6f4692a4..fb0c0dee095 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs
@@ -15,13 +15,13 @@ use crate::{
     ClosureId, Interner, Substitution, Ty, TyExt, TypeFlags,
     db::{HirDatabase, InternedClosure},
     display::DisplayTarget,
-    mir::Operand,
+    mir::OperandKind,
     utils::ClosureSubst,
 };
 
 use super::{
-    BasicBlockId, BorrowKind, LocalId, MirBody, MirLowerError, MirSpan, MutBorrowKind, Place,
-    ProjectionElem, Rvalue, StatementKind, TerminatorKind,
+    BasicBlockId, BorrowKind, LocalId, MirBody, MirLowerError, MirSpan, MutBorrowKind, Operand,
+    Place, ProjectionElem, Rvalue, StatementKind, TerminatorKind,
 };
 
 #[derive(Debug, Clone, PartialEq, Eq)]
@@ -120,8 +120,8 @@ fn make_fetch_closure_field(
 
 fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef> {
     let mut result = vec![];
-    let mut for_operand = |op: &Operand, span: MirSpan| match op {
-        Operand::Copy(p) | Operand::Move(p) => {
+    let mut for_operand = |op: &Operand, span: MirSpan| match op.kind {
+        OperandKind::Copy(p) | OperandKind::Move(p) => {
             let mut ty: Ty = body.locals[p.local].ty.clone();
             let mut is_dereference_of_ref = false;
             for proj in p.projection.lookup(&body.projection_store) {
@@ -139,10 +139,10 @@ fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef>
                 && !ty.clone().is_copy(db, body.owner)
                 && !ty.data(Interner).flags.intersects(TypeFlags::HAS_ERROR)
             {
-                result.push(MovedOutOfRef { span, ty });
+                result.push(MovedOutOfRef { span: op.span.unwrap_or(span), ty });
             }
         }
-        Operand::Constant(_) | Operand::Static(_) => (),
+        OperandKind::Constant(_) | OperandKind::Static(_) => (),
     };
     for (_, block) in body.basic_blocks.iter() {
         db.unwind_if_revision_cancelled();
@@ -215,8 +215,8 @@ fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef>
 
 fn partially_moved(db: &dyn HirDatabase, body: &MirBody) -> Vec<PartiallyMoved> {
     let mut result = vec![];
-    let mut for_operand = |op: &Operand, span: MirSpan| match op {
-        Operand::Copy(p) | Operand::Move(p) => {
+    let mut for_operand = |op: &Operand, span: MirSpan| match op.kind {
+        OperandKind::Copy(p) | OperandKind::Move(p) => {
             let mut ty: Ty = body.locals[p.local].ty.clone();
             for proj in p.projection.lookup(&body.projection_store) {
                 ty = proj.projected_ty(
@@ -232,7 +232,7 @@ fn partially_moved(db: &dyn HirDatabase, body: &MirBody) -> Vec<PartiallyMoved>
                 result.push(PartiallyMoved { span, ty, local: p.local });
             }
         }
-        Operand::Constant(_) | Operand::Static(_) => (),
+        OperandKind::Constant(_) | OperandKind::Static(_) => (),
     };
     for (_, block) in body.basic_blocks.iter() {
         db.unwind_if_revision_cancelled();
@@ -492,7 +492,7 @@ fn record_usage(local: LocalId, result: &mut ArenaMap<LocalId, MutabilityReason>
 }
 
 fn record_usage_for_operand(arg: &Operand, result: &mut ArenaMap<LocalId, MutabilityReason>) {
-    if let Operand::Copy(p) | Operand::Move(p) = arg {
+    if let OperandKind::Copy(p) | OperandKind::Move(p) = arg.kind {
         record_usage(p.local, result);
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
index 386226b16d5..21e5428520e 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
@@ -47,7 +47,7 @@ use crate::{
 
 use super::{
     AggregateKind, BasicBlockId, BinOp, CastKind, LocalId, MirBody, MirLowerError, MirSpan,
-    Operand, Place, PlaceElem, ProjectionElem, ProjectionStore, Rvalue, StatementKind,
+    Operand, OperandKind, Place, PlaceElem, ProjectionElem, ProjectionStore, Rvalue, StatementKind,
     TerminatorKind, UnOp, return_slot,
 };
 
@@ -655,22 +655,15 @@ impl Evaluator<'_> {
             mir_or_dyn_index_cache: RefCell::new(Default::default()),
             unused_locals_store: RefCell::new(Default::default()),
             cached_ptr_size,
-            cached_fn_trait_func: db
-                .lang_item(crate_id, LangItem::Fn)
-                .and_then(|x| x.as_trait())
+            cached_fn_trait_func: LangItem::Fn
+                .resolve_trait(db, crate_id)
                 .and_then(|x| db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call))),
-            cached_fn_mut_trait_func: db
-                .lang_item(crate_id, LangItem::FnMut)
-                .and_then(|x| x.as_trait())
-                .and_then(|x| {
-                    db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call_mut))
-                }),
-            cached_fn_once_trait_func: db
-                .lang_item(crate_id, LangItem::FnOnce)
-                .and_then(|x| x.as_trait())
-                .and_then(|x| {
-                    db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call_once))
-                }),
+            cached_fn_mut_trait_func: LangItem::FnMut.resolve_trait(db, crate_id).and_then(|x| {
+                db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call_mut))
+            }),
+            cached_fn_once_trait_func: LangItem::FnOnce.resolve_trait(db, crate_id).and_then(|x| {
+                db.trait_items(x).method_by_name(&Name::new_symbol_root(sym::call_once))
+            }),
         })
     }
 
@@ -863,10 +856,10 @@ impl Evaluator<'_> {
     }
 
     fn operand_ty(&self, o: &Operand, locals: &Locals) -> Result<Ty> {
-        Ok(match o {
-            Operand::Copy(p) | Operand::Move(p) => self.place_ty(p, locals)?,
-            Operand::Constant(c) => c.data(Interner).ty.clone(),
-            &Operand::Static(s) => {
+        Ok(match &o.kind {
+            OperandKind::Copy(p) | OperandKind::Move(p) => self.place_ty(p, locals)?,
+            OperandKind::Constant(c) => c.data(Interner).ty.clone(),
+            &OperandKind::Static(s) => {
                 let ty = self.db.infer(s.into())[self.db.body(s.into()).body_expr].clone();
                 TyKind::Ref(Mutability::Not, static_lifetime(), ty).intern(Interner)
             }
@@ -1880,16 +1873,16 @@ impl Evaluator<'_> {
     }
 
     fn eval_operand(&mut self, it: &Operand, locals: &mut Locals) -> Result<Interval> {
-        Ok(match it {
-            Operand::Copy(p) | Operand::Move(p) => {
+        Ok(match &it.kind {
+            OperandKind::Copy(p) | OperandKind::Move(p) => {
                 locals.drop_flags.remove_place(p, &locals.body.projection_store);
                 self.eval_place(p, locals)?
             }
-            Operand::Static(st) => {
+            OperandKind::Static(st) => {
                 let addr = self.eval_static(*st, locals)?;
                 Interval::new(addr, self.ptr_size())
             }
-            Operand::Constant(konst) => self.allocate_const_in_heap(locals, konst)?,
+            OperandKind::Constant(konst) => self.allocate_const_in_heap(locals, konst)?,
         })
     }
 
@@ -2811,7 +2804,7 @@ impl Evaluator<'_> {
         span: MirSpan,
     ) -> Result<()> {
         let Some(drop_fn) = (|| {
-            let drop_trait = self.db.lang_item(self.crate_id, LangItem::Drop)?.as_trait()?;
+            let drop_trait = LangItem::Drop.resolve_trait(self.db, self.crate_id)?;
             self.db.trait_items(drop_trait).method_by_name(&Name::new_symbol_root(sym::drop))
         })() else {
             // in some tests we don't have drop trait in minicore, and
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 4de44cfd02e..26ef95d264b 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
@@ -6,7 +6,6 @@ use std::cmp::{self, Ordering};
 use chalk_ir::TyKind;
 use hir_def::{
     builtin_type::{BuiltinInt, BuiltinUint},
-    lang_item::LangItemTarget,
     resolver::HasResolver,
 };
 use hir_expand::name::Name;
@@ -156,8 +155,8 @@ impl Evaluator<'_> {
         if let Some(LangItem::PanicFmt) = self.db.lang_attr(def.into()) {
             let resolver = self.db.crate_def_map(self.crate_id).crate_root().resolver(self.db);
 
-            let Some(hir_def::lang_item::LangItemTarget::Function(const_panic_fmt)) =
-                self.db.lang_item(resolver.krate(), LangItem::ConstPanicFmt)
+            let Some(const_panic_fmt) =
+                LangItem::ConstPanicFmt.resolve_function(self.db, resolver.krate())
             else {
                 not_supported!("const_panic_fmt lang item not found or not a function");
             };
@@ -1257,12 +1256,12 @@ impl Evaluator<'_> {
                     let addr = tuple.interval.addr.offset(offset);
                     args.push(IntervalAndTy::new(addr, field, self, locals)?);
                 }
-                if let Some(target) = self.db.lang_item(self.crate_id, LangItem::FnOnce) {
-                    if let Some(def) = target.as_trait().and_then(|it| {
-                        self.db
-                            .trait_items(it)
-                            .method_by_name(&Name::new_symbol_root(sym::call_once))
-                    }) {
+                if let Some(target) = LangItem::FnOnce.resolve_trait(self.db, self.crate_id) {
+                    if let Some(def) = self
+                        .db
+                        .trait_items(target)
+                        .method_by_name(&Name::new_symbol_root(sym::call_once))
+                    {
                         self.exec_fn_trait(
                             def,
                             &args,
@@ -1376,9 +1375,7 @@ impl Evaluator<'_> {
                         }
                     }
                 }
-                if let Some(LangItemTarget::EnumId(e)) =
-                    self.db.lang_item(self.crate_id, LangItem::Ordering)
-                {
+                if let Some(e) = LangItem::Ordering.resolve_enum(self.db, self.crate_id) {
                     let ty = self.db.ty(e.into());
                     let r = self
                         .compute_discriminant(ty.skip_binders().clone(), &[result as i8 as u8])?;
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
index 557027756f3..7b48b15d9ea 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
@@ -13,7 +13,7 @@ use hir_def::{
         Pat, PatId, RecordFieldPat, RecordLitField,
     },
     item_tree::FieldsShape,
-    lang_item::{LangItem, LangItemTarget},
+    lang_item::{LangItem, LangItemTarget, lang_item},
     resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs},
 };
 use hir_expand::name::Name;
@@ -48,6 +48,8 @@ use crate::{
     utils::ClosureSubst,
 };
 
+use super::OperandKind;
+
 mod as_place;
 mod pattern_matching;
 
@@ -324,7 +326,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
         let Some((p, current)) = self.lower_expr_as_place(current, expr_id, true)? else {
             return Ok(None);
         };
-        Ok(Some((Operand::Copy(p), current)))
+        Ok(Some((Operand { kind: OperandKind::Copy(p), span: Some(expr_id.into()) }, current)))
     }
 
     fn lower_expr_to_place_with_adjust(
@@ -347,7 +349,12 @@ impl<'ctx> MirLowerCtx<'ctx> {
                     else {
                         return Ok(None);
                     };
-                    self.push_assignment(current, place, Operand::Copy(p).into(), expr_id.into());
+                    self.push_assignment(
+                        current,
+                        place,
+                        Operand { kind: OperandKind::Copy(p), span: None }.into(),
+                        expr_id.into(),
+                    );
                     Ok(Some(current))
                 }
                 Adjust::Borrow(AutoBorrow::Ref(_, m) | AutoBorrow::RawPtr(m)) => {
@@ -371,7 +378,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
                         place,
                         Rvalue::Cast(
                             CastKind::PointerCoercion(*cast),
-                            Operand::Copy(p),
+                            Operand { kind: OperandKind::Copy(p), span: None },
                             last.target.clone(),
                         ),
                         expr_id.into(),
@@ -476,7 +483,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
                         self.push_assignment(
                             current,
                             place,
-                            Operand::Copy(temp).into(),
+                            Operand { kind: OperandKind::Copy(temp), span: None }.into(),
                             expr_id.into(),
                         );
                         Ok(Some(current))
@@ -517,21 +524,23 @@ impl<'ctx> MirLowerCtx<'ctx> {
                         self.push_assignment(
                             current,
                             place,
-                            Operand::Constant(
-                                ConstData {
-                                    ty,
-                                    value: chalk_ir::ConstValue::BoundVar(BoundVar::new(
-                                        DebruijnIndex::INNERMOST,
-                                        generics.type_or_const_param_idx(p.into()).ok_or(
-                                            MirLowerError::TypeError(
-                                                "fail to lower const generic param",
-                                            ),
-                                        )?,
-                                    )),
-                                }
-                                .intern(Interner),
-                            )
-                            .into(),
+                            Rvalue::from(Operand {
+                                kind: OperandKind::Constant(
+                                    ConstData {
+                                        ty,
+                                        value: chalk_ir::ConstValue::BoundVar(BoundVar::new(
+                                            DebruijnIndex::INNERMOST,
+                                            generics.type_or_const_param_idx(p.into()).ok_or(
+                                                MirLowerError::TypeError(
+                                                    "fail to lower const generic param",
+                                                ),
+                                            )?,
+                                        )),
+                                    }
+                                    .intern(Interner),
+                                ),
+                                span: None,
+                            }),
                             expr_id.into(),
                         );
                         Ok(Some(current))
@@ -876,7 +885,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
                                                 })),
                                                 &mut self.result.projection_store,
                                             );
-                                            Operand::Copy(p)
+                                            Operand { kind: OperandKind::Copy(p), span: None }
                                         }
                                     })
                                     .collect(),
@@ -979,7 +988,12 @@ impl<'ctx> MirLowerCtx<'ctx> {
                 else {
                     return Ok(None);
                 };
-                self.push_assignment(current, place, Operand::Copy(p).into(), expr_id.into());
+                self.push_assignment(
+                    current,
+                    place,
+                    Operand { kind: OperandKind::Copy(p), span: None }.into(),
+                    expr_id.into(),
+                );
                 Ok(Some(current))
             }
             Expr::UnaryOp {
@@ -1056,8 +1070,11 @@ impl<'ctx> MirLowerCtx<'ctx> {
                     else {
                         return Ok(None);
                     };
-                    let r_value =
-                        Rvalue::CheckedBinaryOp(op.into(), Operand::Copy(lhs_place), rhs_op);
+                    let r_value = Rvalue::CheckedBinaryOp(
+                        op.into(),
+                        Operand { kind: OperandKind::Copy(lhs_place), span: None },
+                        rhs_op,
+                    );
                     self.push_assignment(current, lhs_place, r_value, expr_id.into());
                     return Ok(Some(current));
                 }
@@ -1232,9 +1249,11 @@ impl<'ctx> MirLowerCtx<'ctx> {
                                 Rvalue::Ref(*bk, p),
                                 capture_spans[0],
                             );
-                            operands.push(Operand::Move(tmp));
+                            operands.push(Operand { kind: OperandKind::Move(tmp), span: None });
+                        }
+                        CaptureKind::ByValue => {
+                            operands.push(Operand { kind: OperandKind::Move(p), span: None })
                         }
-                        CaptureKind::ByValue => operands.push(Operand::Move(p)),
                     }
                 }
                 self.push_assignment(
@@ -1476,7 +1495,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
                 .const_eval(const_id, subst, None)
                 .map_err(|e| MirLowerError::ConstEvalError(name.into(), Box::new(e)))?
         };
-        Ok(Operand::Constant(c))
+        Ok(Operand { kind: OperandKind::Constant(c), span: None })
     }
 
     fn write_bytes_to_place(
@@ -1727,7 +1746,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
 
     fn resolve_lang_item(&self, item: LangItem) -> Result<LangItemTarget> {
         let crate_id = self.owner.module(self.db).krate();
-        self.db.lang_item(crate_id, item).ok_or(MirLowerError::LangItemNotFound(item))
+        lang_item(self.db, crate_id, item).ok_or(MirLowerError::LangItemNotFound(item))
     }
 
     fn lower_block_to_place(
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs
index d3cd0099246..c22bada7a90 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs
@@ -1,6 +1,6 @@
 //! MIR lowering for places
 
-use crate::mir::MutBorrowKind;
+use crate::mir::{MutBorrowKind, Operand, OperandKind};
 
 use super::*;
 use hir_def::FunctionId;
@@ -155,7 +155,7 @@ impl MirLowerCtx<'_> {
                         self.push_assignment(
                             current,
                             temp,
-                            Operand::Static(s).into(),
+                            Operand { kind: OperandKind::Static(s), span: None }.into(),
                             expr_id.into(),
                         );
                         Ok(Some((
@@ -305,7 +305,7 @@ impl MirLowerCtx<'_> {
         );
         let Some(current) = self.lower_call(
             index_fn_op,
-            Box::new([Operand::Copy(place), index_operand]),
+            Box::new([Operand { kind: OperandKind::Copy(place), span: None }, index_operand]),
             result,
             current,
             false,
@@ -365,7 +365,7 @@ impl MirLowerCtx<'_> {
         let mut result: Place = self.temp(target_ty_ref, current, span)?.into();
         let Some(current) = self.lower_call(
             deref_fn_op,
-            Box::new([Operand::Copy(ref_place)]),
+            Box::new([Operand { kind: OperandKind::Copy(ref_place), span: None }]),
             result,
             current,
             false,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
index abfa7aee04f..b3c1f6f387f 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
@@ -5,10 +5,10 @@ use hir_def::{AssocItemId, hir::ExprId, signatures::VariantFields};
 use crate::{
     BindingMode,
     mir::{
-        LocalId, MutBorrowKind,
+        LocalId, MutBorrowKind, Operand, OperandKind,
         lower::{
             BasicBlockId, BinOp, BindingId, BorrowKind, Either, Expr, FieldId, Idx, Interner,
-            MemoryMap, MirLowerCtx, MirLowerError, MirSpan, Mutability, Operand, Pat, PatId, Place,
+            MemoryMap, MirLowerCtx, MirLowerError, MirSpan, Mutability, Pat, PatId, Place,
             PlaceElem, ProjectionElem, RecordFieldPat, ResolveValueResult, Result, Rvalue,
             Substitution, SwitchTargets, TerminatorKind, TupleFieldId, TupleId, TyBuilder, TyKind,
             ValueNs, VariantId,
@@ -217,10 +217,14 @@ impl MirLowerCtx<'_> {
                     self.push_assignment(
                         current,
                         discr,
-                        Rvalue::CheckedBinaryOp(binop, lv, Operand::Copy(cond_place)),
+                        Rvalue::CheckedBinaryOp(
+                            binop,
+                            lv,
+                            Operand { kind: OperandKind::Copy(cond_place), span: None },
+                        ),
                         pattern.into(),
                     );
-                    let discr = Operand::Copy(discr);
+                    let discr = Operand { kind: OperandKind::Copy(discr), span: None };
                     self.set_terminator(
                         current,
                         TerminatorKind::SwitchInt {
@@ -262,7 +266,10 @@ impl MirLowerCtx<'_> {
                             self.set_terminator(
                                 current,
                                 TerminatorKind::SwitchInt {
-                                    discr: Operand::Copy(place_len),
+                                    discr: Operand {
+                                        kind: OperandKind::Copy(place_len),
+                                        span: None,
+                                    },
                                     targets: SwitchTargets::static_if(
                                         pattern_len as u128,
                                         next,
@@ -282,10 +289,14 @@ impl MirLowerCtx<'_> {
                             self.push_assignment(
                                 current,
                                 discr,
-                                Rvalue::CheckedBinaryOp(BinOp::Le, c, Operand::Copy(place_len)),
+                                Rvalue::CheckedBinaryOp(
+                                    BinOp::Le,
+                                    c,
+                                    Operand { kind: OperandKind::Copy(place_len), span: None },
+                                ),
                                 pattern.into(),
                             );
-                            let discr = Operand::Copy(discr);
+                            let discr = Operand { kind: OperandKind::Copy(discr), span: None };
                             self.set_terminator(
                                 current,
                                 TerminatorKind::SwitchInt {
@@ -407,8 +418,8 @@ impl MirLowerCtx<'_> {
                         tmp2,
                         Rvalue::CheckedBinaryOp(
                             BinOp::Eq,
-                            Operand::Copy(tmp),
-                            Operand::Copy(cond_place),
+                            Operand { kind: OperandKind::Copy(tmp), span: None },
+                            Operand { kind: OperandKind::Copy(cond_place), span: None },
                         ),
                         span,
                     );
@@ -417,7 +428,7 @@ impl MirLowerCtx<'_> {
                     self.set_terminator(
                         current,
                         TerminatorKind::SwitchInt {
-                            discr: Operand::Copy(tmp2),
+                            discr: Operand { kind: OperandKind::Copy(tmp2), span: None },
                             targets: SwitchTargets::static_if(1, next, else_target),
                         },
                         span,
@@ -486,7 +497,7 @@ impl MirLowerCtx<'_> {
                 self.push_assignment(
                     current,
                     lhs_place,
-                    Operand::Copy(cond_place).into(),
+                    Operand { kind: OperandKind::Copy(cond_place), span: None }.into(),
                     expr.into(),
                 );
                 (current, current_else)
@@ -523,7 +534,9 @@ impl MirLowerCtx<'_> {
             current,
             target_place.into(),
             match mode {
-                BindingMode::Move => Operand::Copy(cond_place).into(),
+                BindingMode::Move => {
+                    Operand { kind: OperandKind::Copy(cond_place), span: None }.into()
+                }
                 BindingMode::Ref(Mutability::Not) => Rvalue::Ref(BorrowKind::Shared, cond_place),
                 BindingMode::Ref(Mutability::Mut) => {
                     Rvalue::Ref(BorrowKind::Mut { kind: MutBorrowKind::Default }, cond_place)
@@ -547,10 +560,14 @@ impl MirLowerCtx<'_> {
         self.push_assignment(
             current,
             discr,
-            Rvalue::CheckedBinaryOp(BinOp::Eq, c, Operand::Copy(cond_place)),
+            Rvalue::CheckedBinaryOp(
+                BinOp::Eq,
+                c,
+                Operand { kind: OperandKind::Copy(cond_place), span: None },
+            ),
             pattern.into(),
         );
-        let discr = Operand::Copy(discr);
+        let discr = Operand { kind: OperandKind::Copy(discr), span: None };
         self.set_terminator(
             current,
             TerminatorKind::SwitchInt {
@@ -583,7 +600,7 @@ impl MirLowerCtx<'_> {
                     self.set_terminator(
                         current,
                         TerminatorKind::SwitchInt {
-                            discr: Operand::Copy(tmp),
+                            discr: Operand { kind: OperandKind::Copy(tmp), span: None },
                             targets: SwitchTargets::static_if(e, next, *else_target),
                         },
                         span,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs
index d4f10c032cb..d8f443145ca 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs
@@ -25,7 +25,7 @@ use crate::{
     infer::normalize,
 };
 
-use super::{MirBody, MirLowerError, Operand, Rvalue, StatementKind, TerminatorKind};
+use super::{MirBody, MirLowerError, Operand, OperandKind, Rvalue, StatementKind, TerminatorKind};
 
 macro_rules! not_supported {
     ($it: expr) => {
@@ -170,8 +170,8 @@ impl Filler<'_> {
     }
 
     fn fill_operand(&mut self, op: &mut Operand) -> Result<(), MirLowerError> {
-        match op {
-            Operand::Constant(c) => {
+        match &mut op.kind {
+            OperandKind::Constant(c) => {
                 match &c.data(Interner).value {
                     chalk_ir::ConstValue::BoundVar(b) => {
                         let resolved = self
@@ -215,7 +215,7 @@ impl Filler<'_> {
                 }
                 self.fill_const(c)?;
             }
-            Operand::Copy(_) | Operand::Move(_) | Operand::Static(_) => (),
+            OperandKind::Copy(_) | OperandKind::Move(_) | OperandKind::Static(_) => (),
         }
         Ok(())
     }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs
index f71e2978976..7ae6e907e7a 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs
@@ -18,8 +18,8 @@ use crate::{
 };
 
 use super::{
-    AggregateKind, BasicBlockId, BorrowKind, LocalId, MirBody, MutBorrowKind, Operand, Place,
-    Rvalue, UnOp,
+    AggregateKind, BasicBlockId, BorrowKind, LocalId, MirBody, MutBorrowKind, Operand, OperandKind,
+    Place, Rvalue, UnOp,
 };
 
 macro_rules! w {
@@ -374,14 +374,14 @@ impl<'a> MirPrettyCtx<'a> {
     }
 
     fn operand(&mut self, r: &Operand) {
-        match r {
-            Operand::Copy(p) | Operand::Move(p) => {
+        match &r.kind {
+            OperandKind::Copy(p) | OperandKind::Move(p) => {
                 // MIR at the time of writing doesn't have difference between move and copy, so we show them
                 // equally. Feel free to change it.
                 self.place(p);
             }
-            Operand::Constant(c) => w!(self, "Const({})", self.hir_display(c)),
-            Operand::Static(s) => w!(self, "Static({:?})", s),
+            OperandKind::Constant(c) => w!(self, "Const({})", self.hir_display(c)),
+            OperandKind::Static(s) => w!(self, "Static({:?})", s),
         }
     }
 
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs
index d2bba120b68..bcd8aa6c4e9 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs
@@ -16,7 +16,7 @@ use syntax::TextRange;
 use test_utils::extract_annotations;
 use triomphe::Arc;
 
-#[salsa::db]
+#[salsa_macros::db]
 #[derive(Clone)]
 pub(crate) struct TestDB {
     storage: salsa::Storage<Self>,
@@ -47,7 +47,7 @@ impl fmt::Debug for TestDB {
     }
 }
 
-#[salsa::db]
+#[salsa_macros::db]
 impl SourceDatabase for TestDB {
     fn file_text(&self, file_id: base_db::FileId) -> FileText {
         self.files.file_text(file_id)
@@ -102,7 +102,7 @@ impl SourceDatabase for TestDB {
     }
 }
 
-#[salsa::db]
+#[salsa_macros::db]
 impl salsa::Database for TestDB {
     fn salsa_event(&self, event: &dyn std::ops::Fn() -> salsa::Event) {
         let mut events = self.events.lock().unwrap();
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs
index eeaacbf12ea..ddc5b715194 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs
@@ -561,7 +561,7 @@ trait Foo {}
 fn test(f: impl Foo, g: &(impl Foo + ?Sized)) {
     let _: &dyn Foo = &f;
     let _: &dyn Foo = g;
-                    //^ expected &'? dyn Foo, got &'? impl Foo + ?Sized
+                    //^ expected &'? (dyn Foo + 'static), got &'? impl Foo + ?Sized
 }
         "#,
     );
@@ -827,11 +827,11 @@ struct V<T> { t: T }
 fn main() {
     let a: V<&dyn Tr>;
     (a,) = V { t: &S };
-  //^^^^expected V<&'? S>, got (V<&'? dyn Tr>,)
+  //^^^^expected V<&'? S>, got (V<&'? (dyn Tr + '?)>,)
 
     let mut a: V<&dyn Tr> = V { t: &S };
     (a,) = V { t: &S };
-  //^^^^expected V<&'? S>, got (V<&'? dyn Tr>,)
+  //^^^^expected V<&'? S>, got (V<&'? (dyn Tr + '?)>,)
 }
         "#,
     );
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs
index 60c03b52246..a986b54a7b0 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs
@@ -65,13 +65,13 @@ trait A {
 }
 trait B: A {}
 
-fn test(
+fn test<'a>(
     _: &(dyn A<Assoc = ()> + Send),
-  //^ &'_ (dyn A<Assoc = ()> + Send)
-    _: &(dyn Send + A<Assoc = ()>),
-  //^ &'_ (dyn A<Assoc = ()> + Send)
+  //^ &(dyn A<Assoc = ()> + Send + 'static)
+    _: &'a (dyn Send + A<Assoc = ()>),
+  //^ &'a (dyn A<Assoc = ()> + Send + 'static)
     _: &dyn B<Assoc = ()>,
-  //^ &'_ (dyn B<Assoc = ()>)
+  //^ &(dyn B<Assoc = ()> + 'static)
 ) {}
         "#,
     );
@@ -85,7 +85,7 @@ fn render_dyn_for_ty() {
 trait Foo<'a> {}
 
 fn foo(foo: &dyn for<'a> Foo<'a>) {}
-    // ^^^ &'_ dyn Foo<'_>
+    // ^^^ &(dyn Foo<'?> + 'static)
 "#,
     );
 }
@@ -111,11 +111,11 @@ fn test(
     b;
   //^ impl Foo
     c;
-  //^ &'_ impl Foo + ?Sized
+  //^ &impl Foo + ?Sized
     d;
   //^ S<impl Foo>
     ref_any;
-  //^^^^^^^ &'_ impl ?Sized
+  //^^^^^^^ &impl ?Sized
     empty;
 } //^^^^^ impl Sized
 "#,
@@ -192,7 +192,7 @@ fn test(
     b;
   //^ fn(impl Foo) -> impl Foo
     c;
-} //^ fn(&'_ impl Foo + ?Sized) -> &'_ impl Foo + ?Sized
+} //^ fn(&impl Foo + ?Sized) -> &impl Foo + ?Sized
 "#,
     );
 }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs
index 3a258ecad10..94826acca30 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs
@@ -1153,9 +1153,9 @@ fn dyn_trait_super_trait_not_in_scope() {
             51..55 'self': &'? Self
             64..69 '{ 0 }': u32
             66..67 '0': u32
-            176..177 'd': &'? dyn Trait
+            176..177 'd': &'? (dyn Trait + 'static)
             191..207 '{     ...o(); }': ()
-            197..198 'd': &'? dyn Trait
+            197..198 'd': &'? (dyn Trait + 'static)
             197..204 'd.foo()': u32
         "#]],
     );
@@ -2019,10 +2019,10 @@ impl dyn Error + Send {
     /// Attempts to downcast the box to a concrete type.
     pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error + Send>> {
         let err: Box<dyn Error> = self;
-                               // ^^^^ expected Box<dyn Error>, got Box<dyn Error + Send>
+                               // ^^^^ expected Box<dyn Error + 'static>, got Box<dyn Error + Send + 'static>
                                // FIXME, type mismatch should not occur
         <dyn Error>::downcast(err).map_err(|_| loop {})
-      //^^^^^^^^^^^^^^^^^^^^^ type: fn downcast<{unknown}>(Box<dyn Error>) -> Result<Box<{unknown}>, Box<dyn Error>>
+      //^^^^^^^^^^^^^^^^^^^^^ type: fn downcast<{unknown}>(Box<dyn Error + 'static>) -> Result<Box<{unknown}>, Box<dyn Error + 'static>>
     }
 }
 "#,
@@ -2170,3 +2170,26 @@ fn main() {
 "#,
     );
 }
+
+#[test]
+fn mut_to_const_pointer() {
+    check(
+        r#"
+pub trait X {
+    fn perform(self) -> u64;
+}
+
+impl X for *const u8 {
+    fn perform(self) -> u64 {
+        42
+    }
+}
+
+fn test(x: *mut u8) {
+    let _v = x.perform();
+     //      ^ adjustments: Pointer(MutToConstPointer)
+     //      ^^^^^^^^^^^ type: u64
+}
+"#,
+    );
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
index 638306054a9..47c695c6974 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
@@ -629,7 +629,7 @@ fn issue_4053_diesel_where_clauses() {
             488..522 '{     ...     }': ()
             498..502 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}>
             498..508 'self.order': O
-            498..515 'self.o...into()': dyn QueryFragment<DB>
+            498..515 'self.o...into()': dyn QueryFragment<DB> + 'static
         "#]],
     );
 }
@@ -773,7 +773,7 @@ fn issue_4800() {
         "#,
         expect![[r#"
             379..383 'self': &'? mut PeerSet<D>
-            401..424 '{     ...     }': dyn Future<Output = ()>
+            401..424 '{     ...     }': dyn Future<Output = ()> + 'static
             411..418 'loop {}': !
             416..418 '{}': ()
             575..579 'self': &'? mut Self
@@ -2278,3 +2278,26 @@ fn test(x: bool) {
         "#]],
     );
 }
+
+#[test]
+fn issue_19730() {
+    check_infer(
+        r#"
+trait Trait<T = Self> {}
+
+trait Foo {
+    type Bar<A, B>: Trait;
+
+    fn foo<A, B>(bar: Self::Bar<A, B>) {
+        let _ = bar;
+    }
+}
+"#,
+        expect![[r#"
+            83..86 'bar': Foo::Bar<Self, A, B>
+            105..133 '{     ...     }': ()
+            119..120 '_': Foo::Bar<Self, A, B>
+            123..126 'bar': Foo::Bar<Self, A, B>
+        "#]],
+    );
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
index 0f5e44151de..eeebe38f182 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
@@ -2741,11 +2741,11 @@ impl B for Astruct {}
             715..744 '#[rust...1i32])': Box<[i32; 1], Global>
             737..743 '[1i32]': [i32; 1]
             738..742 '1i32': i32
-            755..756 'v': Vec<Box<dyn B, Global>, Global>
-            776..793 '<[_]> ...to_vec': fn into_vec<Box<dyn B, Global>, Global>(Box<[Box<dyn B, Global>], Global>) -> Vec<Box<dyn B, Global>, Global>
-            776..850 '<[_]> ...ct)]))': Vec<Box<dyn B, Global>, Global>
-            794..849 '#[rust...uct)])': Box<[Box<dyn B, Global>; 1], Global>
-            816..848 '[#[rus...ruct)]': [Box<dyn B, Global>; 1]
+            755..756 'v': Vec<Box<dyn B + 'static, Global>, Global>
+            776..793 '<[_]> ...to_vec': fn into_vec<Box<dyn B + 'static, Global>, Global>(Box<[Box<dyn B + 'static, Global>], Global>) -> Vec<Box<dyn B + 'static, Global>, Global>
+            776..850 '<[_]> ...ct)]))': Vec<Box<dyn B + 'static, Global>, Global>
+            794..849 '#[rust...uct)])': Box<[Box<dyn B + 'static, Global>; 1], Global>
+            816..848 '[#[rus...ruct)]': [Box<dyn B + 'static, Global>; 1]
             817..847 '#[rust...truct)': Box<Astruct, Global>
             839..846 'Astruct': Astruct
         "#]],
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
index 2fb51acea87..14137605c9f 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
@@ -1475,26 +1475,26 @@ fn test(x: Box<dyn Trait<u64>>, y: &dyn Trait<u64>) {
         expect![[r#"
             29..33 'self': &'? Self
             54..58 'self': &'? Self
-            198..200 '{}': Box<dyn Trait<u64>>
-            210..211 'x': Box<dyn Trait<u64>>
-            234..235 'y': &'? dyn Trait<u64>
+            198..200 '{}': Box<dyn Trait<u64> + 'static>
+            210..211 'x': Box<dyn Trait<u64> + 'static>
+            234..235 'y': &'? (dyn Trait<u64> + 'static)
             254..371 '{     ...2(); }': ()
-            260..261 'x': Box<dyn Trait<u64>>
-            267..268 'y': &'? dyn Trait<u64>
-            278..279 'z': Box<dyn Trait<u64>>
-            282..285 'bar': fn bar() -> Box<dyn Trait<u64>>
-            282..287 'bar()': Box<dyn Trait<u64>>
-            293..294 'x': Box<dyn Trait<u64>>
+            260..261 'x': Box<dyn Trait<u64> + 'static>
+            267..268 'y': &'? (dyn Trait<u64> + 'static)
+            278..279 'z': Box<dyn Trait<u64> + 'static>
+            282..285 'bar': fn bar() -> Box<dyn Trait<u64> + 'static>
+            282..287 'bar()': Box<dyn Trait<u64> + 'static>
+            293..294 'x': Box<dyn Trait<u64> + 'static>
             293..300 'x.foo()': u64
-            306..307 'y': &'? dyn Trait<u64>
+            306..307 'y': &'? (dyn Trait<u64> + 'static)
             306..313 'y.foo()': u64
-            319..320 'z': Box<dyn Trait<u64>>
+            319..320 'z': Box<dyn Trait<u64> + 'static>
             319..326 'z.foo()': u64
-            332..333 'x': Box<dyn Trait<u64>>
+            332..333 'x': Box<dyn Trait<u64> + 'static>
             332..340 'x.foo2()': i64
-            346..347 'y': &'? dyn Trait<u64>
+            346..347 'y': &'? (dyn Trait<u64> + 'static)
             346..354 'y.foo2()': i64
-            360..361 'z': Box<dyn Trait<u64>>
+            360..361 'z': Box<dyn Trait<u64> + 'static>
             360..368 'z.foo2()': i64
         "#]],
     );
@@ -1523,14 +1523,14 @@ fn test(s: S<u32, i32>) {
         expect![[r#"
             32..36 'self': &'? Self
             102..106 'self': &'? S<T, U>
-            128..139 '{ loop {} }': &'? dyn Trait<T, U>
+            128..139 '{ loop {} }': &'? (dyn Trait<T, U> + 'static)
             130..137 'loop {}': !
             135..137 '{}': ()
             175..179 'self': &'? Self
             251..252 's': S<u32, i32>
             267..289 '{     ...z(); }': ()
             273..274 's': S<u32, i32>
-            273..280 's.bar()': &'? dyn Trait<u32, i32>
+            273..280 's.bar()': &'? (dyn Trait<u32, i32> + 'static)
             273..286 's.bar().baz()': (u32, i32)
         "#]],
     );
@@ -1556,20 +1556,20 @@ fn test(x: Trait, y: &Trait) -> u64 {
 }"#,
         expect![[r#"
             26..30 'self': &'? Self
-            60..62 '{}': dyn Trait
-            72..73 'x': dyn Trait
-            82..83 'y': &'? dyn Trait
+            60..62 '{}': dyn Trait + 'static
+            72..73 'x': dyn Trait + 'static
+            82..83 'y': &'? (dyn Trait + 'static)
             100..175 '{     ...o(); }': u64
-            106..107 'x': dyn Trait
-            113..114 'y': &'? dyn Trait
-            124..125 'z': dyn Trait
-            128..131 'bar': fn bar() -> dyn Trait
-            128..133 'bar()': dyn Trait
-            139..140 'x': dyn Trait
+            106..107 'x': dyn Trait + 'static
+            113..114 'y': &'? (dyn Trait + 'static)
+            124..125 'z': dyn Trait + 'static
+            128..131 'bar': fn bar() -> dyn Trait + 'static
+            128..133 'bar()': dyn Trait + 'static
+            139..140 'x': dyn Trait + 'static
             139..146 'x.foo()': u64
-            152..153 'y': &'? dyn Trait
+            152..153 'y': &'? (dyn Trait + 'static)
             152..159 'y.foo()': u64
-            165..166 'z': dyn Trait
+            165..166 'z': dyn Trait + 'static
             165..172 'z.foo()': u64
         "#]],
     );
@@ -1589,10 +1589,10 @@ fn main() {
         expect![[r#"
             31..35 'self': &'? S
             37..39 '{}': ()
-            47..48 '_': &'? dyn Fn(S)
+            47..48 '_': &'? (dyn Fn(S) + 'static)
             58..60 '{}': ()
             71..105 '{     ...()); }': ()
-            77..78 'f': fn f(&'? dyn Fn(S))
+            77..78 'f': fn f(&'? (dyn Fn(S) + 'static))
             77..102 'f(&|nu...foo())': ()
             79..101 '&|numb....foo()': &'? impl Fn(S)
             80..101 '|numbe....foo()': impl Fn(S)
@@ -2927,13 +2927,13 @@ fn test(x: &dyn Foo) {
     foo(x);
 }"#,
         expect![[r#"
-            21..22 'x': &'? dyn Foo
+            21..22 'x': &'? (dyn Foo + 'static)
             34..36 '{}': ()
-            46..47 'x': &'? dyn Foo
+            46..47 'x': &'? (dyn Foo + 'static)
             59..74 '{     foo(x); }': ()
-            65..68 'foo': fn foo(&'? dyn Foo)
+            65..68 'foo': fn foo(&'? (dyn Foo + 'static))
             65..71 'foo(x)': ()
-            69..70 'x': &'? dyn Foo
+            69..70 'x': &'? (dyn Foo + 'static)
         "#]],
     );
 }
@@ -3210,13 +3210,13 @@ fn foo() {
             218..324 '{     ...&s); }': ()
             228..229 's': Option<i32>
             232..236 'None': Option<i32>
-            246..247 'f': Box<dyn FnOnce(&'? Option<i32>)>
-            281..310 'Box { ... {}) }': Box<dyn FnOnce(&'? Option<i32>)>
+            246..247 'f': Box<dyn FnOnce(&'? Option<i32>) + 'static>
+            281..310 'Box { ... {}) }': Box<dyn FnOnce(&'? Option<i32>) + 'static>
             294..308 '&mut (|ps| {})': &'? mut impl FnOnce(&'? Option<i32>)
             300..307 '|ps| {}': impl FnOnce(&'? Option<i32>)
             301..303 'ps': &'? Option<i32>
             305..307 '{}': ()
-            316..317 'f': Box<dyn FnOnce(&'? Option<i32>)>
+            316..317 'f': Box<dyn FnOnce(&'? Option<i32>) + 'static>
             316..321 'f(&s)': ()
             318..320 '&s': &'? Option<i32>
             319..320 's': Option<i32>
@@ -4252,9 +4252,9 @@ fn f<'a>(v: &dyn Trait<Assoc<i32> = &'a i32>) {
     "#,
         expect![[r#"
             90..94 'self': &'? Self
-            127..128 'v': &'? (dyn Trait<Assoc<i32> = &'a i32>)
+            127..128 'v': &'? (dyn Trait<Assoc<i32> = &'a i32> + 'static)
             164..195 '{     ...f(); }': ()
-            170..171 'v': &'? (dyn Trait<Assoc<i32> = &'a i32>)
+            170..171 'v': &'? (dyn Trait<Assoc<i32> = &'a i32> + 'static)
             170..184 'v.get::<i32>()': &'? i32
             170..192 'v.get:...eref()': &'? i32
         "#]],
@@ -4735,7 +4735,7 @@ pub async fn foo_async<'a>() -> Box<dyn Trait + 'a>  {
 
 fn foo() {
     foo_async();
-  //^^^^^^^^^^^impl Future<Output = Box<dyn Trait>> + ?Sized
+  //^^^^^^^^^^^impl Future<Output = Box<dyn Trait + '?>> + ?Sized
 }
 "#,
     )
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs
index a5c195d4086..f9f8776cff7 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs
@@ -8,10 +8,7 @@ use chalk_recursive::Cache;
 use chalk_solve::{Solver, logging_db::LoggingRustIrDatabase, rust_ir};
 
 use base_db::Crate;
-use hir_def::{
-    BlockId, TraitId,
-    lang_item::{LangItem, LangItemTarget},
-};
+use hir_def::{BlockId, TraitId, lang_item::LangItem};
 use hir_expand::name::Name;
 use intern::sym;
 use span::Edition;
@@ -292,10 +289,6 @@ impl FnTrait {
     }
 
     pub fn get_id(self, db: &dyn HirDatabase, krate: Crate) -> Option<TraitId> {
-        let target = db.lang_item(krate, self.lang_item())?;
-        match target {
-            LangItemTarget::Trait(t) => Some(t),
-            _ => None,
-        }
+        self.lang_item().resolve_trait(db, krate)
     }
 }
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 198f715a6db..1e0ff423ded 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
@@ -36,8 +36,7 @@ use crate::{
 pub(crate) fn fn_traits(db: &dyn DefDatabase, krate: Crate) -> impl Iterator<Item = TraitId> + '_ {
     [LangItem::Fn, LangItem::FnMut, LangItem::FnOnce]
         .into_iter()
-        .filter_map(move |lang| db.lang_item(krate, lang))
-        .flat_map(|it| it.as_trait())
+        .filter_map(move |lang| lang.resolve_trait(db, krate))
 }
 
 /// Returns an iterator over the direct super traits (including the trait itself).
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs
index 4e9aa5610a5..6e1cd9a310f 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs
@@ -22,7 +22,6 @@ use crate::{
 use chalk_ir::Mutability;
 use hir_def::signatures::StructFlags;
 use hir_def::{AdtId, GenericDefId, GenericParamId, VariantId};
-use salsa::CycleRecoveryAction;
 use std::fmt;
 use std::ops::Not;
 use stdx::never;
@@ -55,14 +54,14 @@ pub(crate) fn variances_of(db: &dyn HirDatabase, def: GenericDefId) -> Option<Ar
     variances.is_empty().not().then(|| Arc::from_iter(variances))
 }
 
-pub(crate) fn variances_of_cycle_fn(
-    _db: &dyn HirDatabase,
-    _result: &Option<Arc<[Variance]>>,
-    _count: u32,
-    _def: GenericDefId,
-) -> CycleRecoveryAction<Option<Arc<[Variance]>>> {
-    CycleRecoveryAction::Iterate
-}
+// pub(crate) fn variances_of_cycle_fn(
+//     _db: &dyn HirDatabase,
+//     _result: &Option<Arc<[Variance]>>,
+//     _count: u32,
+//     _def: GenericDefId,
+// ) -> salsa::CycleRecoveryAction<Option<Arc<[Variance]>>> {
+//     salsa::CycleRecoveryAction::Iterate
+// }
 
 pub(crate) fn variances_of_cycle_initial(
     db: &dyn HirDatabase,
@@ -966,7 +965,7 @@ struct S3<T>(S<T, T>);
 struct FixedPoint<T, U, V>(&'static FixedPoint<(), T, U>, V);
 "#,
             expect![[r#"
-                FixedPoint[T: covariant, U: covariant, V: covariant]
+                FixedPoint[T: bivariant, U: bivariant, V: bivariant]
             "#]],
         );
     }
diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs
index 53817f37aa6..124ab8e274a 100644
--- a/src/tools/rust-analyzer/crates/hir/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/display.rs
@@ -516,8 +516,7 @@ impl HirDisplay for TypeParam {
             return Ok(());
         }
 
-        let sized_trait =
-            f.db.lang_item(krate, LangItem::Sized).and_then(|lang_item| lang_item.as_trait());
+        let sized_trait = LangItem::Sized.resolve_trait(f.db, krate);
         let has_only_sized_bound = predicates.iter().all(move |pred| match pred.skip_binders() {
             WhereClause::Implemented(it) => Some(it.hir_trait_id()) == sized_trait,
             _ => false,
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index 143c13069e4..3f1d5bb01f2 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -53,7 +53,6 @@ use hir_def::{
         generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
     },
     item_tree::{AttrOwner, FieldParent, ImportAlias, ItemTreeFieldId, ItemTreeNode},
-    lang_item::LangItemTarget,
     layout::{self, ReprOptions, TargetDataLayout},
     nameres::{self, diagnostics::DefDiagnostic},
     per_ns::PerNs,
@@ -137,7 +136,6 @@ pub use {
             HirFileRange, InFile, InFileWrapper, InMacroFile, InRealFile, MacroFilePosition,
             MacroFileRange,
         },
-        hygiene::{SyntaxContextExt, marks_rev},
         inert_attr_macro::AttributeTemplate,
         mod_path::{ModPath, PathKind, tool_path},
         name::Name,
@@ -781,7 +779,7 @@ impl Module {
             let drop_maybe_dangle = (|| {
                 // FIXME: This can be simplified a lot by exposing hir-ty's utils.rs::Generics helper
                 let trait_ = trait_?;
-                let drop_trait = db.lang_item(self.krate().into(), LangItem::Drop)?.as_trait()?;
+                let drop_trait = LangItem::Drop.resolve_trait(db, self.krate().into())?;
                 if drop_trait != trait_.into() {
                     return None;
                 }
@@ -2388,14 +2386,11 @@ impl Function {
         }
 
         let Some(impl_traits) = self.ret_type(db).as_impl_traits(db) else { return false };
-        let Some(future_trait_id) =
-            db.lang_item(self.ty(db).env.krate, LangItem::Future).and_then(|t| t.as_trait())
+        let Some(future_trait_id) = LangItem::Future.resolve_trait(db, self.ty(db).env.krate)
         else {
             return false;
         };
-        let Some(sized_trait_id) =
-            db.lang_item(self.ty(db).env.krate, LangItem::Sized).and_then(|t| t.as_trait())
-        else {
+        let Some(sized_trait_id) = LangItem::Sized.resolve_trait(db, self.ty(db).env.krate) else {
             return false;
         };
 
@@ -2861,9 +2856,7 @@ pub struct Trait {
 
 impl Trait {
     pub fn lang(db: &dyn HirDatabase, krate: Crate, name: &Name) -> Option<Trait> {
-        db.lang_item(krate.into(), LangItem::from_name(name)?)
-            .and_then(LangItemTarget::as_trait)
-            .map(Into::into)
+        LangItem::from_name(name)?.resolve_trait(db, krate.into()).map(Into::into)
     }
 
     pub fn module(self, db: &dyn HirDatabase) -> Module {
@@ -3692,24 +3685,16 @@ impl GenericDef {
         }
 
         let source_map = match def {
-            GenericDefId::AdtId(AdtId::EnumId(it)) => {
-                db.enum_signature_with_source_map(it).1.clone()
-            }
-            GenericDefId::AdtId(AdtId::StructId(it)) => {
-                db.struct_signature_with_source_map(it).1.clone()
-            }
-            GenericDefId::AdtId(AdtId::UnionId(it)) => {
-                db.union_signature_with_source_map(it).1.clone()
-            }
+            GenericDefId::AdtId(AdtId::EnumId(it)) => db.enum_signature_with_source_map(it).1,
+            GenericDefId::AdtId(AdtId::StructId(it)) => db.struct_signature_with_source_map(it).1,
+            GenericDefId::AdtId(AdtId::UnionId(it)) => db.union_signature_with_source_map(it).1,
             GenericDefId::ConstId(_) => return,
-            GenericDefId::FunctionId(it) => db.function_signature_with_source_map(it).1.clone(),
-            GenericDefId::ImplId(it) => db.impl_signature_with_source_map(it).1.clone(),
+            GenericDefId::FunctionId(it) => db.function_signature_with_source_map(it).1,
+            GenericDefId::ImplId(it) => db.impl_signature_with_source_map(it).1,
             GenericDefId::StaticId(_) => return,
-            GenericDefId::TraitAliasId(it) => {
-                db.trait_alias_signature_with_source_map(it).1.clone()
-            }
-            GenericDefId::TraitId(it) => db.trait_signature_with_source_map(it).1.clone(),
-            GenericDefId::TypeAliasId(it) => db.type_alias_signature_with_source_map(it).1.clone(),
+            GenericDefId::TraitAliasId(it) => db.trait_alias_signature_with_source_map(it).1,
+            GenericDefId::TraitId(it) => db.trait_signature_with_source_map(it).1,
+            GenericDefId::TypeAliasId(it) => db.type_alias_signature_with_source_map(it).1,
         };
 
         expr_store_diagnostics(db, acc, &source_map);
@@ -3809,7 +3794,7 @@ impl GenericSubstitution {
         container_params
             .chain(self_params)
             .filter_map(|(ty, name)| {
-                Some((name?.symbol().clone(), Type { ty: ty.clone(), env: self.env.clone() }))
+                Some((name?.symbol().clone(), Type { ty, env: self.env.clone() }))
             })
             .collect()
     }
@@ -4989,18 +4974,14 @@ impl Type {
     /// `std::future::Future` and returns the `Output` associated type.
     /// This function is used in `.await` syntax completion.
     pub fn into_future_output(&self, db: &dyn HirDatabase) -> Option<Type> {
-        let trait_ = db
-            .lang_item(self.env.krate, LangItem::IntoFutureIntoFuture)
-            .and_then(|it| {
-                let into_future_fn = it.as_function()?;
+        let trait_ = LangItem::IntoFutureIntoFuture
+            .resolve_function(db, self.env.krate)
+            .and_then(|into_future_fn| {
                 let assoc_item = as_assoc_item(db, AssocItem::Function, into_future_fn)?;
                 let into_future_trait = assoc_item.container_or_implemented_trait(db)?;
                 Some(into_future_trait.id)
             })
-            .or_else(|| {
-                let future_trait = db.lang_item(self.env.krate, LangItem::Future)?;
-                future_trait.as_trait()
-            })?;
+            .or_else(|| LangItem::Future.resolve_trait(db, self.env.krate))?;
 
         let canonical_ty =
             Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
@@ -5015,14 +4996,13 @@ impl Type {
 
     /// This does **not** resolve `IntoFuture`, only `Future`.
     pub fn future_output(self, db: &dyn HirDatabase) -> Option<Type> {
-        let future_output =
-            db.lang_item(self.env.krate, LangItem::FutureOutput)?.as_type_alias()?;
+        let future_output = LangItem::FutureOutput.resolve_type_alias(db, self.env.krate)?;
         self.normalize_trait_assoc_type(db, &[], future_output.into())
     }
 
     /// This does **not** resolve `IntoIterator`, only `Iterator`.
     pub fn iterator_item(self, db: &dyn HirDatabase) -> Option<Type> {
-        let iterator_trait = db.lang_item(self.env.krate, LangItem::Iterator)?.as_trait()?;
+        let iterator_trait = LangItem::Iterator.resolve_trait(db, self.env.krate)?;
         let iterator_item = db
             .trait_items(iterator_trait)
             .associated_type_by_name(&Name::new_symbol_root(sym::Item))?;
@@ -5030,9 +5010,7 @@ impl Type {
     }
 
     pub fn impls_iterator(self, db: &dyn HirDatabase) -> bool {
-        let Some(iterator_trait) =
-            db.lang_item(self.env.krate, LangItem::Iterator).and_then(|it| it.as_trait())
-        else {
+        let Some(iterator_trait) = LangItem::Iterator.resolve_trait(db, self.env.krate) else {
             return false;
         };
         let canonical_ty =
@@ -5042,12 +5020,13 @@ impl Type {
 
     /// Resolves the projection `<Self as IntoIterator>::IntoIter` and returns the resulting type
     pub fn into_iterator_iter(self, db: &dyn HirDatabase) -> Option<Type> {
-        let trait_ = db.lang_item(self.env.krate, LangItem::IntoIterIntoIter).and_then(|it| {
-            let into_iter_fn = it.as_function()?;
-            let assoc_item = as_assoc_item(db, AssocItem::Function, into_iter_fn)?;
-            let into_iter_trait = assoc_item.container_or_implemented_trait(db)?;
-            Some(into_iter_trait.id)
-        })?;
+        let trait_ = LangItem::IntoIterIntoIter.resolve_function(db, self.env.krate).and_then(
+            |into_iter_fn| {
+                let assoc_item = as_assoc_item(db, AssocItem::Function, into_iter_fn)?;
+                let into_iter_trait = assoc_item.container_or_implemented_trait(db)?;
+                Some(into_iter_trait.id)
+            },
+        )?;
 
         let canonical_ty =
             Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
@@ -5133,10 +5112,8 @@ impl Type {
     }
 
     pub fn is_copy(&self, db: &dyn HirDatabase) -> bool {
-        let lang_item = db.lang_item(self.env.krate, LangItem::Copy);
-        let copy_trait = match lang_item {
-            Some(LangItemTarget::Trait(it)) => it,
-            _ => return false,
+        let Some(copy_trait) = LangItem::Copy.resolve_trait(db, self.env.krate) else {
+            return false;
         };
         self.impls_trait(db, copy_trait.into(), &[])
     }
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
index f708f2e1667..4d092c1f0bb 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
@@ -25,7 +25,6 @@ use hir_expand::{
     builtin::{BuiltinFnLikeExpander, EagerExpander},
     db::ExpandDatabase,
     files::{FileRangeWrapper, InRealFile},
-    hygiene::SyntaxContextExt as _,
     inert_attr_macro::find_builtin_attr_idx,
     mod_path::{ModPath, PathKind},
     name::AsName,
@@ -927,7 +926,7 @@ impl<'db> SemanticsImpl<'db> {
         token: InRealFile<SyntaxToken>,
         mut cb: impl FnMut(InFile<SyntaxToken>, SyntaxContext) -> ControlFlow<T>,
     ) -> Option<T> {
-        self.descend_into_macros_impl(token.clone(), &mut cb)
+        self.descend_into_macros_impl(token, &mut cb)
     }
 
     /// Descends the token into expansions, returning the tokens that matches the input
@@ -959,17 +958,13 @@ impl<'db> SemanticsImpl<'db> {
         let text = token.text();
         let kind = token.kind();
         if let Ok(token) = self.wrap_token_infile(token.clone()).into_real_file() {
-            self.descend_into_macros_breakable(
-                token.clone(),
-                |InFile { value, file_id: _ }, _ctx| {
-                    let mapped_kind = value.kind();
-                    let any_ident_match =
-                        || kind.is_any_identifier() && value.kind().is_any_identifier();
-                    let matches =
-                        (kind == mapped_kind || any_ident_match()) && text == value.text();
-                    if matches { ControlFlow::Break(value) } else { ControlFlow::Continue(()) }
-                },
-            )
+            self.descend_into_macros_breakable(token, |InFile { value, file_id: _ }, _ctx| {
+                let mapped_kind = value.kind();
+                let any_ident_match =
+                    || kind.is_any_identifier() && value.kind().is_any_identifier();
+                let matches = (kind == mapped_kind || any_ident_match()) && text == value.text();
+                if matches { ControlFlow::Break(value) } else { ControlFlow::Continue(()) }
+            })
         } else {
             None
         }
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs
index 466bf7f6c82..587c51d8cc9 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs
@@ -559,7 +559,7 @@ impl SourceToDefCtx<'_, '_> {
             let item = match ast::Item::cast(value.clone()) {
                 Some(it) => it,
                 None => {
-                    let variant = ast::Variant::cast(value.clone())?;
+                    let variant = ast::Variant::cast(value)?;
                     return this
                         .enum_variant_to_def(InFile::new(file_id, &variant))
                         .map(Into::into);
diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
index 666efe8ec64..c1a75ce7e57 100644
--- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
@@ -556,8 +556,8 @@ impl SourceAnalyzer {
             }
         }
 
-        let future_trait = db.lang_item(self.resolver.krate(), LangItem::Future)?.as_trait()?;
-        let poll_fn = db.lang_item(self.resolver.krate(), LangItem::FuturePoll)?.as_function()?;
+        let future_trait = LangItem::Future.resolve_trait(db, self.resolver.krate())?;
+        let poll_fn = LangItem::FuturePoll.resolve_function(db, self.resolver.krate())?;
         // HACK: subst for `poll()` coincides with that for `Future` because `poll()` itself
         // doesn't have any generic parameters, so we skip building another subst for `poll()`.
         let substs = hir_ty::TyBuilder::subst_for_def(db, future_trait, None).push(ty).build();
@@ -666,7 +666,7 @@ impl SourceAnalyzer {
     ) -> Option<FunctionId> {
         let ty = self.ty_of_expr(try_expr.expr()?)?;
 
-        let op_fn = db.lang_item(self.resolver.krate(), LangItem::TryTraitBranch)?.as_function()?;
+        let op_fn = LangItem::TryTraitBranch.resolve_function(db, self.resolver.krate())?;
         let op_trait = match op_fn.lookup(db).container {
             ItemContainerId::TraitId(id) => id,
             _ => return None,
@@ -1425,13 +1425,13 @@ impl SourceAnalyzer {
         lang_trait: LangItem,
         method_name: &Name,
     ) -> Option<(TraitId, FunctionId)> {
-        let trait_id = db.lang_item(self.resolver.krate(), lang_trait)?.as_trait()?;
+        let trait_id = lang_trait.resolve_trait(db, self.resolver.krate())?;
         let fn_id = db.trait_items(trait_id).method_by_name(method_name)?;
         Some((trait_id, fn_id))
     }
 
     fn ty_of_expr(&self, expr: ast::Expr) -> Option<&Ty> {
-        self.infer()?.type_of_expr_or_pat(self.expr_id(expr.clone())?)
+        self.infer()?.type_of_expr_or_pat(self.expr_id(expr)?)
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs
index 41064d047a5..e87ab87407f 100644
--- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs
@@ -13,13 +13,13 @@ use hir_def::{
 use hir_expand::{HirFileId, name::Name};
 use hir_ty::{
     db::HirDatabase,
-    display::{DisplayTarget, HirDisplay, hir_display_with_store},
+    display::{HirDisplay, hir_display_with_store},
 };
 use intern::Symbol;
 use rustc_hash::FxHashMap;
 use syntax::{AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, ToSmolStr, ast::HasName};
 
-use crate::{Module, ModuleDef, Semantics};
+use crate::{HasCrate, Module, ModuleDef, Semantics};
 
 pub type FxIndexSet<T> = indexmap::IndexSet<T, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
 
@@ -66,7 +66,6 @@ pub struct SymbolCollector<'a> {
     symbols: FxIndexSet<FileSymbol>,
     work: Vec<SymbolCollectorWork>,
     current_container_name: Option<SmolStr>,
-    display_target: DisplayTarget,
 }
 
 /// Given a [`ModuleId`] and a [`HirDatabase`], use the DefMap for the module's crate to collect
@@ -78,10 +77,6 @@ impl<'a> SymbolCollector<'a> {
             symbols: Default::default(),
             work: Default::default(),
             current_container_name: None,
-            display_target: DisplayTarget::from_crate(
-                db,
-                *db.all_crates().last().expect("no crate graph present"),
-            ),
         }
     }
 
@@ -93,8 +88,7 @@ impl<'a> SymbolCollector<'a> {
 
     pub fn collect(&mut self, module: Module) {
         let _p = tracing::info_span!("SymbolCollector::collect", ?module).entered();
-        tracing::info!(?module, "SymbolCollector::collect",);
-        self.display_target = module.krate().to_display_target(self.db);
+        tracing::info!(?module, "SymbolCollector::collect");
 
         // The initial work is the root module we're collecting, additional work will
         // be populated as we traverse the module's definitions.
@@ -263,8 +257,9 @@ impl<'a> SymbolCollector<'a> {
         for (name, Item { def, vis, import }) in scope.macros() {
             if let Some(i) = import {
                 match i {
-                    ImportOrGlob::Import(i) => push_import(self, i, name, def.into(), vis),
-                    ImportOrGlob::Glob(_) => (),
+                    ImportOrExternCrate::Import(i) => push_import(self, i, name, def.into(), vis),
+                    ImportOrExternCrate::Glob(_) => (),
+                    ImportOrExternCrate::ExternCrate(_) => (),
                 }
                 continue;
             }
@@ -320,7 +315,10 @@ impl<'a> SymbolCollector<'a> {
         let impl_data = self.db.impl_signature(impl_id);
         let impl_name = Some(
             hir_display_with_store(impl_data.self_ty, &impl_data.store)
-                .display(self.db, self.display_target)
+                .display(
+                    self.db,
+                    crate::Impl::from(impl_id).krate(self.db).to_display_target(self.db),
+                )
                 .to_smolstr(),
         );
         self.with_container_name(impl_name, |s| {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs b/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs
index 2de0013bb12..fb569f8cdae 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs
@@ -5,7 +5,7 @@
 //! assists if we are allowed to.
 
 use hir::ImportPathConfig;
-use ide_db::{SnippetCap, imports::insert_use::InsertUseConfig};
+use ide_db::{SnippetCap, assists::ExprFillDefaultMode, imports::insert_use::InsertUseConfig};
 
 use crate::AssistKind;
 
@@ -21,6 +21,7 @@ pub struct AssistConfig {
     pub term_search_fuel: u64,
     pub term_search_borrowck: bool,
     pub code_action_grouping: bool,
+    pub expr_fill_default: ExprFillDefaultMode,
 }
 
 impl AssistConfig {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs
index 887ec5aeec9..6a55f39e693 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs
@@ -150,6 +150,7 @@ fn add_missing_impl_members_inner(
         let new_impl_def = edit.make_mut(impl_def.clone());
         let first_new_item = add_trait_assoc_items_to_impl(
             &ctx.sema,
+            ctx.config,
             &missing_items,
             trait_,
             &new_impl_def,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs
index 8c1c83e3f71..858d4369914 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs
@@ -3,6 +3,7 @@ use std::iter::{self, Peekable};
 use either::Either;
 use hir::{Adt, Crate, HasAttrs, ImportPathConfig, ModuleDef, Semantics, sym};
 use ide_db::RootDatabase;
+use ide_db::assists::ExprFillDefaultMode;
 use ide_db::syntax_helpers::suggest_name;
 use ide_db::{famous_defs::FamousDefs, helpers::mod_path_to_ast};
 use itertools::Itertools;
@@ -216,7 +217,17 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
                     // filter out hidden patterns because they're handled by the catch-all arm
                     !hidden
                 })
-                .map(|(pat, _)| make.match_arm(pat, None, make::ext::expr_todo()));
+                .map(|(pat, _)| {
+                    make.match_arm(
+                        pat,
+                        None,
+                        match ctx.config.expr_fill_default {
+                            ExprFillDefaultMode::Todo => make::ext::expr_todo(),
+                            ExprFillDefaultMode::Underscore => make::ext::expr_underscore(),
+                            ExprFillDefaultMode::Default => make::ext::expr_todo(),
+                        },
+                    )
+                });
 
             let mut arms: Vec<_> = match_arm_list
                 .arms()
@@ -246,7 +257,15 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
 
             if needs_catch_all_arm && !has_catch_all_arm {
                 cov_mark::hit!(added_wildcard_pattern);
-                let arm = make.match_arm(make.wildcard_pat().into(), None, make::ext::expr_todo());
+                let arm = make.match_arm(
+                    make.wildcard_pat().into(),
+                    None,
+                    match ctx.config.expr_fill_default {
+                        ExprFillDefaultMode::Todo => make::ext::expr_todo(),
+                        ExprFillDefaultMode::Underscore => make::ext::expr_underscore(),
+                        ExprFillDefaultMode::Default => make::ext::expr_todo(),
+                    },
+                );
                 arms.push(arm);
             }
 
@@ -474,8 +493,8 @@ fn build_pat(
                 hir::StructKind::Record => {
                     let fields = fields
                         .into_iter()
-                        .map(|f| make.name_ref(f.name(db).as_str()))
-                        .map(|name_ref| make.record_pat_field_shorthand(name_ref));
+                        .map(|f| make.ident_pat(false, false, make.name(f.name(db).as_str())))
+                        .map(|ident| make.record_pat_field_shorthand(ident.into()));
                     let fields = make.record_pat_field_list(fields, None);
                     make.record_pat_with_fields(path, fields).into()
                 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs
index cd23ad22372..bcd06c1ef72 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs
@@ -196,7 +196,7 @@ pub(crate) fn convert_bool_then_to_if(acc: &mut Assists, ctx: &AssistContext<'_>
             // Wrap all tails in `Some(...)`
             let none_path = mapless_make.expr_path(mapless_make.ident_path("None"));
             let some_path = mapless_make.expr_path(mapless_make.ident_path("Some"));
-            for_each_tail_expr(&ast::Expr::BlockExpr(closure_body.clone()), &mut |e| {
+            for_each_tail_expr(&ast::Expr::BlockExpr(closure_body), &mut |e| {
                 let e = match e {
                     ast::Expr::BreakExpr(e) => e.expr(),
                     ast::Expr::ReturnExpr(e) => e.expr(),
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs
index 1d3a2db3352..43515de71e2 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs
@@ -1066,7 +1066,7 @@ fn foo() {
             r#"
 fn foo() {
     let (mut a, b) = (0.1, "abc");
-    fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&str) {
+    fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&'static str) {
         *a = 1.2;
         let c = *b;
     }
@@ -1098,7 +1098,7 @@ fn foo() {
             r#"
 fn foo() {
     let (mut a, b) = (0.1, "abc");
-    fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&str) {
+    fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&'static str) {
         let _: &mut bool = p2;
         *a = 1.2;
         let c = *b;
@@ -1136,7 +1136,7 @@ fn foo() {
             r#"
 fn foo() {
     let (mut a, b) = (0.1, "abc");
-    fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&str) {
+    fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&'static str) {
         let _: &mut bool = p2;
         *a = 1.2;
         let c = *b;
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs
index 24cc32d10d8..db41927f1df 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs
@@ -80,7 +80,7 @@ pub(crate) fn convert_from_to_tryfrom(acc: &mut Assists, ctx: &AssistContext<'_>
             let from_fn_name = builder.make_mut(from_fn_name);
             let tail_expr = builder.make_mut(tail_expr);
             let return_exprs = return_exprs.map(|r| builder.make_mut(r)).collect_vec();
-            let associated_items = builder.make_mut(associated_items).clone();
+            let associated_items = builder.make_mut(associated_items);
 
             ted::replace(
                 trait_ty.syntax(),
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs
index df92b07cba7..ebfed9f9ca9 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs
@@ -1,8 +1,9 @@
-use hir::Semantics;
-use ide_db::RootDatabase;
 use syntax::T;
 use syntax::ast::RangeItem;
-use syntax::ast::{AstNode, HasName, LetStmt, Name, Pat, edit::AstNodeEdit};
+use syntax::ast::edit::IndentLevel;
+use syntax::ast::edit_in_place::Indent;
+use syntax::ast::syntax_factory::SyntaxFactory;
+use syntax::ast::{self, AstNode, HasName, LetStmt, Pat};
 
 use crate::{AssistContext, AssistId, Assists};
 
@@ -25,155 +26,205 @@ use crate::{AssistContext, AssistId, Assists};
 // }
 // ```
 pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
-    // should focus on else token to trigger
+    // Should focus on the `else` token to trigger
     let let_stmt = ctx
         .find_token_syntax_at_offset(T![else])
         .and_then(|it| it.parent()?.parent())
         .or_else(|| ctx.find_token_syntax_at_offset(T![let])?.parent())?;
     let let_stmt = LetStmt::cast(let_stmt)?;
-    let let_else_block = let_stmt.let_else()?.block_expr()?;
-    let let_init = let_stmt.initializer()?;
+    let else_block = let_stmt.let_else()?.block_expr()?;
+    let else_expr = if else_block.statements().next().is_none() {
+        else_block.tail_expr()?
+    } else {
+        else_block.into()
+    };
+    let init = let_stmt.initializer()?;
+    // Ignore let stmt with type annotation
     if let_stmt.ty().is_some() {
-        // don't support let with type annotation
         return None;
     }
     let pat = let_stmt.pat()?;
-    let mut binders = Vec::new();
-    binders_in_pat(&mut binders, &pat, &ctx.sema)?;
 
-    let target = let_stmt.syntax().text_range();
+    let make = SyntaxFactory::with_mappings();
+    let mut idents = Vec::default();
+    let pat_without_mut = remove_mut_and_collect_idents(&make, &pat, &mut idents)?;
+    let bindings = idents
+        .into_iter()
+        .filter_map(|ref pat| {
+            // Identifiers which resolve to constants are not bindings
+            if ctx.sema.resolve_bind_pat_to_const(pat).is_none() {
+                Some((pat.name()?, pat.ref_token().is_none() && pat.mut_token().is_some()))
+            } else {
+                None
+            }
+        })
+        .collect::<Vec<_>>();
+
     acc.add(
         AssistId::refactor_rewrite("convert_let_else_to_match"),
-        "Convert let-else to let and match",
-        target,
-        |edit| {
-            let indent_level = let_stmt.indent_level().0 as usize;
-            let indent = "    ".repeat(indent_level);
-            let indent1 = "    ".repeat(indent_level + 1);
+        if bindings.is_empty() {
+            "Convert let-else to match"
+        } else {
+            "Convert let-else to let and match"
+        },
+        let_stmt.syntax().text_range(),
+        |builder| {
+            let mut editor = builder.make_editor(let_stmt.syntax());
 
-            let binders_str = binders_to_str(&binders, false);
-            let binders_str_mut = binders_to_str(&binders, true);
+            let binding_paths = bindings
+                .iter()
+                .map(|(name, _)| make.expr_path(make.ident_path(&name.to_string())))
+                .collect::<Vec<_>>();
 
-            let init_expr = let_init.syntax().text();
-            let mut pat_no_mut = pat.syntax().text().to_string();
-            // remove the mut from the pattern
-            for (b, ismut) in binders.iter() {
-                if *ismut {
-                    pat_no_mut = pat_no_mut.replace(&format!("mut {b}"), &b.to_string());
-                }
-            }
+            let binding_arm = make.match_arm(
+                pat_without_mut,
+                None,
+                // There are three possible cases:
+                //
+                // - No bindings: `None => {}`
+                // - Single binding: `Some(it) => it`
+                // - Multiple bindings: `Foo::Bar { a, b, .. } => (a, b)`
+                match binding_paths.len() {
+                    0 => make.expr_empty_block().into(),
 
-            let only_expr = let_else_block.statements().next().is_none();
-            let branch2 = match &let_else_block.tail_expr() {
-                Some(tail) if only_expr => format!("{tail},"),
-                _ => let_else_block.syntax().text().to_string(),
-            };
-            let replace = if binders.is_empty() {
-                format!(
-                    "match {init_expr} {{
-{indent1}{pat_no_mut} => {binders_str}
-{indent1}_ => {branch2}
-{indent}}}"
-                )
+                    1 => binding_paths[0].clone(),
+                    _ => make.expr_tuple(binding_paths).into(),
+                },
+            );
+            let else_arm = make.match_arm(make.wildcard_pat().into(), None, else_expr);
+            let match_ = make.expr_match(init, make.match_arm_list([binding_arm, else_arm]));
+            match_.reindent_to(IndentLevel::from_node(let_stmt.syntax()));
+
+            if bindings.is_empty() {
+                editor.replace(let_stmt.syntax(), match_.syntax());
             } else {
-                format!(
-                    "let {binders_str_mut} = match {init_expr} {{
-{indent1}{pat_no_mut} => {binders_str},
-{indent1}_ => {branch2}
-{indent}}};"
-                )
-            };
-            edit.replace(target, replace);
+                let ident_pats = bindings
+                    .into_iter()
+                    .map(|(name, is_mut)| make.ident_pat(false, is_mut, name).into())
+                    .collect::<Vec<Pat>>();
+                let new_let_stmt = make.let_stmt(
+                    if ident_pats.len() == 1 {
+                        ident_pats[0].clone()
+                    } else {
+                        make.tuple_pat(ident_pats).into()
+                    },
+                    None,
+                    Some(match_.into()),
+                );
+                editor.replace(let_stmt.syntax(), new_let_stmt.syntax());
+            }
+
+            editor.add_mappings(make.finish_with_mappings());
+            builder.add_file_edits(ctx.vfs_file_id(), editor);
         },
     )
 }
 
-/// Gets a list of binders in a pattern, and whether they are mut.
-fn binders_in_pat(
-    acc: &mut Vec<(Name, bool)>,
-    pat: &Pat,
-    sem: &Semantics<'_, RootDatabase>,
-) -> Option<()> {
-    use Pat::*;
-    match pat {
-        IdentPat(p) => {
-            let ident = p.name()?;
-            let ismut = p.ref_token().is_none() && p.mut_token().is_some();
-            // check for const reference
-            if sem.resolve_bind_pat_to_const(p).is_none() {
-                acc.push((ident, ismut));
-            }
+fn remove_mut_and_collect_idents(
+    make: &SyntaxFactory,
+    pat: &ast::Pat,
+    acc: &mut Vec<ast::IdentPat>,
+) -> Option<ast::Pat> {
+    Some(match pat {
+        ast::Pat::IdentPat(p) => {
+            acc.push(p.clone());
+            let non_mut_pat = make.ident_pat(
+                p.ref_token().is_some(),
+                p.ref_token().is_some() && p.mut_token().is_some(),
+                p.name()?,
+            );
             if let Some(inner) = p.pat() {
-                binders_in_pat(acc, &inner, sem)?;
-            }
-            Some(())
-        }
-        BoxPat(p) => p.pat().and_then(|p| binders_in_pat(acc, &p, sem)),
-        RestPat(_) | LiteralPat(_) | PathPat(_) | WildcardPat(_) | ConstBlockPat(_) => Some(()),
-        OrPat(p) => {
-            for p in p.pats() {
-                binders_in_pat(acc, &p, sem)?;
+                non_mut_pat.set_pat(remove_mut_and_collect_idents(make, &inner, acc));
             }
-            Some(())
+            non_mut_pat.into()
         }
-        ParenPat(p) => p.pat().and_then(|p| binders_in_pat(acc, &p, sem)),
-        RangePat(p) => {
-            if let Some(st) = p.start() {
-                binders_in_pat(acc, &st, sem)?
-            }
-            if let Some(ed) = p.end() {
-                binders_in_pat(acc, &ed, sem)?
-            }
-            Some(())
-        }
-        RecordPat(p) => {
-            for f in p.record_pat_field_list()?.fields() {
-                let pat = f.pat()?;
-                binders_in_pat(acc, &pat, sem)?;
-            }
-            Some(())
+        ast::Pat::BoxPat(p) => {
+            make.box_pat(remove_mut_and_collect_idents(make, &p.pat()?, acc)?).into()
         }
-        RefPat(p) => p.pat().and_then(|p| binders_in_pat(acc, &p, sem)),
-        SlicePat(p) => {
-            for p in p.pats() {
-                binders_in_pat(acc, &p, sem)?;
-            }
-            Some(())
-        }
-        TuplePat(p) => {
-            for p in p.fields() {
-                binders_in_pat(acc, &p, sem)?;
-            }
-            Some(())
+        ast::Pat::OrPat(p) => make
+            .or_pat(
+                p.pats()
+                    .map(|pat| remove_mut_and_collect_idents(make, &pat, acc))
+                    .collect::<Option<Vec<_>>>()?,
+                p.leading_pipe().is_some(),
+            )
+            .into(),
+        ast::Pat::ParenPat(p) => {
+            make.paren_pat(remove_mut_and_collect_idents(make, &p.pat()?, acc)?).into()
         }
-        TupleStructPat(p) => {
-            for p in p.fields() {
-                binders_in_pat(acc, &p, sem)?;
+        ast::Pat::RangePat(p) => make
+            .range_pat(
+                if let Some(start) = p.start() {
+                    Some(remove_mut_and_collect_idents(make, &start, acc)?)
+                } else {
+                    None
+                },
+                if let Some(end) = p.end() {
+                    Some(remove_mut_and_collect_idents(make, &end, acc)?)
+                } else {
+                    None
+                },
+            )
+            .into(),
+        ast::Pat::RecordPat(p) => make
+            .record_pat_with_fields(
+                p.path()?,
+                make.record_pat_field_list(
+                    p.record_pat_field_list()?
+                        .fields()
+                        .map(|field| {
+                            remove_mut_and_collect_idents(make, &field.pat()?, acc).map(|pat| {
+                                if let Some(name_ref) = field.name_ref() {
+                                    make.record_pat_field(name_ref, pat)
+                                } else {
+                                    make.record_pat_field_shorthand(pat)
+                                }
+                            })
+                        })
+                        .collect::<Option<Vec<_>>>()?,
+                    p.record_pat_field_list()?.rest_pat(),
+                ),
+            )
+            .into(),
+        ast::Pat::RefPat(p) => {
+            let inner = p.pat()?;
+            if let ast::Pat::IdentPat(ident) = inner {
+                acc.push(ident);
+                p.clone_for_update().into()
+            } else {
+                make.ref_pat(remove_mut_and_collect_idents(make, &inner, acc)?).into()
             }
-            Some(())
         }
+        ast::Pat::SlicePat(p) => make
+            .slice_pat(
+                p.pats()
+                    .map(|pat| remove_mut_and_collect_idents(make, &pat, acc))
+                    .collect::<Option<Vec<_>>>()?,
+            )
+            .into(),
+        ast::Pat::TuplePat(p) => make
+            .tuple_pat(
+                p.fields()
+                    .map(|field| remove_mut_and_collect_idents(make, &field, acc))
+                    .collect::<Option<Vec<_>>>()?,
+            )
+            .into(),
+        ast::Pat::TupleStructPat(p) => make
+            .tuple_struct_pat(
+                p.path()?,
+                p.fields()
+                    .map(|field| remove_mut_and_collect_idents(make, &field, acc))
+                    .collect::<Option<Vec<_>>>()?,
+            )
+            .into(),
+        ast::Pat::RestPat(_)
+        | ast::Pat::LiteralPat(_)
+        | ast::Pat::PathPat(_)
+        | ast::Pat::WildcardPat(_)
+        | ast::Pat::ConstBlockPat(_) => pat.clone(),
         // don't support macro pat yet
-        MacroPat(_) => None,
-    }
-}
-
-fn binders_to_str(binders: &[(Name, bool)], addmut: bool) -> String {
-    let vars = binders
-        .iter()
-        .map(
-            |(ident, ismut)| {
-                if *ismut && addmut { format!("mut {ident}") } else { ident.to_string() }
-            },
-        )
-        .collect::<Vec<_>>()
-        .join(", ");
-    if binders.is_empty() {
-        String::from("{}")
-    } else if binders.len() == 1 {
-        vars
-    } else {
-        format!("({vars})")
-    }
+        ast::Pat::MacroPat(_) => return None,
+    })
 }
 
 #[cfg(test)]
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs
index 800ef89ac6e..b8c647ac8b7 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs
@@ -196,7 +196,9 @@ fn destructure_pat(
             let fields = field_names.iter().map(|(old_name, new_name)| {
                 // Use shorthand syntax if possible
                 if old_name == new_name && !is_mut {
-                    make.record_pat_field_shorthand(make.name_ref(old_name))
+                    make.record_pat_field_shorthand(
+                        make.ident_pat(false, false, make.name(old_name)).into(),
+                    )
                 } else {
                     make.record_pat_field(
                         make.name_ref(old_name),
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs
index adf0f0997b3..f09389f8302 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs
@@ -142,7 +142,7 @@ fn collect_data(ident_pat: IdentPat, ctx: &AssistContext<'_>) -> Option<TupleDat
         .map(|(id, ty)| {
             match name_generator.for_type(&ty, ctx.db(), ctx.edition()) {
                 Some(name) => name,
-                None => name_generator.suggest_name(&format!("_{}", id)),
+                None => name_generator.suggest_name(&format!("_{id}")),
             }
             .to_string()
         })
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs
index 4e487e21626..b71de5e00c6 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs
@@ -56,7 +56,12 @@ fn expand_record_rest_pattern(
             let new_field_list = make.record_pat_field_list(old_field_list.fields(), None);
             for (f, _) in missing_fields.iter() {
                 let field = make.record_pat_field_shorthand(
-                    make.name_ref(&f.name(ctx.sema.db).display_no_db(edition).to_smolstr()),
+                    make.ident_pat(
+                        false,
+                        false,
+                        make.name(&f.name(ctx.sema.db).display_no_db(edition).to_smolstr()),
+                    )
+                    .into(),
                 );
                 new_field_list.add_field(field);
             }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
index 046af71a9dc..e977798c4fd 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
@@ -5033,7 +5033,7 @@ fn main() {
     fun_name(bar);
 }
 
-fn $0fun_name(bar: &str) {
+fn $0fun_name(bar: &'static str) {
     m!(bar);
 }
 "#,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs
index 3971b60f253..31e84e9adcf 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs
@@ -631,7 +631,7 @@ fn main() {
 "#,
             r#"
 fn main() {
-    const $0HELLO: &str = "hello";
+    const $0HELLO: &'static str = "hello";
 }
 "#,
             "Extract into constant",
@@ -726,7 +726,7 @@ fn main() {
 "#,
             r#"
 fn main() {
-    static $0HELLO: &str = "hello";
+    static $0HELLO: &'static str = "hello";
 }
 "#,
             "Extract into static",
@@ -2528,13 +2528,13 @@ fn foo() {
         check_assist_by_label(
             extract_variable,
             r#"
-struct Entry(&str);
+struct Entry<'a>(&'a str);
 fn foo() {
     let entry = Entry($0"Hello"$0);
 }
 "#,
             r#"
-struct Entry(&str);
+struct Entry<'a>(&'a str);
 fn foo() {
     let $0hello = "Hello";
     let entry = Entry(hello);
@@ -2546,13 +2546,13 @@ fn foo() {
         check_assist_by_label(
             extract_variable,
             r#"
-struct Entry(&str);
+struct Entry<'a>(&'a str);
 fn foo() {
     let entry = Entry($0"Hello"$0);
 }
 "#,
             r#"
-struct Entry(&str);
+struct Entry<'a>(&'a str);
 fn foo() {
     const $0HELLO: &str = "Hello";
     let entry = Entry(HELLO);
@@ -2564,13 +2564,13 @@ fn foo() {
         check_assist_by_label(
             extract_variable,
             r#"
-struct Entry(&str);
+struct Entry<'a>(&'a str);
 fn foo() {
     let entry = Entry($0"Hello"$0);
 }
 "#,
             r#"
-struct Entry(&str);
+struct Entry<'a>(&'a str);
 fn foo() {
     static $0HELLO: &str = "Hello";
     let entry = Entry(HELLO);
@@ -2587,13 +2587,13 @@ fn foo() {
         check_assist_by_label(
             extract_variable,
             r#"
-struct Entry { message: &str }
+struct Entry<'a> { message: &'a str }
 fn foo() {
     let entry = Entry { message: $0"Hello"$0 };
 }
 "#,
             r#"
-struct Entry { message: &str }
+struct Entry<'a> { message: &'a str }
 fn foo() {
     let $0message = "Hello";
     let entry = Entry { message };
@@ -2605,13 +2605,13 @@ fn foo() {
         check_assist_by_label(
             extract_variable,
             r#"
-struct Entry { message: &str }
+struct Entry<'a> { message: &'a str }
 fn foo() {
     let entry = Entry { message: $0"Hello"$0 };
 }
 "#,
             r#"
-struct Entry { message: &str }
+struct Entry<'a> { message: &'a str }
 fn foo() {
     const $0HELLO: &str = "Hello";
     let entry = Entry { message: HELLO };
@@ -2623,13 +2623,13 @@ fn foo() {
         check_assist_by_label(
             extract_variable,
             r#"
-struct Entry { message: &str }
+struct Entry<'a> { message: &'a str }
 fn foo() {
     let entry = Entry { message: $0"Hello"$0 };
 }
 "#,
             r#"
-struct Entry { message: &str }
+struct Entry<'a> { message: &'a str }
 fn foo() {
     static $0HELLO: &str = "Hello";
     let entry = Entry { message: HELLO };
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
index 824380253ae..30084d23d1f 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
@@ -4,6 +4,7 @@ use hir::{
 };
 use ide_db::{
     FileId, FxHashMap, FxHashSet, RootDatabase, SnippetCap,
+    assists::ExprFillDefaultMode,
     defs::{Definition, NameRefClass},
     famous_defs::FamousDefs,
     helpers::is_editable_crate,
@@ -46,7 +47,7 @@ use crate::{
 //     bar("", baz());
 // }
 //
-// fn bar(arg: &str, baz: Baz) ${0:-> _} {
+// fn bar(arg: &'static str, baz: Baz) ${0:-> _} {
 //     todo!()
 // }
 //
@@ -276,7 +277,11 @@ impl FunctionBuilder {
                 target_module,
                 &mut necessary_generic_params,
             );
-            let placeholder_expr = make::ext::expr_todo();
+            let placeholder_expr = match ctx.config.expr_fill_default {
+                ExprFillDefaultMode::Todo => make::ext::expr_todo(),
+                ExprFillDefaultMode::Underscore => make::ext::expr_underscore(),
+                ExprFillDefaultMode::Default => make::ext::expr_todo(),
+            };
             fn_body = make::block_expr(vec![], Some(placeholder_expr));
         };
 
@@ -331,7 +336,11 @@ impl FunctionBuilder {
         let (generic_param_list, where_clause) =
             fn_generic_params(ctx, necessary_generic_params, &target)?;
 
-        let placeholder_expr = make::ext::expr_todo();
+        let placeholder_expr = match ctx.config.expr_fill_default {
+            ExprFillDefaultMode::Todo => make::ext::expr_todo(),
+            ExprFillDefaultMode::Underscore => make::ext::expr_underscore(),
+            ExprFillDefaultMode::Default => make::ext::expr_todo(),
+        };
         let fn_body = make::block_expr(vec![], Some(placeholder_expr));
 
         Some(Self {
@@ -383,14 +392,14 @@ impl FunctionBuilder {
                 // Focus the return type if there is one
                 match ret_type {
                     Some(ret_type) => {
-                        edit.add_placeholder_snippet(cap, ret_type.clone());
+                        edit.add_placeholder_snippet(cap, ret_type);
                     }
                     None => {
-                        edit.add_placeholder_snippet(cap, tail_expr.clone());
+                        edit.add_placeholder_snippet(cap, tail_expr);
                     }
                 }
             } else {
-                edit.add_placeholder_snippet(cap, tail_expr.clone());
+                edit.add_placeholder_snippet(cap, tail_expr);
             }
         }
 
@@ -444,7 +453,11 @@ fn make_fn_body_as_new_function(
     let adt_info = adt_info.as_ref()?;
 
     let path_self = make::ext::ident_path("Self");
-    let placeholder_expr = make::ext::expr_todo();
+    let placeholder_expr = match ctx.config.expr_fill_default {
+        ExprFillDefaultMode::Todo => make::ext::expr_todo(),
+        ExprFillDefaultMode::Underscore => make::ext::expr_underscore(),
+        ExprFillDefaultMode::Default => make::ext::expr_todo(),
+    };
     let tail_expr = if let Some(strukt) = adt_info.adt.as_struct() {
         match strukt.kind(ctx.db()) {
             StructKind::Record => {
@@ -1505,7 +1518,7 @@ fn foo() {
     bar("bar")
 }
 
-fn bar(arg: &str) {
+fn bar(arg: &'static str) {
     ${0:todo!()}
 }
 "#,
@@ -2122,7 +2135,7 @@ fn foo() {
     bar(baz(), baz(), "foo", "bar")
 }
 
-fn bar(baz_1: Baz, baz_2: Baz, arg_1: &str, arg_2: &str) {
+fn bar(baz_1: Baz, baz_2: Baz, arg_1: &'static str, arg_2: &'static str) {
     ${0:todo!()}
 }
 "#,
@@ -3090,7 +3103,7 @@ pub struct Foo {
     field_2: String,
 }
 impl Foo {
-    fn new(baz_1: Baz, baz_2: Baz, arg_1: &str, arg_2: &str) -> Self {
+    fn new(baz_1: Baz, baz_2: Baz, arg_1: &'static str, arg_2: &'static str) -> Self {
         ${0:Self { field_1: todo!(), field_2: todo!() }}
     }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs
index b7f7cb9cb01..6bf7f584914 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs
@@ -1,14 +1,14 @@
 use either::Either;
 use ide_db::imports::{
     insert_use::{ImportGranularity, InsertUseConfig},
-    merge_imports::{MergeBehavior, try_merge_imports, try_merge_trees, try_normalize_use_tree},
+    merge_imports::{MergeBehavior, try_merge_imports, try_merge_trees},
 };
-use itertools::Itertools;
 use syntax::{
     AstNode, SyntaxElement, SyntaxNode,
     algo::neighbor,
-    ast::{self, edit_in_place::Removable},
-    match_ast, ted,
+    ast::{self, syntax_factory::SyntaxFactory},
+    match_ast,
+    syntax_editor::Removable,
 };
 
 use crate::{
@@ -69,49 +69,32 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio
         (selection_range, edits?)
     };
 
+    let parent_node = match ctx.covering_element() {
+        SyntaxElement::Node(n) => n,
+        SyntaxElement::Token(t) => t.parent()?,
+    };
+
     acc.add(AssistId::refactor_rewrite("merge_imports"), "Merge imports", target, |builder| {
-        let edits_mut: Vec<Edit> = edits
-            .into_iter()
-            .map(|it| match it {
-                Remove(Either::Left(it)) => Remove(Either::Left(builder.make_mut(it))),
-                Remove(Either::Right(it)) => Remove(Either::Right(builder.make_mut(it))),
-                Replace(old, new) => Replace(builder.make_syntax_mut(old), new),
-            })
-            .collect();
-        for edit in edits_mut {
+        let make = SyntaxFactory::with_mappings();
+        let mut editor = builder.make_editor(&parent_node);
+
+        for edit in edits {
             match edit {
-                Remove(it) => it.as_ref().either(Removable::remove, Removable::remove),
-                Replace(old, new) => {
-                    ted::replace(old, &new);
-
-                    // If there's a selection and we're replacing a use tree in a tree list,
-                    // normalize the parent use tree if it only contains the merged subtree.
-                    if !ctx.has_empty_selection() {
-                        let normalized_use_tree = ast::UseTree::cast(new)
-                            .as_ref()
-                            .and_then(ast::UseTree::parent_use_tree_list)
-                            .and_then(|use_tree_list| {
-                                if use_tree_list.use_trees().collect_tuple::<(_,)>().is_some() {
-                                    Some(use_tree_list.parent_use_tree())
-                                } else {
-                                    None
-                                }
-                            })
-                            .and_then(|target_tree| {
-                                try_normalize_use_tree(
-                                    &target_tree,
-                                    ctx.config.insert_use.granularity.into(),
-                                )
-                                .map(|top_use_tree_flat| (target_tree, top_use_tree_flat))
-                            });
-                        if let Some((old_tree, new_tree)) = normalized_use_tree {
-                            cov_mark::hit!(replace_parent_with_normalized_use_tree);
-                            ted::replace(old_tree.syntax(), new_tree.syntax());
-                        }
+                Remove(it) => {
+                    let node = it.as_ref();
+                    if let Some(left) = node.left() {
+                        left.remove(&mut editor);
+                    } else if let Some(right) = node.right() {
+                        right.remove(&mut editor);
                     }
                 }
+                Replace(old, new) => {
+                    editor.replace(old, &new);
+                }
             }
         }
+        editor.add_mappings(make.finish_with_mappings());
+        builder.add_file_edits(ctx.vfs_file_id(), editor);
     })
 }
 
@@ -723,11 +706,10 @@ use std::{
         );
 
         cov_mark::check!(merge_with_selected_use_tree_neighbors);
-        cov_mark::check!(replace_parent_with_normalized_use_tree);
         check_assist(
             merge_imports,
             r"use std::$0{fmt::Display, fmt::Debug}$0;",
-            r"use std::fmt::{Debug, Display};",
+            r"use std::{fmt::{Debug, Display}};",
         );
     }
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
index 6dcdf5edbd6..806c8fba9ea 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -9,7 +9,7 @@ use syntax::{
 };
 
 use crate::{
-    AssistId,
+    AssistConfig, AssistId,
     assist_context::{AssistContext, Assists, SourceChangeBuilder},
     utils::{
         DefaultMethods, IgnoreAssocItems, add_trait_assoc_items_to_impl, filter_assoc_items,
@@ -128,8 +128,14 @@ fn add_assist(
     acc.add(AssistId::refactor("replace_derive_with_manual_impl"), label, target, |builder| {
         let insert_after = ted::Position::after(builder.make_mut(adt.clone()).syntax());
         let impl_is_unsafe = trait_.map(|s| s.is_unsafe(ctx.db())).unwrap_or(false);
-        let impl_def_with_items =
-            impl_def_from_trait(&ctx.sema, adt, &annotated_name, trait_, replace_trait_path);
+        let impl_def_with_items = impl_def_from_trait(
+            &ctx.sema,
+            ctx.config,
+            adt,
+            &annotated_name,
+            trait_,
+            replace_trait_path,
+        );
         update_attribute(builder, old_derives, old_tree, old_trait_path, attr);
 
         let trait_path = make::ty_path(replace_trait_path.clone());
@@ -217,6 +223,7 @@ fn add_assist(
 
 fn impl_def_from_trait(
     sema: &hir::Semantics<'_, ide_db::RootDatabase>,
+    config: &AssistConfig,
     adt: &ast::Adt,
     annotated_name: &ast::Name,
     trait_: Option<hir::Trait>,
@@ -241,7 +248,7 @@ fn impl_def_from_trait(
     let impl_def = generate_trait_impl(adt, make::ty_path(trait_path.clone()));
 
     let first_assoc_item =
-        add_trait_assoc_items_to_impl(sema, &trait_items, trait_, &impl_def, &target_scope);
+        add_trait_assoc_items_to_impl(sema, config, &trait_items, trait_, &impl_def, &target_scope);
 
     // Generate a default `impl` function body for the derived trait.
     if let ast::AssocItem::Fn(ref func) = first_assoc_item {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_use.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_imports.rs
index 805a7344494..c066f41ca47 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_use.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_imports.rs
@@ -1,7 +1,10 @@
 use syntax::{
     AstNode, SyntaxKind,
-    ast::{self, HasVisibility, edit_in_place::Removable, make},
-    ted::{self, Position},
+    ast::{
+        self, HasAttrs, HasVisibility, edit::IndentLevel, edit_in_place::AttrsOwnerEdit, make,
+        syntax_factory::SyntaxFactory,
+    },
+    syntax_editor::{Element, Position, Removable},
 };
 
 use crate::{
@@ -9,9 +12,9 @@ use crate::{
     assist_context::{AssistContext, Assists},
 };
 
-// Assist: unmerge_use
+// Assist: unmerge_imports
 //
-// Extracts single use item from use list.
+// Extracts a use item from a use list into a standalone use list.
 //
 // ```
 // use std::fmt::{Debug, Display$0};
@@ -21,21 +24,18 @@ use crate::{
 // use std::fmt::{Debug};
 // use std::fmt::Display;
 // ```
-pub(crate) fn unmerge_use(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
-    let tree: ast::UseTree = ctx.find_node_at_offset::<ast::UseTree>()?.clone_for_update();
+pub(crate) fn unmerge_imports(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
+    let tree = ctx.find_node_at_offset::<ast::UseTree>()?;
 
     let tree_list = tree.syntax().parent().and_then(ast::UseTreeList::cast)?;
     if tree_list.use_trees().count() < 2 {
-        cov_mark::hit!(skip_single_use_item);
+        cov_mark::hit!(skip_single_import);
         return None;
     }
 
-    let use_: ast::Use = tree_list.syntax().ancestors().find_map(ast::Use::cast)?;
+    let use_ = tree_list.syntax().ancestors().find_map(ast::Use::cast)?;
     let path = resolve_full_path(&tree)?;
 
-    let old_parent_range = use_.syntax().parent()?.text_range();
-    let new_parent = use_.syntax().parent()?;
-
     // If possible, explain what is going to be done.
     let label = match tree.path().and_then(|path| path.first_segment()) {
         Some(name) => format!("Unmerge use of `{name}`"),
@@ -43,17 +43,31 @@ pub(crate) fn unmerge_use(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
     };
 
     let target = tree.syntax().text_range();
-    acc.add(AssistId::refactor_rewrite("unmerge_use"), label, target, |builder| {
-        let new_use = make::use_(
+    acc.add(AssistId::refactor_rewrite("unmerge_imports"), label, target, |builder| {
+        let make = SyntaxFactory::with_mappings();
+        let new_use = make.use_(
             use_.visibility(),
-            make::use_tree(path, tree.use_tree_list(), tree.rename(), tree.star_token().is_some()),
-        )
-        .clone_for_update();
-
-        tree.remove();
-        ted::insert(Position::after(use_.syntax()), new_use.syntax());
+            make.use_tree(path, tree.use_tree_list(), tree.rename(), tree.star_token().is_some()),
+        );
+        // Add any attributes that are present on the use tree
+        use_.attrs().for_each(|attr| {
+            new_use.add_attr(attr.clone_for_update());
+        });
 
-        builder.replace(old_parent_range, new_parent.to_string());
+        let mut editor = builder.make_editor(use_.syntax());
+        // Remove the use tree from the current use item
+        tree.remove(&mut editor);
+        // Insert a newline and indentation, followed by the new use item
+        editor.insert_all(
+            Position::after(use_.syntax()),
+            vec![
+                make.whitespace(&format!("\n{}", IndentLevel::from_node(use_.syntax())))
+                    .syntax_element(),
+                new_use.syntax().syntax_element(),
+            ],
+        );
+        editor.add_mappings(make.finish_with_mappings());
+        builder.add_file_edits(ctx.vfs_file_id(), editor);
     })
 }
 
@@ -80,22 +94,22 @@ mod tests {
     use super::*;
 
     #[test]
-    fn skip_single_use_item() {
-        cov_mark::check!(skip_single_use_item);
+    fn skip_single_import() {
+        cov_mark::check!(skip_single_import);
         check_assist_not_applicable(
-            unmerge_use,
+            unmerge_imports,
             r"
 use std::fmt::Debug$0;
 ",
         );
         check_assist_not_applicable(
-            unmerge_use,
+            unmerge_imports,
             r"
 use std::fmt::{Debug$0};
 ",
         );
         check_assist_not_applicable(
-            unmerge_use,
+            unmerge_imports,
             r"
 use std::fmt::Debug as Dbg$0;
 ",
@@ -105,7 +119,7 @@ use std::fmt::Debug as Dbg$0;
     #[test]
     fn skip_single_glob_import() {
         check_assist_not_applicable(
-            unmerge_use,
+            unmerge_imports,
             r"
 use std::fmt::*$0;
 ",
@@ -113,9 +127,9 @@ use std::fmt::*$0;
     }
 
     #[test]
-    fn unmerge_use_item() {
+    fn unmerge_import() {
         check_assist(
-            unmerge_use,
+            unmerge_imports,
             r"
 use std::fmt::{Debug, Display$0};
 ",
@@ -126,7 +140,7 @@ use std::fmt::Display;
         );
 
         check_assist(
-            unmerge_use,
+            unmerge_imports,
             r"
 use std::fmt::{Debug, format$0, Display};
 ",
@@ -140,7 +154,7 @@ use std::fmt::format;
     #[test]
     fn unmerge_glob_import() {
         check_assist(
-            unmerge_use,
+            unmerge_imports,
             r"
 use std::fmt::{*$0, Display};
 ",
@@ -152,9 +166,9 @@ use std::fmt::*;
     }
 
     #[test]
-    fn unmerge_renamed_use_item() {
+    fn unmerge_renamed_import() {
         check_assist(
-            unmerge_use,
+            unmerge_imports,
             r"
 use std::fmt::{Debug, Display as Disp$0};
 ",
@@ -166,9 +180,9 @@ use std::fmt::Display as Disp;
     }
 
     #[test]
-    fn unmerge_indented_use_item() {
+    fn unmerge_indented_import() {
         check_assist(
-            unmerge_use,
+            unmerge_imports,
             r"
 mod format {
     use std::fmt::{Debug, Display$0 as Disp, format};
@@ -184,9 +198,9 @@ mod format {
     }
 
     #[test]
-    fn unmerge_nested_use_item() {
+    fn unmerge_nested_import() {
         check_assist(
-            unmerge_use,
+            unmerge_imports,
             r"
 use foo::bar::{baz::{qux$0, foobar}, barbaz};
 ",
@@ -196,7 +210,7 @@ use foo::bar::baz::qux;
 ",
         );
         check_assist(
-            unmerge_use,
+            unmerge_imports,
             r"
 use foo::bar::{baz$0::{qux, foobar}, barbaz};
 ",
@@ -208,9 +222,9 @@ use foo::bar::baz::{qux, foobar};
     }
 
     #[test]
-    fn unmerge_use_item_with_visibility() {
+    fn unmerge_import_with_visibility() {
         check_assist(
-            unmerge_use,
+            unmerge_imports,
             r"
 pub use std::fmt::{Debug, Display$0};
 ",
@@ -222,12 +236,27 @@ pub use std::fmt::Display;
     }
 
     #[test]
-    fn unmerge_use_item_on_self() {
+    fn unmerge_import_on_self() {
         check_assist(
-            unmerge_use,
+            unmerge_imports,
             r"use std::process::{Command, self$0};",
             r"use std::process::{Command};
 use std::process;",
         );
     }
+
+    #[test]
+    fn unmerge_import_with_attributes() {
+        check_assist(
+            unmerge_imports,
+            r"
+#[allow(deprecated)]
+use foo::{bar, baz$0};",
+            r"
+#[allow(deprecated)]
+use foo::{bar};
+#[allow(deprecated)]
+use foo::baz;",
+        );
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs
index 31ff47a0549..5aedff5cc77 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unmerge_match_arm.rs
@@ -53,8 +53,14 @@ pub(crate) fn unmerge_match_arm(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
         |edit| {
             let pats_after = pipe_token
                 .siblings_with_tokens(Direction::Next)
-                .filter_map(|it| ast::Pat::cast(it.into_node()?));
-            let new_pat = make::or_pat(pats_after, or_pat.leading_pipe().is_some());
+                .filter_map(|it| ast::Pat::cast(it.into_node()?))
+                .collect::<Vec<_>>();
+            // It is guaranteed that `pats_after` has at least one element
+            let new_pat = if pats_after.len() == 1 {
+                pats_after[0].clone()
+            } else {
+                make::or_pat(pats_after, or_pat.leading_pipe().is_some()).into()
+            };
             let new_match_arm =
                 make::match_arm(new_pat, match_arm.guard(), match_arm_body).clone_for_update();
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs
index 1068d5d4cd5..e1b94673e77 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs
@@ -116,7 +116,7 @@ pub(crate) fn wrap_unwrap_cfg_attr(acc: &mut Assists, ctx: &AssistContext<'_>) -
             (Some(attr), Some(ident))
                 if attr.simple_name().map(|v| v.eq("derive")).unwrap_or_default() =>
             {
-                Some(attempt_get_derive(attr.clone(), ident))
+                Some(attempt_get_derive(attr, ident))
             }
 
             (Some(attr), _) => Some(WrapUnwrapOption::WrapAttr(attr)),
@@ -128,7 +128,7 @@ pub(crate) fn wrap_unwrap_cfg_attr(acc: &mut Assists, ctx: &AssistContext<'_>) -
             NodeOrToken::Node(node) => ast::Attr::cast(node).map(WrapUnwrapOption::WrapAttr),
             NodeOrToken::Token(ident) if ident.kind() == syntax::T![ident] => {
                 let attr = ident.parent_ancestors().find_map(ast::Attr::cast)?;
-                Some(attempt_get_derive(attr.clone(), ident))
+                Some(attempt_get_derive(attr, ident))
             }
             _ => None,
         }
@@ -233,7 +233,7 @@ fn wrap_cfg_attr(acc: &mut Assists, ctx: &AssistContext<'_>, attr: ast::Attr) ->
         if let Some(meta) = attr.meta() {
             if let (Some(eq), Some(expr)) = (meta.eq_token(), meta.expr()) {
                 raw_tokens.push(NodeOrToken::Token(make::tokens::whitespace(" ")));
-                raw_tokens.push(NodeOrToken::Token(eq.clone()));
+                raw_tokens.push(NodeOrToken::Token(eq));
                 raw_tokens.push(NodeOrToken::Token(make::tokens::whitespace(" ")));
 
                 expr.syntax().descendants_with_tokens().for_each(|it| {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs
index a157483a449..627ed37b04e 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs
@@ -222,8 +222,8 @@ mod handlers {
     mod toggle_async_sugar;
     mod toggle_ignore;
     mod toggle_macro_delimiter;
+    mod unmerge_imports;
     mod unmerge_match_arm;
-    mod unmerge_use;
     mod unnecessary_async;
     mod unqualify_method_call;
     mod unwrap_block;
@@ -363,7 +363,7 @@ mod handlers {
             toggle_ignore::toggle_ignore,
             toggle_macro_delimiter::toggle_macro_delimiter,
             unmerge_match_arm::unmerge_match_arm,
-            unmerge_use::unmerge_use,
+            unmerge_imports::unmerge_imports,
             unnecessary_async::unnecessary_async,
             unqualify_method_call::unqualify_method_call,
             unwrap_block::unwrap_block,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs
index 0593e6930dc..5e6889792db 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs
@@ -4,6 +4,7 @@ use expect_test::expect;
 use hir::Semantics;
 use ide_db::{
     EditionedFileId, FileRange, RootDatabase, SnippetCap,
+    assists::ExprFillDefaultMode,
     base_db::SourceDatabase,
     imports::insert_use::{ImportGranularity, InsertUseConfig},
     source_change::FileSystemEdit,
@@ -35,6 +36,7 @@ pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig {
     term_search_fuel: 400,
     term_search_borrowck: true,
     code_action_grouping: true,
+    expr_fill_default: ExprFillDefaultMode::Todo,
 };
 
 pub(crate) const TEST_CONFIG_NO_GROUPING: AssistConfig = AssistConfig {
@@ -54,6 +56,7 @@ pub(crate) const TEST_CONFIG_NO_GROUPING: AssistConfig = AssistConfig {
     term_search_fuel: 400,
     term_search_borrowck: true,
     code_action_grouping: false,
+    expr_fill_default: ExprFillDefaultMode::Todo,
 };
 
 pub(crate) const TEST_CONFIG_NO_SNIPPET_CAP: AssistConfig = AssistConfig {
@@ -73,6 +76,7 @@ pub(crate) const TEST_CONFIG_NO_SNIPPET_CAP: AssistConfig = AssistConfig {
     term_search_fuel: 400,
     term_search_borrowck: true,
     code_action_grouping: true,
+    expr_fill_default: ExprFillDefaultMode::Todo,
 };
 
 pub(crate) const TEST_CONFIG_IMPORT_ONE: AssistConfig = AssistConfig {
@@ -92,6 +96,7 @@ pub(crate) const TEST_CONFIG_IMPORT_ONE: AssistConfig = AssistConfig {
     term_search_fuel: 400,
     term_search_borrowck: true,
     code_action_grouping: true,
+    expr_fill_default: ExprFillDefaultMode::Todo,
 };
 
 pub(crate) fn with_single_file(text: &str) -> (RootDatabase, EditionedFileId) {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
index 00a9d35c310..01ab0be34b2 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
@@ -1737,7 +1737,7 @@ fn foo() {
     bar("", baz());
 }
 
-fn bar(arg: &str, baz: Baz) ${0:-> _} {
+fn bar(arg: &'static str, baz: Baz) ${0:-> _} {
     todo!()
 }
 
@@ -3340,6 +3340,20 @@ sth!{ }
 }
 
 #[test]
+fn doctest_unmerge_imports() {
+    check_doc_test(
+        "unmerge_imports",
+        r#####"
+use std::fmt::{Debug, Display$0};
+"#####,
+        r#####"
+use std::fmt::{Debug};
+use std::fmt::Display;
+"#####,
+    )
+}
+
+#[test]
 fn doctest_unmerge_match_arm() {
     check_doc_test(
         "unmerge_match_arm",
@@ -3366,20 +3380,6 @@ fn handle(action: Action) {
 }
 
 #[test]
-fn doctest_unmerge_use() {
-    check_doc_test(
-        "unmerge_use",
-        r#####"
-use std::fmt::{Debug, Display$0};
-"#####,
-        r#####"
-use std::fmt::{Debug};
-use std::fmt::Display;
-"#####,
-    )
-}
-
-#[test]
 fn doctest_unnecessary_async() {
     check_doc_test(
         "unnecessary_async",
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
index 0471998f0b1..ef6914fda1d 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
@@ -8,6 +8,7 @@ use hir::{
 };
 use ide_db::{
     RootDatabase,
+    assists::ExprFillDefaultMode,
     famous_defs::FamousDefs,
     path_transform::PathTransform,
     syntax_helpers::{node_ext::preorder_expr, prettify_macro_expansion},
@@ -27,7 +28,10 @@ use syntax::{
     ted,
 };
 
-use crate::assist_context::{AssistContext, SourceChangeBuilder};
+use crate::{
+    AssistConfig,
+    assist_context::{AssistContext, SourceChangeBuilder},
+};
 
 mod gen_trait_fn_body;
 pub(crate) mod ref_field_expr;
@@ -174,6 +178,7 @@ pub fn filter_assoc_items(
 /// inserted.
 pub fn add_trait_assoc_items_to_impl(
     sema: &Semantics<'_, RootDatabase>,
+    config: &AssistConfig,
     original_items: &[InFile<ast::AssocItem>],
     trait_: hir::Trait,
     impl_: &ast::Impl,
@@ -219,7 +224,14 @@ pub fn add_trait_assoc_items_to_impl(
         match &item {
             ast::AssocItem::Fn(fn_) if fn_.body().is_none() => {
                 let body = AstNodeEdit::indent(
-                    &make::block_expr(None, Some(make::ext::expr_todo())),
+                    &make::block_expr(
+                        None,
+                        Some(match config.expr_fill_default {
+                            ExprFillDefaultMode::Todo => make::ext::expr_todo(),
+                            ExprFillDefaultMode::Underscore => make::ext::expr_underscore(),
+                            ExprFillDefaultMode::Default => make::ext::expr_todo(),
+                        }),
+                    ),
                     new_indent_level,
                 );
                 ted::replace(fn_.get_or_create_body().syntax(), body.clone_for_update().syntax())
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs
index ee1a21f9a1a..7fbd1fbc1af 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs
@@ -363,9 +363,14 @@ pub(crate) fn complete_expr_path(
                     add_keyword("true", "true");
                     add_keyword("false", "false");
 
-                    if in_condition || in_block_expr {
-                        add_keyword("letm", "let mut $0");
-                        add_keyword("let", "let $0");
+                    if in_condition {
+                        add_keyword("letm", "let mut $1 = $0");
+                        add_keyword("let", "let $1 = $0");
+                    }
+
+                    if in_block_expr {
+                        add_keyword("letm", "let mut $1 = $0;");
+                        add_keyword("let", "let $1 = $0;");
                     }
 
                     if after_if_expr {
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs
index 039742463c8..64bb1fce6ba 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/keyword.rs
@@ -336,7 +336,7 @@ fn main() {
     }
 
     #[test]
-    fn completes_let_with_space() {
+    fn completes_let_in_block() {
         check_edit(
             "let",
             r#"
@@ -346,7 +346,7 @@ fn main() {
 "#,
             r#"
 fn main() {
-    let $0
+    let $1 = $0;
 }
 "#,
         );
@@ -359,7 +359,97 @@ fn main() {
 "#,
             r#"
 fn main() {
-    let mut $0
+    let mut $1 = $0;
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn completes_let_in_condition() {
+        check_edit(
+            "let",
+            r#"
+fn main() {
+    if $0 {}
+}
+"#,
+            r#"
+fn main() {
+    if let $1 = $0 {}
+}
+"#,
+        );
+        check_edit(
+            "letm",
+            r#"
+fn main() {
+    if $0 {}
+}
+"#,
+            r#"
+fn main() {
+    if let mut $1 = $0 {}
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn completes_let_in_no_empty_condition() {
+        check_edit(
+            "let",
+            r#"
+fn main() {
+    if $0x {}
+}
+"#,
+            r#"
+fn main() {
+    if let $1 = $0x {}
+}
+"#,
+        );
+        check_edit(
+            "letm",
+            r#"
+fn main() {
+    if $0x {}
+}
+"#,
+            r#"
+fn main() {
+    if let mut $1 = $0x {}
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn completes_let_in_condition_block() {
+        check_edit(
+            "let",
+            r#"
+fn main() {
+    if { $0 } {}
+}
+"#,
+            r#"
+fn main() {
+    if { let $1 = $0; } {}
+}
+"#,
+        );
+        check_edit(
+            "letm",
+            r#"
+fn main() {
+    if { $0 } {}
+}
+"#,
+            r#"
+fn main() {
+    if { let mut $1 = $0; } {}
 }
 "#,
         );
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs
index b02f079b721..8902cd09cec 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs
@@ -116,13 +116,13 @@ fn foo<'lifetime>(foo: &'a$0) {}
         check(
             r#"
 struct Foo;
-impl<'impl> Foo {
+impl<'r#impl> Foo {
     fn foo<'func>(&'a$0 self) {}
 }
 "#,
             expect![[r#"
                 lt 'func
-                lt 'impl
+                lt 'r#impl
                 lt 'static
             "#]],
         );
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
index 59599735896..391e2379dcd 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
@@ -387,11 +387,7 @@ fn expand(
 
     match (
         sema.expand_macro_call(&actual_macro_call),
-        sema.speculative_expand_macro_call(
-            &actual_macro_call,
-            &speculative_args,
-            fake_ident_token.clone(),
-        ),
+        sema.speculative_expand_macro_call(&actual_macro_call, &speculative_args, fake_ident_token),
     ) {
         // successful expansions
         (Some(actual_expansion), Some((fake_expansion, fake_mapped_tokens))) => {
@@ -661,9 +657,8 @@ fn expected_type_and_name(
                             ))
                         } else {
                             cov_mark::hit!(expected_type_struct_field_without_leading_char);
-                            let expr_field = token.prev_sibling_or_token()?
-                                .into_node()
-                                .and_then(ast::RecordExprField::cast)?;
+                            cov_mark::hit!(expected_type_struct_field_followed_by_comma);
+                            let expr_field = previous_non_trivia_token(token.clone())?.parent().and_then(ast::RecordExprField::cast)?;
                             let (_, _, ty) = sema.resolve_record_field(&expr_field)?;
                             Some((
                                 Some(ty),
@@ -681,7 +676,6 @@ fn expected_type_and_name(
                             .or_else(|| sema.type_of_expr(&expr).map(TypeInfo::original));
                         (ty, field_name)
                     } else {
-                        cov_mark::hit!(expected_type_struct_field_followed_by_comma);
                         (field_ty, field_name)
                     }
                 },
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs
index e208b9fd41a..19cdef30bd9 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs
@@ -135,7 +135,7 @@ impl fmt::Debug for CompletionItem {
                 },
                 CompletionItemRefMode::Dereference => "*",
             };
-            s.field("ref_match", &format!("{}@{offset:?}", prefix));
+            s.field("ref_match", &format!("{prefix}@{offset:?}"));
         }
         if self.trigger_call_info {
             s.field("trigger_call_info", &true);
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs
index b30ac43bf8f..d5137949d42 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs
@@ -1517,7 +1517,7 @@ fn main() {
             en Enum                      Enum
             fn function()                fn()
             fn main()                    fn()
-            lc variable                  &str
+            lc variable          &'static str
             ma helper!(…) macro_rules! helper
             ma m!(…)           macro_rules! m
             ma makro!(…)   macro_rules! makro
@@ -2110,3 +2110,19 @@ fn foo() {
         "#]],
     );
 }
+
+#[test]
+fn escaped_label() {
+    check(
+        r#"
+fn main() {
+    'r#break: {
+        break '$0;
+    }
+}
+    "#,
+        expect![[r#"
+            lb 'r#break
+        "#]],
+    );
+}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs
index 15518e98370..148203107c4 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs
@@ -1358,7 +1358,7 @@ pub fn foo<'x, T>(x: &'x mut T) -> u8 where T: Clone, { 0u8 }
 fn main() { fo$0 }
 "#,
         CompletionItemKind::SymbolKind(ide_db::SymbolKind::Function),
-        expect!("fn(&mut T) -> u8"),
+        expect!("fn(&'x mut T) -> u8"),
         expect!("pub fn foo<'x, T>(x: &'x mut T) -> u8 where T: Clone,"),
     );
 
@@ -1391,7 +1391,7 @@ fn main() {
 }
 "#,
         CompletionItemKind::SymbolKind(SymbolKind::Method),
-        expect!("const fn(&'foo mut self, &Foo) -> !"),
+        expect!("const fn(&'foo mut self, &'foo Foo) -> !"),
         expect!("pub const fn baz<'foo>(&'foo mut self, x: &'foo Foo) -> !"),
     );
 }
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs
index c7e2d058257..125e11e9e35 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs
@@ -429,18 +429,18 @@ trait Tr<T> {
 impl Tr<$0
     "#,
         expect![[r#"
-            en Enum                    Enum
-            ma makro!(…) macro_rules! makro
+            en Enum                        Enum
+            ma makro!(…)     macro_rules! makro
             md module
-            sp Self       dyn Tr<{unknown}>
-            st Record                Record
-            st S                          S
-            st Tuple                  Tuple
-            st Unit                    Unit
+            sp Self dyn Tr<{unknown}> + 'static
+            st Record                    Record
+            st S                              S
+            st Tuple                      Tuple
+            st Unit                        Unit
             tt Tr
             tt Trait
-            un Union                  Union
-            bt u32                      u32
+            un Union                      Union
+            bt u32                          u32
             kw crate::
             kw self::
         "#]],
diff --git a/src/tools/rust-analyzer/crates/ide-db/Cargo.toml b/src/tools/rust-analyzer/crates/ide-db/Cargo.toml
index f1d6b605b00..583318de26d 100644
--- a/src/tools/rust-analyzer/crates/ide-db/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/ide-db/Cargo.toml
@@ -24,6 +24,7 @@ arrayvec.workspace = true
 indexmap.workspace = true
 memchr = "2.7.4"
 salsa.workspace = true
+salsa-macros.workspace = true
 query-group.workspace = true
 triomphe.workspace = true
 nohash-hasher.workspace = true
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/assists.rs b/src/tools/rust-analyzer/crates/ide-db/src/assists.rs
index 90ae4a3b5b3..384eb57c0fd 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/assists.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/assists.rs
@@ -169,3 +169,15 @@ impl AssistResolveStrategy {
 
 #[derive(Clone, Debug)]
 pub struct GroupLabel(pub String);
+
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub enum ExprFillDefaultMode {
+    Todo,
+    Default,
+    Underscore,
+}
+impl Default for ExprFillDefaultMode {
+    fn default() -> Self {
+        Self::Todo
+    }
+}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs b/src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs
index e9385253250..4b0a84a559e 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs
@@ -86,7 +86,7 @@ pub fn items_with_name_in_module<T>(
     let local_query = match name {
         NameToImport::Prefix(exact_name, case_sensitive)
         | NameToImport::Exact(exact_name, case_sensitive) => {
-            let mut local_query = symbol_index::Query::new(exact_name.clone());
+            let mut local_query = symbol_index::Query::new(exact_name);
             local_query.assoc_search_mode(assoc_item_search);
             if prefix {
                 local_query.prefix();
@@ -99,7 +99,7 @@ pub fn items_with_name_in_module<T>(
             local_query
         }
         NameToImport::Fuzzy(fuzzy_search_string, case_sensitive) => {
-            let mut local_query = symbol_index::Query::new(fuzzy_search_string.clone());
+            let mut local_query = symbol_index::Query::new(fuzzy_search_string);
             local_query.fuzzy();
             local_query.assoc_search_mode(assoc_item_search);
 
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
index d3934e14abf..63cc7cde280 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
@@ -76,8 +76,10 @@ pub type FxIndexMap<K, V> =
 pub type FilePosition = FilePositionWrapper<FileId>;
 pub type FileRange = FileRangeWrapper<FileId>;
 
-#[salsa::db]
+#[salsa_macros::db]
 pub struct RootDatabase {
+    // FIXME: Revisit this commit now that we migrated to the new salsa, given we store arcs in this
+    // db directly now
     // We use `ManuallyDrop` here because every codegen unit that contains a
     // `&RootDatabase -> &dyn OtherDatabase` cast will instantiate its drop glue in the vtable,
     // which duplicates `Weak::drop` and `Arc::drop` tens of thousands of times, which makes
@@ -89,7 +91,7 @@ pub struct RootDatabase {
 
 impl std::panic::RefUnwindSafe for RootDatabase {}
 
-#[salsa::db]
+#[salsa_macros::db]
 impl salsa::Database for RootDatabase {
     fn salsa_event(&self, _event: &dyn Fn() -> salsa::Event) {}
 }
@@ -116,7 +118,7 @@ impl fmt::Debug for RootDatabase {
     }
 }
 
-#[salsa::db]
+#[salsa_macros::db]
 impl SourceDatabase for RootDatabase {
     fn file_text(&self, file_id: vfs::FileId) -> FileText {
         self.files.file_text(file_id)
@@ -234,14 +236,6 @@ impl RootDatabase {
         // );
         // hir::db::BodyWithSourceMapQuery.in_db_mut(self).set_lru_capacity(2048);
     }
-
-    pub fn snapshot(&self) -> Self {
-        Self {
-            storage: self.storage.clone(),
-            files: self.files.clone(),
-            crates_map: self.crates_map.clone(),
-        }
-    }
 }
 
 #[query_group::query_group]
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs
index 17c3f75ce17..cbe31405ab7 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs
@@ -51,6 +51,7 @@ pub fn parallel_prime_caches(
     enum ParallelPrimeCacheWorkerProgress {
         BeginCrate { crate_id: Crate, crate_name: Symbol },
         EndCrate { crate_id: Crate },
+        Cancelled(Cancelled),
     }
 
     // We split off def map computation from other work,
@@ -71,27 +72,35 @@ pub fn parallel_prime_caches(
                 progress_sender
                     .send(ParallelPrimeCacheWorkerProgress::BeginCrate { crate_id, crate_name })?;
 
-                match kind {
+                let cancelled = Cancelled::catch(|| match kind {
                     PrimingPhase::DefMap => _ = db.crate_def_map(crate_id),
                     PrimingPhase::ImportMap => _ = db.import_map(crate_id),
                     PrimingPhase::CrateSymbols => _ = db.crate_symbols(crate_id.into()),
-                }
+                });
 
-                progress_sender.send(ParallelPrimeCacheWorkerProgress::EndCrate { crate_id })?;
+                match cancelled {
+                    Ok(()) => progress_sender
+                        .send(ParallelPrimeCacheWorkerProgress::EndCrate { crate_id })?,
+                    Err(cancelled) => progress_sender
+                        .send(ParallelPrimeCacheWorkerProgress::Cancelled(cancelled))?,
+                }
             }
 
             Ok::<_, crossbeam_channel::SendError<_>>(())
         };
 
         for id in 0..num_worker_threads {
-            let worker = prime_caches_worker.clone();
-            let db = db.snapshot();
-
-            stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker)
-                .allow_leak(true)
-                .name(format!("PrimeCaches#{id}"))
-                .spawn(move || Cancelled::catch(|| worker(db.snapshot())))
-                .expect("failed to spawn thread");
+            stdx::thread::Builder::new(
+                stdx::thread::ThreadIntent::Worker,
+                format!("PrimeCaches#{id}"),
+            )
+            .allow_leak(true)
+            .spawn({
+                let worker = prime_caches_worker.clone();
+                let db = db.clone();
+                move || worker(db)
+            })
+            .expect("failed to spawn thread");
         }
 
         (work_sender, progress_receiver)
@@ -142,9 +151,14 @@ pub fn parallel_prime_caches(
                 continue;
             }
             Err(crossbeam_channel::RecvTimeoutError::Disconnected) => {
-                // our workers may have died from a cancelled task, so we'll check and re-raise here.
-                db.unwind_if_revision_cancelled();
-                break;
+                // all our workers have exited, mark us as finished and exit
+                cb(ParallelPrimeCachesProgress {
+                    crates_currently_indexing: vec![],
+                    crates_done,
+                    crates_total: crates_done,
+                    work_type: "Indexing",
+                });
+                return;
             }
         };
         match worker_progress {
@@ -156,6 +170,10 @@ pub fn parallel_prime_caches(
                 crates_to_prime.mark_done(crate_id);
                 crates_done += 1;
             }
+            ParallelPrimeCacheWorkerProgress::Cancelled(cancelled) => {
+                // Cancelled::throw should probably be public
+                std::panic::resume_unwind(Box::new(cancelled));
+            }
         };
 
         let progress = ParallelPrimeCachesProgress {
@@ -186,9 +204,14 @@ pub fn parallel_prime_caches(
                 continue;
             }
             Err(crossbeam_channel::RecvTimeoutError::Disconnected) => {
-                // our workers may have died from a cancelled task, so we'll check and re-raise here.
-                db.unwind_if_revision_cancelled();
-                break;
+                // all our workers have exited, mark us as finished and exit
+                cb(ParallelPrimeCachesProgress {
+                    crates_currently_indexing: vec![],
+                    crates_done,
+                    crates_total: crates_done,
+                    work_type: "Populating symbols",
+                });
+                return;
             }
         };
         match worker_progress {
@@ -199,6 +222,10 @@ pub fn parallel_prime_caches(
                 crates_currently_indexing.swap_remove(&crate_id);
                 crates_done += 1;
             }
+            ParallelPrimeCacheWorkerProgress::Cancelled(cancelled) => {
+                // Cancelled::throw should probably be public
+                std::panic::resume_unwind(Box::new(cancelled));
+            }
         };
 
         let progress = ParallelPrimeCachesProgress {
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/expected_function.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/expected_function.rs
index af25c2b2e33..a6da0fd9c5e 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/expected_function.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/expected_function.rs
@@ -31,7 +31,7 @@ fn foo() {
     x();
  // ^^^ error: expected function, found i32
     ""();
- // ^^^^ error: expected function, found &str
+ // ^^^^ error: expected function, found &'static str
     foo();
 }
 "#,
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs
index b56255b1fde..d72b21099ce 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs
@@ -166,7 +166,7 @@ fn main() {
     let _ = ptr as bool;
           //^^^^^^^^^^^ error: cannot cast `*const ()` as `bool`
     let v = "hello" as bool;
-          //^^^^^^^^^^^^^^^ error: casting `&str` as `bool` is invalid: needs casting through a raw pointer first
+          //^^^^^^^^^^^^^^^ error: casting `&'static str` as `bool` is invalid: needs casting through a raw pointer first
 }
 "#,
         );
@@ -956,7 +956,7 @@ fn main() {
 fn main() {
     let pointer: usize = &1_i32 as *const i32 as usize;
     let _reference: &'static i32 = unsafe { pointer as *const i32 as &'static i32 };
-                                          //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: non-primitive cast: `*const i32` as `&i32`
+                                          //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: non-primitive cast: `*const i32` as `&'static i32`
 }
 "#,
         );
@@ -992,7 +992,7 @@ impl Deref for Foo {
 
 fn main() {
     let _ = "foo" as bool;
-          //^^^^^^^^^^^^^ error: casting `&str` as `bool` is invalid: needs casting through a raw pointer first
+          //^^^^^^^^^^^^^ error: casting `&'static str` as `bool` is invalid: needs casting through a raw pointer first
 
     let _ = Foo as bool;
           //^^^^^^^^^^^ error: non-primitive cast: `Foo` as `bool`
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs
index 6b02111016c..a354d123f5a 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs
@@ -5,9 +5,13 @@ use hir::{
     sym,
 };
 use ide_db::{
-    FxHashMap, assists::Assist, famous_defs::FamousDefs,
-    imports::import_assets::item_for_path_search, source_change::SourceChange,
-    syntax_helpers::tree_diff::diff, text_edit::TextEdit,
+    FxHashMap,
+    assists::{Assist, ExprFillDefaultMode},
+    famous_defs::FamousDefs,
+    imports::import_assets::item_for_path_search,
+    source_change::SourceChange,
+    syntax_helpers::tree_diff::diff,
+    text_edit::TextEdit,
     use_trivial_constructor::use_trivial_constructor,
 };
 use stdx::format_to;
@@ -102,8 +106,9 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option<Vec<Ass
             });
 
             let generate_fill_expr = |ty: &Type| match ctx.config.expr_fill_default {
-                crate::ExprFillDefaultMode::Todo => make::ext::expr_todo(),
-                crate::ExprFillDefaultMode::Default => {
+                ExprFillDefaultMode::Todo => make::ext::expr_todo(),
+                ExprFillDefaultMode::Underscore => make::ext::expr_underscore(),
+                ExprFillDefaultMode::Default => {
                     get_default_constructor(ctx, d, ty).unwrap_or_else(make::ext::expr_todo)
                 }
             };
@@ -158,9 +163,14 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option<Vec<Ass
             let old_field_list = field_list_parent.record_pat_field_list()?;
             let new_field_list = old_field_list.clone_for_update();
             for (f, _) in missing_fields.iter() {
-                let field = make::record_pat_field_shorthand(make::name_ref(
-                    &f.name(ctx.sema.db).display_no_db(ctx.edition).to_smolstr(),
-                ));
+                let field = make::record_pat_field_shorthand(
+                    make::ident_pat(
+                        false,
+                        false,
+                        make::name(&f.name(ctx.sema.db).display_no_db(ctx.edition).to_smolstr()),
+                    )
+                    .into(),
+                );
                 new_field_list.add_field(field.clone_for_update());
             }
             build_text_edit(new_field_list.syntax(), old_field_list.syntax())
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs
index 7d0f10983d7..780271361d7 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs
@@ -18,7 +18,22 @@ pub(crate) fn moved_out_of_ref(ctx: &DiagnosticsContext<'_>, d: &hir::MovedOutOf
 mod tests {
     use crate::tests::check_diagnostics;
 
-    // FIXME: spans are broken
+    #[test]
+    fn operand_field_span_respected() {
+        check_diagnostics(
+            r#"
+struct NotCopy;
+struct S {
+    field: NotCopy,
+}
+
+fn f(s: &S) -> S {
+    S { field: s.field }
+             //^^^^^^^ error: cannot move `NotCopy` out of reference
+}
+            "#,
+        );
+    }
 
     #[test]
     fn move_by_explicit_deref() {
@@ -85,7 +100,7 @@ fn consume<T>(_: X<T>) {
 fn main() {
     let a = &X(Y);
     consume(*a);
-  //^^^^^^^^^^^ error: cannot move `X<Y>` out of reference
+          //^^ error: cannot move `X<Y>` out of reference
     let a = &X(5);
     consume(*a);
 }
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs
index 8f6ed1a7bdb..500c5de791d 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs
@@ -195,7 +195,7 @@ fn remove_unnecessary_wrapper(
     let db = ctx.sema.db;
     let root = db.parse_or_expand(expr_ptr.file_id);
     let expr = expr_ptr.value.to_node(&root);
-    let expr = ctx.sema.original_ast_node(expr.clone())?;
+    let expr = ctx.sema.original_ast_node(expr)?;
 
     let Expr::CallExpr(call_expr) = expr else {
         return None;
@@ -306,10 +306,9 @@ fn str_ref_to_owned(
     acc: &mut Vec<Assist>,
 ) -> Option<()> {
     let expected = d.expected.display(ctx.sema.db, ctx.display_target);
-    let actual = d.actual.display(ctx.sema.db, ctx.display_target);
-
     // FIXME do this properly
-    if expected.to_string() != "String" || actual.to_string() != "&str" {
+    let is_applicable = d.actual.strip_reference().is_str() && expected.to_string() == "String";
+    if !is_applicable {
         return None;
     }
 
@@ -1176,7 +1175,7 @@ trait B {}
 
 fn test(a: &dyn A) -> &dyn B {
     a
-  //^ error: expected &dyn B, found &dyn A
+  //^ error: expected &(dyn B + 'static), found &(dyn A + 'static)
 }
 "#,
         );
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs
index 277aff2e08f..a933f1b4261 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs
@@ -1,3 +1,5 @@
+use std::ops::Not;
+
 use hir::{
     ClosureStyle, HirDisplay, ImportPathConfig,
     db::ExpandDatabase,
@@ -60,9 +62,13 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole) -> Option<Vec<Assist>
 
     let mut formatter = |_: &hir::Type| String::from("_");
 
-    let assists: Vec<Assist> = paths
+    let assists: Vec<Assist> = d
+        .expected
+        .is_unknown()
+        .not()
+        .then(|| "todo!()".to_owned())
         .into_iter()
-        .filter_map(|path| {
+        .chain(paths.into_iter().filter_map(|path| {
             path.gen_source_code(
                 &scope,
                 &mut formatter,
@@ -75,7 +81,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole) -> Option<Vec<Assist>
                 ctx.display_target,
             )
             .ok()
-        })
+        }))
         .unique()
         .map(|code| Assist {
             id: AssistId::quick_fix("typed-hole"),
@@ -95,9 +101,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole) -> Option<Vec<Assist>
 
 #[cfg(test)]
 mod tests {
-    use crate::tests::{
-        check_diagnostics, check_fixes_unordered, check_has_fix, check_has_single_fix,
-    };
+    use crate::tests::{check_diagnostics, check_fixes_unordered, check_has_fix};
 
     #[test]
     fn unknown() {
@@ -119,9 +123,9 @@ fn main() {
     if _ {}
      //^ 💡 error: invalid `_` expression, expected type `bool`
     let _: fn() -> i32 = _;
-                       //^ error: invalid `_` expression, expected type `fn() -> i32`
+                       //^ 💡 error: invalid `_` expression, expected type `fn() -> i32`
     let _: fn() -> () = _; // FIXME: This should trigger an assist because `main` matches via *coercion*
-                      //^ error: invalid `_` expression, expected type `fn()`
+                      //^ 💡 error: invalid `_` expression, expected type `fn()`
 }
 "#,
         );
@@ -147,7 +151,7 @@ fn main() {
 fn main() {
     let mut x = t();
     x = _;
-      //^ error: invalid `_` expression, expected type `&str`
+      //^ 💡 error: invalid `_` expression, expected type `&'static str`
     x = "";
 }
 fn t<T>() -> T { loop {} }
@@ -308,7 +312,7 @@ fn main() {
 
     #[test]
     fn ignore_impl_func_with_incorrect_return() {
-        check_has_single_fix(
+        check_fixes_unordered(
             r#"
 struct Bar {}
 trait Foo {
@@ -323,7 +327,8 @@ fn main() {
     let a: i32 = 1;
     let c: Bar = _$0;
 }"#,
-            r#"
+            vec![
+                r#"
 struct Bar {}
 trait Foo {
     type Res;
@@ -337,6 +342,21 @@ fn main() {
     let a: i32 = 1;
     let c: Bar = Bar {  };
 }"#,
+                r#"
+struct Bar {}
+trait Foo {
+    type Res;
+    fn foo(&self) -> Self::Res;
+}
+impl Foo for i32 {
+    type Res = Self;
+    fn foo(&self) -> Self::Res { 1 }
+}
+fn main() {
+    let a: i32 = 1;
+    let c: Bar = todo!();
+}"#,
+            ],
         );
     }
 
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs
index 4422d8f8262..7f07009dc56 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs
@@ -269,7 +269,7 @@ impl<T, U> A<T, U> {
 }
 fn main() {
     let a = A {a: 0, b: ""};
-    A::<i32, &str>::foo();
+    A::<i32, &'static str>::foo();
 }
 "#,
         );
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
index 11efedd8a59..607721d611d 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
@@ -92,7 +92,7 @@ use hir::{
 };
 use ide_db::{
     EditionedFileId, FileId, FileRange, FxHashMap, FxHashSet, RootDatabase, Severity, SnippetCap,
-    assists::{Assist, AssistId, AssistResolveStrategy},
+    assists::{Assist, AssistId, AssistResolveStrategy, ExprFillDefaultMode},
     base_db::{ReleaseChannel, RootQueryDb as _},
     generated::lints::{CLIPPY_LINT_GROUPS, DEFAULT_LINT_GROUPS, DEFAULT_LINTS, Lint, LintGroup},
     imports::insert_use::InsertUseConfig,
@@ -219,17 +219,6 @@ impl Diagnostic {
     }
 }
 
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub enum ExprFillDefaultMode {
-    Todo,
-    Default,
-}
-impl Default for ExprFillDefaultMode {
-    fn default() -> Self {
-        Self::Todo
-    }
-}
-
 #[derive(Debug, Clone)]
 pub struct DiagnosticsConfig {
     /// Whether native diagnostics are enabled.
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs
index 13d08d46ded..4e4bd47e1c2 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs
@@ -3,14 +3,16 @@
 mod overly_long_real_world_cases;
 
 use ide_db::{
-    LineIndexDatabase, RootDatabase, assists::AssistResolveStrategy, base_db::SourceDatabase,
+    LineIndexDatabase, RootDatabase,
+    assists::{AssistResolveStrategy, ExprFillDefaultMode},
+    base_db::SourceDatabase,
 };
 use itertools::Itertools;
 use stdx::trim_indent;
 use test_fixture::WithFixture;
 use test_utils::{MiniCore, assert_eq_text, extract_annotations};
 
-use crate::{DiagnosticsConfig, ExprFillDefaultMode, Severity};
+use crate::{DiagnosticsConfig, Severity};
 
 /// Takes a multi-file input fixture with annotated cursor positions,
 /// and checks that:
@@ -160,55 +162,6 @@ pub(crate) fn check_has_fix(
     assert!(fix.is_some(), "no diagnostic with desired fix");
 }
 
-#[track_caller]
-pub(crate) fn check_has_single_fix(
-    #[rust_analyzer::rust_fixture] ra_fixture_before: &str,
-    #[rust_analyzer::rust_fixture] ra_fixture_after: &str,
-) {
-    let after = trim_indent(ra_fixture_after);
-
-    let (db, file_position) = RootDatabase::with_position(ra_fixture_before);
-    let mut conf = DiagnosticsConfig::test_sample();
-    conf.expr_fill_default = ExprFillDefaultMode::Default;
-    let mut n_fixes = 0;
-    let fix = super::full_diagnostics(
-        &db,
-        &conf,
-        &AssistResolveStrategy::All,
-        file_position.file_id.file_id(&db),
-    )
-    .into_iter()
-    .find(|d| {
-        d.fixes
-            .as_ref()
-            .and_then(|fixes| {
-                n_fixes += fixes.len();
-                fixes.iter().find(|fix| {
-                    if !fix.target.contains_inclusive(file_position.offset) {
-                        return false;
-                    }
-                    let actual = {
-                        let source_change = fix.source_change.as_ref().unwrap();
-                        let file_id = *source_change.source_file_edits.keys().next().unwrap();
-                        let mut actual = db.file_text(file_id).text(&db).to_string();
-
-                        for (edit, snippet_edit) in source_change.source_file_edits.values() {
-                            edit.apply(&mut actual);
-                            if let Some(snippet_edit) = snippet_edit {
-                                snippet_edit.apply(&mut actual);
-                            }
-                        }
-                        actual
-                    };
-                    after == actual
-                })
-            })
-            .is_some()
-    });
-    assert!(fix.is_some(), "no diagnostic with desired fix");
-    assert!(n_fixes == 1, "Too many fixes suggested");
-}
-
 /// Checks that there's a diagnostic *without* fix at `$0`.
 pub(crate) fn check_no_fix(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
     let (db, file_position) = RootDatabase::with_position(ra_fixture);
diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
index ebbd68bcdf7..f0247f32d7e 100644
--- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
@@ -599,7 +599,7 @@ fn filename_and_frag_for_def(
             Some(name) => {
                 match m.attrs(db).by_key(sym::doc).find_string_value_in_tt(sym::keyword) {
                     Some(kw) => {
-                        format!("keyword.{}.html", kw)
+                        format!("keyword.{kw}.html")
                     }
                     None => format!("{}/index.html", name.as_str()),
                 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs
index 2f2d2252f84..075afcec019 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs
@@ -634,9 +634,7 @@ fn walk_and_push_ty(
         } else if let Some(trait_) = t.as_associated_type_parent_trait(db) {
             push_new_def(trait_.into());
         } else if let Some(tp) = t.as_type_param(db) {
-            let sized_trait = db
-                .lang_item(t.krate(db).into(), LangItem::Sized)
-                .and_then(|lang_item| lang_item.as_trait());
+            let sized_trait = LangItem::Sized.resolve_trait(db, t.krate(db).into());
             tp.trait_bounds(db)
                 .into_iter()
                 .filter(|&it| Some(it.into()) != sized_trait)
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 d469cd7c0cd..7b7eef9d579 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
@@ -7085,9 +7085,9 @@ fn foo() {
 }
 "#,
         expect![[r#"
-                ```rust
-                &str
-                ```"#]],
+            ```rust
+            &'static str
+            ```"#]],
     );
 }
 
@@ -8228,7 +8228,7 @@ format_args!("{aaaaa$0}");
             *aaaaa*
 
             ```rust
-            let aaaaa: &str
+            let aaaaa: &'static str
             ```
         "#]],
     );
@@ -8248,7 +8248,7 @@ format_args!("{$0aaaaa}");
             *aaaaa*
 
             ```rust
-            let aaaaa: &str
+            let aaaaa: &'static str
             ```
         "#]],
     );
@@ -8268,7 +8268,7 @@ format_args!(r"{$0aaaaa}");
             *aaaaa*
 
             ```rust
-            let aaaaa: &str
+            let aaaaa: &'static str
             ```
         "#]],
     );
@@ -8293,7 +8293,7 @@ foo!(r"{$0aaaaa}");
             *aaaaa*
 
             ```rust
-            let aaaaa: &str
+            let aaaaa: &'static str
             ```
         "#]],
     );
@@ -8337,7 +8337,7 @@ fn main() {
         expect![[r#"
             *"🦀\u{1f980}\\\x41"*
             ```rust
-            &str
+            &'static str
             ```
             ___
 
@@ -8353,7 +8353,7 @@ fn main() {
         expect![[r#"
             *r"🦀\u{1f980}\\\x41"*
             ```rust
-            &str
+            &'static str
             ```
             ___
 
@@ -8375,7 +8375,7 @@ fsdghs";
 
             fsdghs"*
             ```rust
-            &str
+            &'static str
             ```
             ___
 
@@ -8395,7 +8395,7 @@ fn main() {
         expect![[r#"
             *c"🦀\u{1f980}\\\x41"*
             ```rust
-            &{unknown}
+            &'static {unknown}
             ```
             ___
 
@@ -8414,7 +8414,7 @@ fn main() {
         expect![[r#"
             *r"`[^`]*`"*
             ```rust
-            &str
+            &'static str
             ```
             ___
 
@@ -8429,7 +8429,7 @@ fn main() {
         expect![[r#"
             *r"`"*
             ```rust
-            &str
+            &'static str
             ```
             ___
 
@@ -8444,7 +8444,7 @@ fn main() {
         expect![[r#"
             *r"    "*
             ```rust
-            &str
+            &'static str
             ```
             ___
 
@@ -8460,12 +8460,12 @@ fn main() {
         expect![[r#"
             *r" Hello World "*
             ```rust
-            &str
+            &'static str
             ```
             ___
 
             value of literal: `  Hello World  `
-"#]],
+        "#]],
     )
 }
 
@@ -8480,7 +8480,7 @@ fn main() {
         expect![[r#"
             *b"\xF0\x9F\xA6\x80\\"*
             ```rust
-            &[u8; 5]
+            &'static [u8; 5]
             ```
             ___
 
@@ -8496,7 +8496,7 @@ fn main() {
         expect![[r#"
             *br"\xF0\x9F\xA6\x80\\"*
             ```rust
-            &[u8; 18]
+            &'static [u8; 18]
             ```
             ___
 
@@ -9070,7 +9070,7 @@ struct Pedro$0<'a> {
 
             ```rust
             struct Pedro<'a> {
-                hola: &str,
+                hola: &'a str,
             }
             ```
 
@@ -9937,7 +9937,7 @@ fn baz() {
 
             ---
 
-            `U` = `i32`, `T` = `&str`
+            `U` = `i32`, `T` = `&'static str`
         "#]],
     );
 }
@@ -10030,7 +10030,7 @@ fn bar() {
 
             ---
 
-            `T` = `i8`, `U` = `&str`
+            `T` = `i8`, `U` = `&'static str`
         "#]],
     );
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
index 52ea2e5ec58..36fdd90e8ae 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
@@ -380,9 +380,9 @@ fn main() {
     let foo = foo3();
      // ^^^ impl Fn(f64, f64) -> u32
     let foo = foo4();
-     // ^^^ &dyn Fn(f64, f64) -> u32
+     // ^^^ &'static (dyn Fn(f64, f64) -> u32 + 'static)
     let foo = foo5();
-     // ^^^ &dyn Fn(&dyn Fn(f64, f64) -> u32, f64) -> u32
+     // ^^^ &'static (dyn Fn(&(dyn Fn(f64, f64) -> u32 + 'static), f64) -> u32 + 'static)
     let foo = foo6();
      // ^^^ impl Fn(f64, f64) -> u32
     let foo = foo7();
@@ -413,7 +413,7 @@ fn main() {
     let foo = foo3();
      // ^^^ impl Fn(f64, f64) -> u32
     let foo = foo4();
-     // ^^^ &dyn Fn(f64, f64) -> u32
+     // ^^^ &'static (dyn Fn(f64, f64) -> u32 + 'static)
     let foo = foo5();
     let foo = foo6();
     let foo = foo7();
@@ -528,7 +528,7 @@ fn main() {
           //^^^^ i32
     let _ = 22;
     let test = "test";
-      //^^^^ &str
+      //^^^^ &'static str
     let test = InnerStruct {};
       //^^^^ InnerStruct
 
@@ -618,12 +618,12 @@ impl<T> Iterator for IntoIter<T> {
 
 fn main() {
     let mut data = Vec::new();
-          //^^^^ Vec<&str>
+          //^^^^ Vec<&'static str>
     data.push("foo");
     for i in data {
-      //^ &str
+      //^ &'static str
       let z = i;
-        //^ &str
+        //^ &'static str
     }
 }
 "#,
@@ -651,8 +651,8 @@ fn main() {
       //^^ Vec<Box<&(dyn Display + Sync)>>
     let _v = { Vec::<Box<*const (dyn Display + Sync)>>::new() };
       //^^ Vec<Box<*const (dyn Display + Sync)>>
-    let _v = { Vec::<Box<dyn Display + Sync>>::new() };
-      //^^ Vec<Box<dyn Display + Sync>>
+    let _v = { Vec::<Box<dyn Display + Sync + 'static>>::new() };
+      //^^ Vec<Box<dyn Display + Sync + 'static>>
 }
 "#,
         );
@@ -1017,7 +1017,7 @@ fn test<T>(t: T) {
 "#,
             expect![[r#"
                 fn test<T>(t: T) {
-                    let f = |a: i32, b: &str, c: T| {};
+                    let f = |a: i32, b: &'static str, c: T| {};
                     let result: () = f(42, "", t);
                 }
             "#]],
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs
index de9ca8c000f..2ec85da4a42 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs
@@ -194,7 +194,7 @@ impl Tr for () {
 //^ impl Tr for ()
 impl dyn Tr {
   }
-//^ impl dyn Tr
+//^ impl dyn Tr + 'static
 
 static S0: () = 0;
 static S1: () = {};
diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs
index a13be6c4927..aa525a86123 100644
--- a/src/tools/rust-analyzer/crates/ide/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs
@@ -123,9 +123,9 @@ pub use ide_completion::{
     CallableSnippets, CompletionConfig, CompletionFieldsToResolve, CompletionItem,
     CompletionItemKind, CompletionItemRefMode, CompletionRelevance, Snippet, SnippetScope,
 };
-pub use ide_db::text_edit::{Indel, TextEdit};
 pub use ide_db::{
     FileId, FilePosition, FileRange, RootDatabase, Severity, SymbolKind,
+    assists::ExprFillDefaultMode,
     base_db::{Crate, CrateGraphBuilder, FileChange, SourceRoot, SourceRootId},
     documentation::Documentation,
     label::Label,
@@ -134,8 +134,9 @@ pub use ide_db::{
     search::{ReferenceCategory, SearchScope},
     source_change::{FileSystemEdit, SnippetEdit, SourceChange},
     symbol_index::Query,
+    text_edit::{Indel, TextEdit},
 };
-pub use ide_diagnostics::{Diagnostic, DiagnosticCode, DiagnosticsConfig, ExprFillDefaultMode};
+pub use ide_diagnostics::{Diagnostic, DiagnosticCode, DiagnosticsConfig};
 pub use ide_ssr::SsrError;
 pub use span::Edition;
 pub use syntax::{TextRange, TextSize};
@@ -181,7 +182,7 @@ impl AnalysisHost {
     /// Returns a snapshot of the current state, which you can query for
     /// semantic information.
     pub fn analysis(&self) -> Analysis {
-        Analysis { db: self.db.snapshot() }
+        Analysis { db: self.db.clone() }
     }
 
     /// Applies changes to the current state of the world. If there are
@@ -863,7 +864,7 @@ impl Analysis {
     where
         F: FnOnce(&RootDatabase) -> T + std::panic::UnwindSafe,
     {
-        let snap = self.db.snapshot();
+        let snap = self.db.clone();
         Cancelled::catch(|| f(&snap))
     }
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/moniker.rs b/src/tools/rust-analyzer/crates/ide/src/moniker.rs
index 4a06cd919fc..795c1f2ca3c 100644
--- a/src/tools/rust-analyzer/crates/ide/src/moniker.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/moniker.rs
@@ -451,7 +451,7 @@ mod tests {
         assert_eq!(x.len(), 1);
         match x.into_iter().next().unwrap() {
             MonikerResult::Local { enclosing_moniker } => {
-                panic!("Unexpected local enclosed in {:?}", enclosing_moniker);
+                panic!("Unexpected local enclosed in {enclosing_moniker:?}");
             }
             MonikerResult::Moniker(x) => {
                 assert_eq!(identifier, x.identifier.to_string());
diff --git a/src/tools/rust-analyzer/crates/ide/src/status.rs b/src/tools/rust-analyzer/crates/ide/src/status.rs
index 55a0db2d820..cfcd76d2aa3 100644
--- a/src/tools/rust-analyzer/crates/ide/src/status.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/status.rs
@@ -51,8 +51,8 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option<FileId>) -> String {
                 buf,
                 "Crate: {}\n",
                 match display_name {
-                    Some(it) => format!("{it}({:?})", crate_id),
-                    None => format!("{:?}", crate_id),
+                    Some(it) => format!("{it}({crate_id:?})"),
+                    None => format!("{crate_id:?}"),
                 }
             );
             format_to!(buf, "    Root module file id: {}\n", root_file_id.index());
diff --git a/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs b/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs
index 4696fef3209..7985279679c 100644
--- a/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs
@@ -80,7 +80,7 @@ impl<'a> dot::Labeller<'a, Crate, Edge<'a>> for DotCrateGraph<'_> {
 
     fn node_id(&'a self, n: &Crate) -> Id<'a> {
         let id = n.as_id().as_u32();
-        Id::new(format!("_{:?}", id)).unwrap()
+        Id::new(format!("_{id:?}")).unwrap()
     }
 
     fn node_shape(&'a self, _node: &Crate) -> Option<LabelText<'a>> {
diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol.rs b/src/tools/rust-analyzer/crates/intern/src/symbol.rs
index 89c3be96fcb..8b2d6e8717d 100644
--- a/src/tools/rust-analyzer/crates/intern/src/symbol.rs
+++ b/src/tools/rust-analyzer/crates/intern/src/symbol.rs
@@ -163,28 +163,28 @@ impl Symbol {
 
     pub fn integer(i: usize) -> Self {
         match i {
-            0 => symbols::INTEGER_0.clone(),
-            1 => symbols::INTEGER_1.clone(),
-            2 => symbols::INTEGER_2.clone(),
-            3 => symbols::INTEGER_3.clone(),
-            4 => symbols::INTEGER_4.clone(),
-            5 => symbols::INTEGER_5.clone(),
-            6 => symbols::INTEGER_6.clone(),
-            7 => symbols::INTEGER_7.clone(),
-            8 => symbols::INTEGER_8.clone(),
-            9 => symbols::INTEGER_9.clone(),
-            10 => symbols::INTEGER_10.clone(),
-            11 => symbols::INTEGER_11.clone(),
-            12 => symbols::INTEGER_12.clone(),
-            13 => symbols::INTEGER_13.clone(),
-            14 => symbols::INTEGER_14.clone(),
-            15 => symbols::INTEGER_15.clone(),
+            0 => symbols::INTEGER_0,
+            1 => symbols::INTEGER_1,
+            2 => symbols::INTEGER_2,
+            3 => symbols::INTEGER_3,
+            4 => symbols::INTEGER_4,
+            5 => symbols::INTEGER_5,
+            6 => symbols::INTEGER_6,
+            7 => symbols::INTEGER_7,
+            8 => symbols::INTEGER_8,
+            9 => symbols::INTEGER_9,
+            10 => symbols::INTEGER_10,
+            11 => symbols::INTEGER_11,
+            12 => symbols::INTEGER_12,
+            13 => symbols::INTEGER_13,
+            14 => symbols::INTEGER_14,
+            15 => symbols::INTEGER_15,
             i => Symbol::intern(&format!("{i}")),
         }
     }
 
     pub fn empty() -> Self {
-        symbols::__empty.clone()
+        symbols::__empty
     }
 
     #[inline]
diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs
index 3e52dbaea65..2686a75c7c8 100644
--- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs
@@ -292,7 +292,7 @@ impl ProjectFolders {
             };
 
             let file_set_roots = vec![VfsPath::from(ratoml_path.to_owned())];
-            let entry = vfs::loader::Entry::Files(vec![ratoml_path.to_owned()]);
+            let entry = vfs::loader::Entry::Files(vec![ratoml_path]);
 
             res.watch.push(res.load.len());
             res.load.push(entry);
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs
index 34dcf2a1822..0ac25da3294 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs
@@ -4,7 +4,7 @@ use crate::grammar::attributes::ATTRIBUTE_FIRST;
 
 use super::*;
 
-pub(super) use atom::{LITERAL_FIRST, literal};
+pub(super) use atom::{EXPR_RECOVERY_SET, LITERAL_FIRST, literal};
 pub(crate) use atom::{block_expr, match_arm_list};
 
 #[derive(PartialEq, Eq)]
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs
index c66afed91c5..5faf6fc2759 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs
@@ -46,7 +46,6 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet =
         T!['['],
         T![|],
         T![async],
-        T![box],
         T![break],
         T![const],
         T![continue],
@@ -68,7 +67,8 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet =
         LIFETIME_IDENT,
     ]));
 
-pub(super) const EXPR_RECOVERY_SET: TokenSet = TokenSet::new(&[T![')'], T![']']]);
+pub(in crate::grammar) const EXPR_RECOVERY_SET: TokenSet =
+    TokenSet::new(&[T!['}'], T![')'], T![']'], T![,]]);
 
 pub(super) fn atom_expr(
     p: &mut Parser<'_>,
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs
index f5f003be489..b9f4866574a 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs
@@ -32,6 +32,9 @@ pub(super) const ITEM_RECOVERY_SET: TokenSet = TokenSet::new(&[
     T![impl],
     T![trait],
     T![const],
+    T![async],
+    T![unsafe],
+    T![extern],
     T![static],
     T![let],
     T![mod],
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs
index 3410505cd46..770827c6b0d 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs
@@ -81,7 +81,7 @@ fn path_for_qualifier(
 }
 
 const EXPR_PATH_SEGMENT_RECOVERY_SET: TokenSet =
-    items::ITEM_RECOVERY_SET.union(TokenSet::new(&[T![')'], T![,], T![let]]));
+    expressions::EXPR_RECOVERY_SET.union(items::ITEM_RECOVERY_SET);
 const TYPE_PATH_SEGMENT_RECOVERY_SET: TokenSet = types::TYPE_RECOVERY_SET;
 
 fn path_segment(p: &mut Parser<'_>, mode: Mode, first: bool) -> Option<CompletedMarker> {
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs
index 460051a0f4a..4dd44c030f3 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs
@@ -199,8 +199,19 @@ fn pattern_single_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
     }
 }
 
-const PAT_RECOVERY_SET: TokenSet =
-    TokenSet::new(&[T![let], T![if], T![while], T![loop], T![match], T![')'], T![,], T![=]]);
+const PAT_RECOVERY_SET: TokenSet = TokenSet::new(&[
+    T![let],
+    T![if],
+    T![while],
+    T![loop],
+    T![match],
+    T![')'],
+    T![']'],
+    T!['}'],
+    T![,],
+    T![=],
+    T![&],
+]);
 
 fn atom_pat(p: &mut Parser<'_>, recovery_set: TokenSet) -> Option<CompletedMarker> {
     let m = match p.current() {
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/types.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/types.rs
index 0133b7d5d82..9d31e435cf9 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/types.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/types.rs
@@ -20,10 +20,15 @@ pub(super) const TYPE_FIRST: TokenSet = paths::PATH_FIRST.union(TokenSet::new(&[
 
 pub(super) const TYPE_RECOVERY_SET: TokenSet = TokenSet::new(&[
     T![')'],
+    // test_err type_in_array_recover
+    // const _: [&];
+    T![']'],
+    T!['}'],
     T![>],
     T![,],
     // test_err struct_field_recover
     // struct S { f pub g: () }
+    // struct S { f: pub g: () }
     T![pub],
 ]);
 
diff --git a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs
index 585e7ffb1ae..0a5c16dc4c4 100644
--- a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs
@@ -179,6 +179,15 @@ impl<'a> Converter<'a> {
                     COMMENT
                 }
 
+                rustc_lexer::TokenKind::Frontmatter  { has_invalid_preceding_whitespace, invalid_infostring } => {
+                    if *has_invalid_preceding_whitespace {
+                        err = "invalid preceding whitespace for frontmatter opening"
+                    } else if *invalid_infostring {
+                        err = "invalid infostring for frontmatter"
+                    }
+                    FRONTMATTER
+                }
+
                 rustc_lexer::TokenKind::Whitespace => WHITESPACE,
 
                 rustc_lexer::TokenKind::Ident if token_text == "_" => UNDERSCORE,
diff --git a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs
index e6f93a1fbda..b1727509b13 100644
--- a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs
@@ -150,6 +150,7 @@ pub enum SyntaxKind {
     STRING,
     COMMENT,
     ERROR,
+    FRONTMATTER,
     IDENT,
     LIFETIME_IDENT,
     NEWLINE,
@@ -483,6 +484,7 @@ impl SyntaxKind {
             | YIELD_EXPR
             | COMMENT
             | ERROR
+            | FRONTMATTER
             | IDENT
             | LIFETIME_IDENT
             | NEWLINE
@@ -994,7 +996,7 @@ impl SyntaxKind {
     }
 }
 #[macro_export]
-macro_rules ! T_ { [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [abstract] => { $ crate :: SyntaxKind :: ABSTRACT_KW } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [become] => { $ crate :: SyntaxKind :: BECOME_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [do] => { $ crate :: SyntaxKind :: DO_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [final] => { $ crate :: SyntaxKind :: FINAL_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [override] => { $ crate :: SyntaxKind :: OVERRIDE_KW } ; [priv] => { $ crate :: SyntaxKind :: PRIV_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [typeof] => { $ crate :: SyntaxKind :: TYPEOF_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [unsized] => { $ crate :: SyntaxKind :: UNSIZED_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [virtual] => { $ crate :: SyntaxKind :: VIRTUAL_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [asm] => { $ crate :: SyntaxKind :: ASM_KW } ; [att_syntax] => { $ crate :: SyntaxKind :: ATT_SYNTAX_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW } ; [clobber_abi] => { $ crate :: SyntaxKind :: CLOBBER_ABI_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [format_args] => { $ crate :: SyntaxKind :: FORMAT_ARGS_KW } ; [inlateout] => { $ crate :: SyntaxKind :: INLATEOUT_KW } ; [inout] => { $ crate :: SyntaxKind :: INOUT_KW } ; [label] => { $ crate :: SyntaxKind :: LABEL_KW } ; [lateout] => { $ crate :: SyntaxKind :: LATEOUT_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [may_unwind] => { $ crate :: SyntaxKind :: MAY_UNWIND_KW } ; [nomem] => { $ crate :: SyntaxKind :: NOMEM_KW } ; [noreturn] => { $ crate :: SyntaxKind :: NORETURN_KW } ; [nostack] => { $ crate :: SyntaxKind :: NOSTACK_KW } ; [offset_of] => { $ crate :: SyntaxKind :: OFFSET_OF_KW } ; [options] => { $ crate :: SyntaxKind :: OPTIONS_KW } ; [out] => { $ crate :: SyntaxKind :: OUT_KW } ; [preserves_flags] => { $ crate :: SyntaxKind :: PRESERVES_FLAGS_KW } ; [pure] => { $ crate :: SyntaxKind :: PURE_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [readonly] => { $ crate :: SyntaxKind :: READONLY_KW } ; [safe] => { $ crate :: SyntaxKind :: SAFE_KW } ; [sym] => { $ crate :: SyntaxKind :: SYM_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [yeet] => { $ crate :: SyntaxKind :: YEET_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [gen] => { $ crate :: SyntaxKind :: GEN_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [int_number] => { $ crate :: SyntaxKind :: INT_NUMBER } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [string] => { $ crate :: SyntaxKind :: STRING } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; }
+macro_rules ! T_ { [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [abstract] => { $ crate :: SyntaxKind :: ABSTRACT_KW } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [become] => { $ crate :: SyntaxKind :: BECOME_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [do] => { $ crate :: SyntaxKind :: DO_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [final] => { $ crate :: SyntaxKind :: FINAL_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [override] => { $ crate :: SyntaxKind :: OVERRIDE_KW } ; [priv] => { $ crate :: SyntaxKind :: PRIV_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [typeof] => { $ crate :: SyntaxKind :: TYPEOF_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [unsized] => { $ crate :: SyntaxKind :: UNSIZED_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [virtual] => { $ crate :: SyntaxKind :: VIRTUAL_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [asm] => { $ crate :: SyntaxKind :: ASM_KW } ; [att_syntax] => { $ crate :: SyntaxKind :: ATT_SYNTAX_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW } ; [clobber_abi] => { $ crate :: SyntaxKind :: CLOBBER_ABI_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [format_args] => { $ crate :: SyntaxKind :: FORMAT_ARGS_KW } ; [inlateout] => { $ crate :: SyntaxKind :: INLATEOUT_KW } ; [inout] => { $ crate :: SyntaxKind :: INOUT_KW } ; [label] => { $ crate :: SyntaxKind :: LABEL_KW } ; [lateout] => { $ crate :: SyntaxKind :: LATEOUT_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [may_unwind] => { $ crate :: SyntaxKind :: MAY_UNWIND_KW } ; [nomem] => { $ crate :: SyntaxKind :: NOMEM_KW } ; [noreturn] => { $ crate :: SyntaxKind :: NORETURN_KW } ; [nostack] => { $ crate :: SyntaxKind :: NOSTACK_KW } ; [offset_of] => { $ crate :: SyntaxKind :: OFFSET_OF_KW } ; [options] => { $ crate :: SyntaxKind :: OPTIONS_KW } ; [out] => { $ crate :: SyntaxKind :: OUT_KW } ; [preserves_flags] => { $ crate :: SyntaxKind :: PRESERVES_FLAGS_KW } ; [pure] => { $ crate :: SyntaxKind :: PURE_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [readonly] => { $ crate :: SyntaxKind :: READONLY_KW } ; [safe] => { $ crate :: SyntaxKind :: SAFE_KW } ; [sym] => { $ crate :: SyntaxKind :: SYM_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [yeet] => { $ crate :: SyntaxKind :: YEET_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [gen] => { $ crate :: SyntaxKind :: GEN_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [int_number] => { $ crate :: SyntaxKind :: INT_NUMBER } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [string] => { $ crate :: SyntaxKind :: STRING } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; [frontmatter] => { $ crate :: SyntaxKind :: FRONTMATTER } ; }
 impl ::core::marker::Copy for SyntaxKind {}
 impl ::core::clone::Clone for SyntaxKind {
     #[inline]
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs
index 6c9d02aaa8f..24db9478ee5 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs
@@ -870,6 +870,10 @@ mod err {
         run_and_expect_errors("test_data/parser/inline/err/tuple_pat_leading_comma.rs");
     }
     #[test]
+    fn type_in_array_recover() {
+        run_and_expect_errors("test_data/parser/inline/err/type_in_array_recover.rs");
+    }
+    #[test]
     fn unsafe_block_in_mod() {
         run_and_expect_errors("test_data/parser/inline/err/unsafe_block_in_mod.rs");
     }
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0022_bad_exprs.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0022_bad_exprs.rast
index d97fc6c7209..1a8e881dd9e 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0022_bad_exprs.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0022_bad_exprs.rast
@@ -35,8 +35,8 @@ SOURCE_FILE
         WHITESPACE " "
         LET_STMT
           LET_KW "let"
-          ERROR
-            R_BRACK "]"
+        ERROR
+          R_BRACK "]"
         WHITESPACE " "
         R_CURLY "}"
   WHITESPACE "\n"
@@ -149,7 +149,8 @@ error 17: expected expression, item or let statement
 error 25: expected a name
 error 26: expected `;`, `{`, or `(`
 error 30: expected pattern
-error 31: expected SEMICOLON
+error 30: expected SEMICOLON
+error 30: expected expression, item or let statement
 error 53: expected expression
 error 54: expected R_PAREN
 error 54: expected SEMICOLON
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_default_values_syntax.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_default_values_syntax.rast
index feb617e1aa2..b57066f2fb3 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_default_values_syntax.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_default_values_syntax.rast
@@ -23,8 +23,7 @@ SOURCE_FILE
               L_CURLY "{"
               WHITESPACE " "
               DOT2 ".."
-              ERROR
-                COMMA ","
+              COMMA ","
               WHITESPACE " "
               R_CURLY "}"
           SEMICOLON ";"
@@ -39,8 +38,7 @@ SOURCE_FILE
             L_CURLY "{"
             WHITESPACE " "
             DOT2 ".."
-            ERROR
-              COMMA ","
+            COMMA ","
             WHITESPACE " "
             RECORD_EXPR_FIELD
               NAME_REF
@@ -55,5 +53,6 @@ SOURCE_FILE
         R_CURLY "}"
   WHITESPACE "\n"
 error 21: expected expression
+error 21: cannot use a comma after the base struct
 error 36: expected expression
-error 37: expected COMMA
+error 36: cannot use a comma after the base struct
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rast
index 458d7f4e2fa..5a12c21b647 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rast
@@ -26,6 +26,36 @@ SOURCE_FILE
       WHITESPACE " "
       R_CURLY "}"
   WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S"
+    WHITESPACE " "
+    RECORD_FIELD_LIST
+      L_CURLY "{"
+      WHITESPACE " "
+      RECORD_FIELD
+        NAME
+          IDENT "f"
+        COLON ":"
+      WHITESPACE " "
+      RECORD_FIELD
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        NAME
+          IDENT "g"
+        COLON ":"
+        WHITESPACE " "
+        TUPLE_TYPE
+          L_PAREN "("
+          R_PAREN ")"
+      WHITESPACE " "
+      R_CURLY "}"
+  WHITESPACE "\n"
 error 12: expected COLON
 error 12: expected type
 error 12: expected COMMA
+error 38: expected type
+error 38: expected COMMA
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rs
index da32227adcd..5b1e5a5b8a2 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rs
@@ -1 +1,2 @@
 struct S { f pub g: () }
+struct S { f: pub g: () }
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_in_array_recover.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_in_array_recover.rast
new file mode 100644
index 00000000000..db76e8d7c88
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_in_array_recover.rast
@@ -0,0 +1,15 @@
+SOURCE_FILE
+  CONST
+    CONST_KW "const"
+    WHITESPACE " "
+    UNDERSCORE "_"
+    COLON ":"
+    WHITESPACE " "
+    SLICE_TYPE
+      L_BRACK "["
+      REF_TYPE
+        AMP "&"
+      R_BRACK "]"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+error 11: expected type
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_in_array_recover.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_in_array_recover.rs
new file mode 100644
index 00000000000..039bf829977
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_in_array_recover.rs
@@ -0,0 +1 @@
+const _: [&];
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/build.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/build.rs
index 07a10aaae57..97c0c4bda7d 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/build.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/build.rs
@@ -12,5 +12,5 @@ fn main() {
     let version_string = std::str::from_utf8(&output.stdout[..])
         .expect("rustc --version output must be UTF-8")
         .trim();
-    println!("cargo::rustc-env=RUSTC_VERSION={}", version_string);
+    println!("cargo::rustc-env=RUSTC_VERSION={version_string}");
 }
diff --git a/src/tools/rust-analyzer/crates/project-model/src/env.rs b/src/tools/rust-analyzer/crates/project-model/src/env.rs
index f2e5df171ae..e7293b0b2ef 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/env.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/env.rs
@@ -25,7 +25,7 @@ pub(crate) fn inject_cargo_package_env(env: &mut Env, package: &PackageData) {
     env.set("CARGO_PKG_VERSION_PATCH", package.version.patch.to_string());
     env.set("CARGO_PKG_VERSION_PRE", package.version.pre.to_string());
 
-    env.set("CARGO_PKG_AUTHORS", package.authors.join(":").clone());
+    env.set("CARGO_PKG_AUTHORS", package.authors.join(":"));
 
     env.set("CARGO_PKG_NAME", package.name.clone());
     env.set("CARGO_PKG_DESCRIPTION", package.description.as_deref().unwrap_or_default());
diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
index c6e0cf36aff..eec0077ea6e 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
@@ -1370,7 +1370,7 @@ fn detached_file_to_crate_graph(
         Edition::CURRENT,
         display_name.clone(),
         None,
-        cfg_options.clone(),
+        cfg_options,
         None,
         Env::default(),
         CrateOrigin::Local {
diff --git a/src/tools/rust-analyzer/crates/query-group-macro/Cargo.toml b/src/tools/rust-analyzer/crates/query-group-macro/Cargo.toml
index 8aeb2629423..8b03d8f8cc7 100644
--- a/src/tools/rust-analyzer/crates/query-group-macro/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/query-group-macro/Cargo.toml
@@ -20,3 +20,4 @@ syn = { version = "2.0", features = ["full", "extra-traits", "visit-mut"] }
 [dev-dependencies]
 expect-test = "1.5.1"
 salsa.workspace = true
+salsa-macros.workspace = true
diff --git a/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs b/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs
index f4f316c1ac1..ec4b6b2a4ac 100644
--- a/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs
@@ -178,7 +178,7 @@ pub(crate) fn query_group_impl(
     let supertraits = &item_trait.supertraits;
 
     let db_attr: Attribute = parse_quote! {
-        #[salsa::db]
+        #[salsa_macros::db]
     };
     item_trait.attrs.push(db_attr);
 
@@ -210,7 +210,7 @@ pub(crate) fn query_group_impl(
                 .into_iter()
                 .filter(|fn_arg| matches!(fn_arg, FnArg::Typed(_)))
                 .map(|fn_arg| match fn_arg {
-                    FnArg::Typed(pat_type) => pat_type.clone(),
+                    FnArg::Typed(pat_type) => pat_type,
                     FnArg::Receiver(_) => unreachable!("this should have been filtered out"),
                 })
                 .collect::<Vec<syn::PatType>>();
@@ -407,7 +407,7 @@ pub(crate) fn query_group_impl(
         .collect::<Vec<proc_macro2::TokenStream>>();
 
     let input_struct = quote! {
-        #[salsa::input]
+        #[salsa_macros::input]
         pub(crate) struct #input_struct_name {
             #(#fields),*
         }
@@ -418,7 +418,7 @@ pub(crate) fn query_group_impl(
 
     let create_data_method = quote! {
         #[allow(non_snake_case)]
-        #[salsa::tracked]
+        #[salsa_macros::tracked]
         fn #create_data_ident(db: &dyn #trait_name_ident) -> #input_struct_name {
             #input_struct_name::new(db, #(#field_params),*)
         }
@@ -443,7 +443,7 @@ pub(crate) fn query_group_impl(
     item_trait.items.append(&mut lookup_signatures);
 
     let trait_impl = quote! {
-        #[salsa::db]
+        #[salsa_macros::db]
         impl<DB> #trait_name_ident for DB
         where
             DB: #supertraits,
diff --git a/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs b/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs
index d4d40588bfc..baac3e8bbfe 100644
--- a/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs
+++ b/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs
@@ -49,7 +49,7 @@ impl ToTokens for TrackedQuery {
             })
             .into_iter()
             .chain(self.lru.map(|lru| quote!(lru = #lru)));
-        let annotation = quote!(#[salsa::tracked( #(#options),* )]);
+        let annotation = quote!(#[salsa_macros::tracked( #(#options),* )]);
 
         let pat_and_tys = &self.pat_and_tys;
         let params = self
diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/interned.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/interned.rs
index 26ed316122a..f738185b1fe 100644
--- a/src/tools/rust-analyzer/crates/query-group-macro/tests/interned.rs
+++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/interned.rs
@@ -6,7 +6,7 @@ use salsa::plumbing::AsId;
 mod logger_db;
 use logger_db::LoggerDb;
 
-#[salsa::interned(no_lifetime)]
+#[salsa_macros::interned(no_lifetime)]
 pub struct InternedString {
     data: String,
 }
diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs
index 5cf9be36f70..bade0c2cd6f 100644
--- a/src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs
+++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs
@@ -1,6 +1,6 @@
 use std::sync::{Arc, Mutex};
 
-#[salsa::db]
+#[salsa_macros::db]
 #[derive(Default, Clone)]
 pub(crate) struct LoggerDb {
     storage: salsa::Storage<Self>,
@@ -12,7 +12,7 @@ struct Logger {
     logs: Arc<Mutex<Vec<String>>>,
 }
 
-#[salsa::db]
+#[salsa_macros::db]
 impl salsa::Database for LoggerDb {
     fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) {
         let event = event();
@@ -40,7 +40,7 @@ impl LoggerDb {
     /// it is meant to be run from outside any tracked functions.
     pub(crate) fn assert_logs(&self, expected: expect_test::Expect) {
         let logs = std::mem::take(&mut *self.logger.logs.lock().unwrap());
-        expected.assert_eq(&format!("{:#?}", logs));
+        expected.assert_eq(&format!("{logs:#?}"));
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/old_and_new.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/old_and_new.rs
index a18b23a7d8a..cc57ba78455 100644
--- a/src/tools/rust-analyzer/crates/query-group-macro/tests/old_and_new.rs
+++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/old_and_new.rs
@@ -4,7 +4,7 @@ mod logger_db;
 use logger_db::LoggerDb;
 use query_group_macro::query_group;
 
-#[salsa::input]
+#[salsa_macros::input]
 struct Input {
     str: String,
 }
@@ -30,7 +30,7 @@ fn invoke_length_query_actual(db: &dyn PartialMigrationDatabase, input: Input) -
     input.str(db).len()
 }
 
-#[salsa::tracked]
+#[salsa_macros::tracked]
 fn invoke_length_tracked_actual(db: &dyn PartialMigrationDatabase, input: Input) -> usize {
     input.str(db).len()
 }
@@ -87,12 +87,12 @@ fn invoke_tracked_query() {
 fn new_salsa_baseline() {
     let db = LoggerDb::default();
 
-    #[salsa::input]
+    #[salsa_macros::input]
     struct Input {
         str: String,
     }
 
-    #[salsa::tracked]
+    #[salsa_macros::tracked]
     fn new_salsa_length_query(db: &dyn PartialMigrationDatabase, input: Input) -> usize {
         input.str(db).len()
     }
diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/supertrait.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/supertrait.rs
index 70073ac1de3..ad8ada3ef15 100644
--- a/src/tools/rust-analyzer/crates/query-group-macro/tests/supertrait.rs
+++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/supertrait.rs
@@ -1,6 +1,6 @@
 use query_group_macro::query_group;
 
-#[salsa::db]
+#[salsa_macros::db]
 pub trait SourceDb: salsa::Database {
     /// Text of the file.
     fn file_text(&self, id: usize) -> String;
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs
index ea5a5eaa6a4..4dba97c8ec4 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs
@@ -182,10 +182,8 @@ fn with_extra_thread(
     thread_intent: stdx::thread::ThreadIntent,
     f: impl FnOnce() -> anyhow::Result<()> + Send + 'static,
 ) -> anyhow::Result<()> {
-    let handle = stdx::thread::Builder::new(thread_intent)
-        .name(thread_name.into())
-        .stack_size(STACK_SIZE)
-        .spawn(f)?;
+    let handle =
+        stdx::thread::Builder::new(thread_intent, thread_name).stack_size(STACK_SIZE).spawn(f)?;
 
     handle.join()?;
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
index a62005e3c08..a1e4adf0844 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -175,7 +175,7 @@ impl flags::AnalysisStats {
             UsizeWithUnderscore(dep_loc),
             UsizeWithUnderscore(dep_item_trees),
         );
-        eprintln!("  dependency item stats: {}", dep_item_stats);
+        eprintln!("  dependency item stats: {dep_item_stats}");
 
         // FIXME(salsa-transition): bring back stats for ParseQuery (file size)
         // and ParseMacroExpansionQuery (macro expansion "file") size whenever we implement
@@ -295,7 +295,7 @@ impl flags::AnalysisStats {
             UsizeWithUnderscore(workspace_loc),
             UsizeWithUnderscore(workspace_item_trees),
         );
-        eprintln!("    usages: {}", workspace_item_stats);
+        eprintln!("    usages: {workspace_item_stats}");
 
         eprintln!("  Dependencies:");
         eprintln!(
@@ -303,7 +303,7 @@ impl flags::AnalysisStats {
             UsizeWithUnderscore(dep_loc),
             UsizeWithUnderscore(dep_item_trees),
         );
-        eprintln!("    declarations: {}", dep_item_stats);
+        eprintln!("    declarations: {dep_item_stats}");
 
         let crate_def_map_time = crate_def_map_sw.elapsed();
         eprintln!("{:<20} {}", "Item Collection:", crate_def_map_time);
@@ -701,10 +701,9 @@ impl flags::AnalysisStats {
 
         if self.parallel {
             let mut inference_sw = self.stop_watch();
-            let snap = db.snapshot();
             bodies
                 .par_iter()
-                .map_with(snap, |snap, &body| {
+                .map_with(db.clone(), |snap, &body| {
                     snap.body(body.into());
                     snap.infer(body.into());
                 })
@@ -1294,7 +1293,7 @@ impl fmt::Display for UsizeWithUnderscore {
         let num_str = self.0.to_string();
 
         if num_str.len() <= 3 {
-            return write!(f, "{}", num_str);
+            return write!(f, "{num_str}");
         }
 
         let mut result = String::new();
@@ -1307,7 +1306,7 @@ impl fmt::Display for UsizeWithUnderscore {
         }
 
         let result = result.chars().rev().collect::<String>();
-        write!(f, "{}", result)
+        write!(f, "{result}")
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs
index 7c4eeebdfa3..7b12cb14009 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs
@@ -15,11 +15,13 @@ impl flags::Diagnostics {
     pub fn run(self) -> anyhow::Result<()> {
         const STACK_SIZE: usize = 1024 * 1024 * 8;
 
-        let handle = stdx::thread::Builder::new(stdx::thread::ThreadIntent::LatencySensitive)
-            .name("BIG_STACK_THREAD".into())
-            .stack_size(STACK_SIZE)
-            .spawn(|| self.run_())
-            .unwrap();
+        let handle = stdx::thread::Builder::new(
+            stdx::thread::ThreadIntent::LatencySensitive,
+            "BIG_STACK_THREAD",
+        )
+        .stack_size(STACK_SIZE)
+        .spawn(|| self.run_())
+        .unwrap();
 
         handle.join()
     }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs
index c042c26bd18..e3b372c9149 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs
@@ -7,6 +7,7 @@ use std::{cell::RefCell, fs::read_to_string, panic::AssertUnwindSafe, path::Path
 
 use hir::{ChangeWithProcMacros, Crate};
 use ide::{AnalysisHost, DiagnosticCode, DiagnosticsConfig};
+use ide_db::base_db;
 use itertools::Either;
 use paths::Utf8PathBuf;
 use profile::StopWatch;
@@ -310,7 +311,7 @@ impl flags::RustcTests {
                 let tester = AssertUnwindSafe(&mut tester);
                 let p = p.clone();
                 move || {
-                    let _guard = stdx::panic_context::enter(p.display().to_string());
+                    let _guard = base_db::DbPanicContext::enter(p.display().to_string());
                     { tester }.0.test(p);
                 }
             }) {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
index 2062294f807..d258c5d8191 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
@@ -265,10 +265,10 @@ impl flags::Scip {
         };
 
         if !duplicate_symbol_errors.is_empty() {
-            eprintln!("{}", DUPLICATE_SYMBOLS_MESSAGE);
+            eprintln!("{DUPLICATE_SYMBOLS_MESSAGE}");
             for (source_location, symbol) in duplicate_symbol_errors {
-                eprintln!("{}", source_location);
-                eprintln!("  Duplicate symbol: {}", symbol);
+                eprintln!("{source_location}");
+                eprintln!("  Duplicate symbol: {symbol}");
                 eprintln!();
             }
         }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs
index bca7c8a098c..0362e13b88b 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs
@@ -15,11 +15,13 @@ impl flags::UnresolvedReferences {
     pub fn run(self) -> anyhow::Result<()> {
         const STACK_SIZE: usize = 1024 * 1024 * 8;
 
-        let handle = stdx::thread::Builder::new(stdx::thread::ThreadIntent::LatencySensitive)
-            .name("BIG_STACK_THREAD".into())
-            .stack_size(STACK_SIZE)
-            .spawn(|| self.run_())
-            .unwrap();
+        let handle = stdx::thread::Builder::new(
+            stdx::thread::ThreadIntent::LatencySensitive,
+            "BIG_STACK_THREAD",
+        )
+        .stack_size(STACK_SIZE)
+        .spawn(|| self.run_())
+        .unwrap();
 
         handle.join()
     }
@@ -28,7 +30,7 @@ impl flags::UnresolvedReferences {
         let root =
             vfs::AbsPathBuf::assert_utf8(std::env::current_dir()?.join(&self.path)).normalize();
         let config = crate::config::Config::new(
-            root.clone(),
+            root,
             lsp_types::ClientCapabilities::default(),
             vec![],
             None,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs
index 0035d941e2c..d6c80c399ba 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs
@@ -148,10 +148,10 @@ impl<T: Sized + Send + 'static> CommandHandle<T> {
         let stderr = child.0.stderr().take().unwrap();
 
         let actor = CargoActor::<T>::new(parser, sender, stdout, stderr);
-        let thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker)
-            .name("CommandHandle".to_owned())
-            .spawn(move || actor.run())
-            .expect("failed to spawn thread");
+        let thread =
+            stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker, "CommandHandle")
+                .spawn(move || actor.run())
+                .expect("failed to spawn thread");
         Ok(CommandHandle { program, arguments, current_dir, child, thread, _phantom: PhantomData })
     }
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
index dd827949a9c..03e5b1f6f4b 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -9,13 +9,14 @@ use cfg::{CfgAtom, CfgDiff};
 use hir::Symbol;
 use ide::{
     AssistConfig, CallHierarchyConfig, CallableSnippets, CompletionConfig,
-    CompletionFieldsToResolve, DiagnosticsConfig, ExprFillDefaultMode, GenericParameterHints,
-    HighlightConfig, HighlightRelatedConfig, HoverConfig, HoverDocFormat, InlayFieldsToResolve,
-    InlayHintsConfig, JoinLinesConfig, MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind,
-    Snippet, SnippetScope, SourceRootId,
+    CompletionFieldsToResolve, DiagnosticsConfig, GenericParameterHints, HighlightConfig,
+    HighlightRelatedConfig, HoverConfig, HoverDocFormat, InlayFieldsToResolve, InlayHintsConfig,
+    JoinLinesConfig, MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind, Snippet, SnippetScope,
+    SourceRootId,
 };
 use ide_db::{
     SnippetCap,
+    assists::ExprFillDefaultMode,
     imports::insert_use::{ImportGranularity, InsertUseConfig, PrefixKind},
 };
 use itertools::{Either, Itertools};
@@ -1182,7 +1183,7 @@ impl ConfigChange {
         source_root_map: Arc<FxHashMap<SourceRootId, SourceRootId>>,
     ) {
         assert!(self.source_map_change.is_none());
-        self.source_map_change = Some(source_root_map.clone());
+        self.source_map_change = Some(source_root_map);
     }
 }
 
@@ -1493,6 +1494,11 @@ impl Config {
             term_search_fuel: self.assist_termSearch_fuel(source_root).to_owned() as u64,
             term_search_borrowck: self.assist_termSearch_borrowcheck(source_root).to_owned(),
             code_action_grouping: self.code_action_group(),
+            expr_fill_default: match self.assist_expressionFillDefault(source_root) {
+                ExprFillDefaultDef::Todo => ExprFillDefaultMode::Todo,
+                ExprFillDefaultDef::Default => ExprFillDefaultMode::Default,
+                ExprFillDefaultDef::Underscore => ExprFillDefaultMode::Underscore,
+            },
         }
     }
 
@@ -1577,6 +1583,7 @@ impl Config {
             expr_fill_default: match self.assist_expressionFillDefault(source_root) {
                 ExprFillDefaultDef::Todo => ExprFillDefaultMode::Todo,
                 ExprFillDefaultDef::Default => ExprFillDefaultMode::Default,
+                ExprFillDefaultDef::Underscore => ExprFillDefaultMode::Underscore,
             },
             snippet_cap: self.snippet_cap(),
             insert_use: self.insert_use_config(source_root),
@@ -2527,6 +2534,7 @@ where
 enum ExprFillDefaultDef {
     Todo,
     Default,
+    Underscore,
 }
 
 #[derive(Serialize, Deserialize, Debug, Clone)]
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs
index 9b1463b1126..438a2a0ba1e 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs
@@ -5,7 +5,7 @@ use std::mem;
 
 use cargo_metadata::PackageId;
 use ide::FileId;
-use ide_db::FxHashMap;
+use ide_db::{FxHashMap, base_db::DbPanicContext};
 use itertools::Itertools;
 use rustc_hash::FxHashSet;
 use stdx::iter_eq_by;
@@ -215,7 +215,7 @@ pub(crate) fn fetch_native_diagnostics(
     kind: NativeDiagnosticsFetchKind,
 ) -> Vec<(FileId, Vec<lsp_types::Diagnostic>)> {
     let _p = tracing::info_span!("fetch_native_diagnostics").entered();
-    let _ctx = stdx::panic_context::enter("fetch_native_diagnostics".to_owned());
+    let _ctx = DbPanicContext::enter("fetch_native_diagnostics".to_owned());
 
     // the diagnostics produced may point to different files not requested by the concrete request,
     // put those into here and filter later
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs
index 67ddc41f3b2..24c433610f1 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs
@@ -126,10 +126,8 @@ impl CargoParser<DiscoverProjectMessage> for DiscoverProjectParser {
                 Some(msg)
             }
             Err(err) => {
-                let err = DiscoverProjectData::Error {
-                    error: format!("{:#?}\n{}", err, line),
-                    source: None,
-                };
+                let err =
+                    DiscoverProjectData::Error { error: format!("{err:#?}\n{line}"), source: None };
                 Some(DiscoverProjectMessage::new(err))
             }
         }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs
index 2778b311e1e..fc312439d58 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs
@@ -133,10 +133,10 @@ impl FlycheckHandle {
         let actor =
             FlycheckActor::new(id, sender, config, sysroot_root, workspace_root, manifest_path);
         let (sender, receiver) = unbounded::<StateChange>();
-        let thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker)
-            .name("Flycheck".to_owned())
-            .spawn(move || actor.run(receiver))
-            .expect("failed to spawn thread");
+        let thread =
+            stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker, format!("Flycheck{id}"))
+                .spawn(move || actor.run(receiver))
+                .expect("failed to spawn thread");
         FlycheckHandle { id, sender, _thread: thread }
     }
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
index 820276e8aea..3b3b9c87975 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
@@ -511,7 +511,7 @@ impl GlobalState {
 
                 self.fetch_workspaces_queue.request_op(
                     format!("workspace vfs file change: {path}"),
-                    FetchWorkspaceRequest { path: Some(path.to_owned()), force_crate_graph_reload },
+                    FetchWorkspaceRequest { path: Some(path), force_crate_graph_reload },
                 );
             }
         }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs
index 3b76edf528b..f04ada38893 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs
@@ -4,7 +4,10 @@ use std::{
     panic, thread,
 };
 
-use ide_db::base_db::salsa::{self, Cancelled};
+use ide_db::base_db::{
+    DbPanicContext,
+    salsa::{self, Cancelled},
+};
 use lsp_server::{ExtractError, Response, ResponseError};
 use serde::{Serialize, de::DeserializeOwned};
 use stdx::thread::ThreadIntent;
@@ -56,7 +59,7 @@ impl RequestDispatcher<'_> {
             tracing::info_span!("request", method = ?req.method, "request_id" = ?req.id).entered();
         tracing::debug!(?params);
         let result = {
-            let _pctx = stdx::panic_context::enter(panic_context);
+            let _pctx = DbPanicContext::enter(panic_context);
             f(self.global_state, params)
         };
         if let Ok(response) = result_to_response::<R>(req.id, result) {
@@ -86,7 +89,7 @@ impl RequestDispatcher<'_> {
         let global_state_snapshot = self.global_state.snapshot();
 
         let result = panic::catch_unwind(move || {
-            let _pctx = stdx::panic_context::enter(panic_context);
+            let _pctx = DbPanicContext::enter(panic_context);
             f(global_state_snapshot, params)
         });
 
@@ -257,7 +260,7 @@ impl RequestDispatcher<'_> {
         }
         .spawn(intent, move || {
             let result = panic::catch_unwind(move || {
-                let _pctx = stdx::panic_context::enter(panic_context);
+                let _pctx = DbPanicContext::enter(panic_context);
                 f(world, params)
             });
             match thread_result_to_response::<R>(req.id.clone(), result) {
@@ -421,11 +424,8 @@ impl NotificationDispatcher<'_> {
 
         tracing::debug!(?params);
 
-        let _pctx = stdx::panic_context::enter(format!(
-            "\nversion: {}\nnotification: {}",
-            version(),
-            N::METHOD
-        ));
+        let _pctx =
+            DbPanicContext::enter(format!("\nversion: {}\nnotification: {}", version(), N::METHOD));
         if let Err(e) = f(self.global_state, params) {
             tracing::error!(handler = %N::METHOD, error = %e, "notification handler failed");
         }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs
index a30e5d8ce26..b7373f274f0 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs
@@ -309,7 +309,7 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
         let task = move || -> std::result::Result<(), Cancelled> {
             if invocation_strategy_once {
                 let saved_file = vfs_path.as_path().map(|p| p.to_owned());
-                world.flycheck[0].restart_workspace(saved_file.clone());
+                world.flycheck[0].restart_workspace(saved_file);
             }
 
             let target = TargetSpec::for_file(&world, file_id)?.and_then(|it| {
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 e08dd80973a..69983a67626 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
@@ -2210,7 +2210,7 @@ fn runnable_action_links(
         let label = update_test.label();
         if let Some(r) = to_proto::make_update_runnable(&r, update_test) {
             let update_command = to_proto::command::run_single(&r, label.unwrap().as_str());
-            group.commands.push(to_command_link(update_command, r.label.clone()));
+            group.commands.push(to_command_link(update_command, r.label));
         }
     }
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
index 96c2ceef6ba..f6bcb5642c3 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
@@ -1064,7 +1064,7 @@ fn main() {
         ),
         work_done_progress_params: Default::default(),
     });
-    assert!(res.to_string().contains("&str"));
+    assert!(res.to_string().contains("&'static str"));
 
     let res = server.send_request::<HoverRequest>(HoverParams {
         text_document_position_params: TextDocumentPositionParams::new(
@@ -1073,7 +1073,7 @@ fn main() {
         ),
         work_done_progress_params: Default::default(),
     });
-    assert!(res.to_string().contains("&str"));
+    assert!(res.to_string().contains("&'static str"));
 
     server.request::<GotoTypeDefinition>(
         GotoDefinitionParams {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/ratoml.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/ratoml.rs
index 3f313b7e57f..485f32281dd 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/ratoml.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/ratoml.rs
@@ -82,11 +82,8 @@ impl RatomlTest {
         }
 
         Url::parse(
-            format!(
-                "file://{}",
-                path.into_string().to_owned().replace("C:\\", "/c:/").replace('\\', "/")
-            )
-            .as_str(),
+            format!("file://{}", path.into_string().replace("C:\\", "/c:/").replace('\\', "/"))
+                .as_str(),
         )
         .unwrap()
     }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs
index 3f97952365f..2bebb0c1b97 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs
@@ -202,7 +202,7 @@ impl Project<'_> {
         }
 
         let mut config = Config::new(
-            tmp_dir_path.clone(),
+            tmp_dir_path,
             lsp_types::ClientCapabilities {
                 workspace: Some(lsp_types::WorkspaceClientCapabilities {
                     did_change_watched_files: Some(
@@ -298,8 +298,7 @@ impl Server {
     ) -> Server {
         let (connection, client) = Connection::memory();
 
-        let _thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker)
-            .name("test server".to_owned())
+        let _thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker, "test server")
             .spawn(move || main_loop(config, connection).unwrap())
             .expect("failed to spawn a thread");
 
diff --git a/src/tools/rust-analyzer/crates/span/src/hygiene.rs b/src/tools/rust-analyzer/crates/span/src/hygiene.rs
index b21102f2db7..7bb88ac3658 100644
--- a/src/tools/rust-analyzer/crates/span/src/hygiene.rs
+++ b/src/tools/rust-analyzer/crates/span/src/hygiene.rs
@@ -94,16 +94,11 @@ const _: () = {
         }
     }
     impl zalsa_struct_::Configuration for SyntaxContext {
+        const LOCATION: salsa::plumbing::Location =
+            salsa::plumbing::Location { file: file!(), line: line!() };
         const DEBUG_NAME: &'static str = "SyntaxContextData";
         type Fields<'a> = SyntaxContextData;
         type Struct<'a> = SyntaxContext;
-        fn struct_from_id<'db>(id: salsa::Id) -> Self::Struct<'db> {
-            SyntaxContext::from_salsa_id(id)
-        }
-        fn deref_struct(s: Self::Struct<'_>) -> salsa::Id {
-            s.as_salsa_id()
-                .expect("`SyntaxContext::deref_structs()` called on a root `SyntaxContext`")
-        }
     }
     impl SyntaxContext {
         pub fn ingredient<Db>(db: &Db) -> &zalsa_struct_::IngredientImpl<Self>
@@ -308,7 +303,7 @@ impl SyntaxContext {
 }
 
 #[cfg(feature = "salsa")]
-impl SyntaxContext {
+impl<'db> SyntaxContext {
     const MAX_ID: u32 = salsa::Id::MAX_U32 - 1;
 
     #[inline]
@@ -340,6 +335,60 @@ impl SyntaxContext {
         // SAFETY: This comes from a Salsa ID.
         unsafe { Self::from_u32(id.as_u32()) }
     }
+
+    #[inline]
+    pub fn outer_mark(
+        self,
+        db: &'db dyn salsa::Database,
+    ) -> (Option<crate::MacroCallId>, Transparency) {
+        (self.outer_expn(db), self.outer_transparency(db))
+    }
+
+    #[inline]
+    pub fn normalize_to_macros_2_0(self, db: &'db dyn salsa::Database) -> SyntaxContext {
+        self.opaque(db)
+    }
+
+    #[inline]
+    pub fn normalize_to_macro_rules(self, db: &'db dyn salsa::Database) -> SyntaxContext {
+        self.opaque_and_semitransparent(db)
+    }
+
+    pub fn is_opaque(self, db: &'db dyn salsa::Database) -> bool {
+        !self.is_root() && self.outer_transparency(db).is_opaque()
+    }
+
+    pub fn remove_mark(
+        &mut self,
+        db: &'db dyn salsa::Database,
+    ) -> (Option<crate::MacroCallId>, Transparency) {
+        let data = *self;
+        *self = data.parent(db);
+        (data.outer_expn(db), data.outer_transparency(db))
+    }
+
+    pub fn marks(
+        self,
+        db: &'db dyn salsa::Database,
+    ) -> impl Iterator<Item = (crate::MacroCallId, Transparency)> {
+        let mut marks = self.marks_rev(db).collect::<Vec<_>>();
+        marks.reverse();
+        marks.into_iter()
+    }
+
+    pub fn marks_rev(
+        self,
+        db: &'db dyn salsa::Database,
+    ) -> impl Iterator<Item = (crate::MacroCallId, Transparency)> {
+        std::iter::successors(Some(self), move |&mark| Some(mark.parent(db)))
+            .take_while(|&it| !it.is_root())
+            .map(|ctx| {
+                let mark = ctx.outer_mark(db);
+                // We stop before taking the root expansion, as such we cannot encounter a `None` outer
+                // expansion, as only the ROOT has it.
+                (mark.0.unwrap(), mark.1)
+            })
+    }
 }
 #[cfg(not(feature = "salsa"))]
 #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
diff --git a/src/tools/rust-analyzer/crates/stdx/src/thread.rs b/src/tools/rust-analyzer/crates/stdx/src/thread.rs
index 6c742fecf1b..a34e9e4a655 100644
--- a/src/tools/rust-analyzer/crates/stdx/src/thread.rs
+++ b/src/tools/rust-analyzer/crates/stdx/src/thread.rs
@@ -26,12 +26,12 @@ pub use pool::Pool;
 /// # Panics
 ///
 /// Panics if failed to spawn the thread.
-pub fn spawn<F, T>(intent: ThreadIntent, f: F) -> JoinHandle<T>
+pub fn spawn<F, T>(intent: ThreadIntent, name: String, f: F) -> JoinHandle<T>
 where
     F: (FnOnce() -> T) + Send + 'static,
     T: Send + 'static,
 {
-    Builder::new(intent).spawn(f).expect("failed to spawn thread")
+    Builder::new(intent, name).spawn(f).expect("failed to spawn thread")
 }
 
 pub struct Builder {
@@ -42,13 +42,8 @@ pub struct Builder {
 
 impl Builder {
     #[must_use]
-    pub fn new(intent: ThreadIntent) -> Self {
-        Self { intent, inner: jod_thread::Builder::new(), allow_leak: false }
-    }
-
-    #[must_use]
-    pub fn name(self, name: String) -> Self {
-        Self { inner: self.inner.name(name), ..self }
+    pub fn new(intent: ThreadIntent, name: impl Into<String>) -> Self {
+        Self { intent, inner: jod_thread::Builder::new().name(name.into()), allow_leak: false }
     }
 
     #[must_use]
@@ -56,6 +51,8 @@ impl Builder {
         Self { inner: self.inner.stack_size(size), ..self }
     }
 
+    /// Whether dropping should detach the thread
+    /// instead of joining it.
     #[must_use]
     pub fn allow_leak(self, allow_leak: bool) -> Self {
         Self { allow_leak, ..self }
diff --git a/src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs b/src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs
index 074cd747dac..a8de4db624f 100644
--- a/src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs
+++ b/src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs
@@ -50,10 +50,9 @@ impl Pool {
         let extant_tasks = Arc::new(AtomicUsize::new(0));
 
         let mut handles = Vec::with_capacity(threads);
-        for _ in 0..threads {
-            let handle = Builder::new(INITIAL_INTENT)
+        for idx in 0..threads {
+            let handle = Builder::new(INITIAL_INTENT, format!("Worker{idx}",))
                 .stack_size(STACK_SIZE)
-                .name("Worker".into())
                 .allow_leak(true)
                 .spawn({
                     let extant_tasks = Arc::clone(&extant_tasks);
diff --git a/src/tools/rust-analyzer/crates/syntax/Cargo.toml b/src/tools/rust-analyzer/crates/syntax/Cargo.toml
index 510d44d0091..4c7704803ef 100644
--- a/src/tools/rust-analyzer/crates/syntax/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/syntax/Cargo.toml
@@ -14,7 +14,7 @@ rust-version.workspace = true
 [dependencies]
 either.workspace = true
 itertools.workspace = true
-rowan = "=0.15.15"
+rowan.workspace = true
 rustc-hash.workspace = true
 rustc-literal-escaper.workspace = true
 smol_str.workspace = true
diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram
index a0ae0d68581..10abca7d35d 100644
--- a/src/tools/rust-analyzer/crates/syntax/rust.ungram
+++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram
@@ -133,6 +133,7 @@ Meta =
 
 SourceFile =
   '#shebang'?
+  '#frontmatter'?
   Attr*
   Item*
 
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
index 1243f6418fe..cd9f4dba890 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
@@ -1525,6 +1525,10 @@ impl ast::HasDocComments for SourceFile {}
 impl ast::HasModuleItem for SourceFile {}
 impl SourceFile {
     #[inline]
+    pub fn frontmatter_token(&self) -> Option<SyntaxToken> {
+        support::token(&self.syntax, T![frontmatter])
+    }
+    #[inline]
     pub fn shebang_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![shebang]) }
 }
 pub struct Static {
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
index d608a35effa..596f73e0b10 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
@@ -69,6 +69,9 @@ pub mod ext {
     pub fn expr_todo() -> ast::Expr {
         expr_from_text("todo!()")
     }
+    pub fn expr_underscore() -> ast::Expr {
+        expr_from_text("_")
+    }
     pub fn expr_ty_default(ty: &ast::Type) -> ast::Expr {
         expr_from_text(&format!("{ty}::default()"))
     }
@@ -706,7 +709,7 @@ pub fn wildcard_pat() -> ast::WildcardPat {
 }
 
 pub fn rest_pat() -> ast::RestPat {
-    ast_from_text("fn f(..)")
+    ast_from_text("fn f() { let ..; }")
 }
 
 pub fn literal_pat(lit: &str) -> ast::LiteralPat {
@@ -785,8 +788,8 @@ pub fn record_pat_field(name_ref: ast::NameRef, pat: ast::Pat) -> ast::RecordPat
     ast_from_text(&format!("fn f(S {{ {name_ref}: {pat} }}: ()))"))
 }
 
-pub fn record_pat_field_shorthand(name_ref: ast::NameRef) -> ast::RecordPatField {
-    ast_from_text(&format!("fn f(S {{ {name_ref} }}: ()))"))
+pub fn record_pat_field_shorthand(pat: ast::Pat) -> ast::RecordPatField {
+    ast_from_text(&format!("fn f(S {{ {pat} }}: ()))"))
 }
 
 /// Returns a `IdentPat` if the path has just one segment, a `PathPat` otherwise.
@@ -798,16 +801,38 @@ pub fn path_pat(path: ast::Path) -> ast::Pat {
 }
 
 /// Returns a `Pat` if the path has just one segment, an `OrPat` otherwise.
-pub fn or_pat(pats: impl IntoIterator<Item = ast::Pat>, leading_pipe: bool) -> ast::Pat {
+///
+/// Invariant: `pats` must be length > 1.
+pub fn or_pat(pats: impl IntoIterator<Item = ast::Pat>, leading_pipe: bool) -> ast::OrPat {
     let leading_pipe = if leading_pipe { "| " } else { "" };
     let pats = pats.into_iter().join(" | ");
 
     return from_text(&format!("{leading_pipe}{pats}"));
-    fn from_text(text: &str) -> ast::Pat {
+    fn from_text(text: &str) -> ast::OrPat {
         ast_from_text(&format!("fn f({text}: ())"))
     }
 }
 
+pub fn box_pat(pat: ast::Pat) -> ast::BoxPat {
+    ast_from_text(&format!("fn f(box {pat}: ())"))
+}
+
+pub fn paren_pat(pat: ast::Pat) -> ast::ParenPat {
+    ast_from_text(&format!("fn f(({pat}): ())"))
+}
+
+pub fn range_pat(start: Option<ast::Pat>, end: Option<ast::Pat>) -> ast::RangePat {
+    ast_from_text(&format!(
+        "fn f({}..{}: ())",
+        start.map(|e| e.to_string()).unwrap_or_default(),
+        end.map(|e| e.to_string()).unwrap_or_default()
+    ))
+}
+
+pub fn ref_pat(pat: ast::Pat) -> ast::RefPat {
+    ast_from_text(&format!("fn f(&{pat}: ())"))
+}
+
 pub fn match_arm(pat: ast::Pat, guard: Option<ast::MatchGuard>, expr: ast::Expr) -> ast::MatchArm {
     return match guard {
         Some(guard) => from_text(&format!("{pat} {guard} => {expr}")),
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs
index 1854000d3db..8dee3964d44 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs
@@ -3,7 +3,7 @@ use crate::{
     AstNode, NodeOrToken, SyntaxKind, SyntaxNode, SyntaxToken,
     ast::{
         self, HasArgList, HasGenericArgs, HasGenericParams, HasLoopBody, HasName, HasTypeBounds,
-        HasVisibility, make,
+        HasVisibility, RangeItem, make,
     },
     syntax_editor::SyntaxMappingBuilder,
 };
@@ -107,6 +107,20 @@ impl SyntaxFactory {
         ast
     }
 
+    pub fn use_(&self, visibility: Option<ast::Visibility>, use_tree: ast::UseTree) -> ast::Use {
+        make::use_(visibility, use_tree).clone_for_update()
+    }
+
+    pub fn use_tree(
+        &self,
+        path: ast::Path,
+        use_tree_list: Option<ast::UseTreeList>,
+        alias: Option<ast::Rename>,
+        add_star: bool,
+    ) -> ast::UseTree {
+        make::use_tree(path, use_tree_list, alias, add_star).clone_for_update()
+    }
+
     pub fn path_unqualified(&self, segment: ast::PathSegment) -> ast::Path {
         let ast = make::path_unqualified(segment.clone()).clone_for_update();
 
@@ -254,12 +268,12 @@ impl SyntaxFactory {
         ast
     }
 
-    pub fn record_pat_field_shorthand(&self, name_ref: ast::NameRef) -> ast::RecordPatField {
-        let ast = make::record_pat_field_shorthand(name_ref.clone()).clone_for_update();
+    pub fn record_pat_field_shorthand(&self, pat: ast::Pat) -> ast::RecordPatField {
+        let ast = make::record_pat_field_shorthand(pat.clone()).clone_for_update();
 
         if let Some(mut mapping) = self.mappings() {
             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
-            builder.map_node(name_ref.syntax().clone(), ast.pat().unwrap().syntax().clone());
+            builder.map_node(pat.syntax().clone(), ast.pat().unwrap().syntax().clone());
             builder.finish(&mut mapping);
         }
 
@@ -294,6 +308,76 @@ impl SyntaxFactory {
         make::rest_pat().clone_for_update()
     }
 
+    pub fn or_pat(
+        &self,
+        pats: impl IntoIterator<Item = ast::Pat>,
+        leading_pipe: bool,
+    ) -> ast::OrPat {
+        let (pats, input) = iterator_input(pats);
+        let ast = make::or_pat(pats, leading_pipe).clone_for_update();
+
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+            builder.map_children(input, ast.pats().map(|it| it.syntax().clone()));
+            builder.finish(&mut mapping);
+        }
+
+        ast
+    }
+
+    pub fn box_pat(&self, pat: ast::Pat) -> ast::BoxPat {
+        let ast = make::box_pat(pat.clone()).clone_for_update();
+
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+            builder.map_node(pat.syntax().clone(), ast.pat().unwrap().syntax().clone());
+            builder.finish(&mut mapping);
+        }
+
+        ast
+    }
+
+    pub fn paren_pat(&self, pat: ast::Pat) -> ast::ParenPat {
+        let ast = make::paren_pat(pat.clone()).clone_for_update();
+
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+            builder.map_node(pat.syntax().clone(), ast.pat().unwrap().syntax().clone());
+            builder.finish(&mut mapping);
+        }
+
+        ast
+    }
+
+    pub fn range_pat(&self, start: Option<ast::Pat>, end: Option<ast::Pat>) -> ast::RangePat {
+        let ast = make::range_pat(start.clone(), end.clone()).clone_for_update();
+
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+            if let Some(start) = start {
+                builder.map_node(start.syntax().clone(), ast.start().unwrap().syntax().clone());
+            }
+            if let Some(end) = end {
+                builder.map_node(end.syntax().clone(), ast.end().unwrap().syntax().clone());
+            }
+            builder.finish(&mut mapping);
+        }
+
+        ast
+    }
+
+    pub fn ref_pat(&self, pat: ast::Pat) -> ast::RefPat {
+        let ast = make::ref_pat(pat.clone()).clone_for_update();
+
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+            builder.map_node(pat.syntax().clone(), ast.pat().unwrap().syntax().clone());
+            builder.finish(&mut mapping);
+        }
+
+        ast
+    }
+
     pub fn block_expr(
         &self,
         statements: impl IntoIterator<Item = ast::Stmt>,
@@ -673,6 +757,38 @@ impl SyntaxFactory {
         ast
     }
 
+    pub fn let_else_stmt(
+        &self,
+        pattern: ast::Pat,
+        ty: Option<ast::Type>,
+        initializer: ast::Expr,
+        diverging: ast::BlockExpr,
+    ) -> ast::LetStmt {
+        let ast = make::let_else_stmt(
+            pattern.clone(),
+            ty.clone(),
+            initializer.clone(),
+            diverging.clone(),
+        )
+        .clone_for_update();
+
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+            builder.map_node(pattern.syntax().clone(), ast.pat().unwrap().syntax().clone());
+            if let Some(input) = ty {
+                builder.map_node(input.syntax().clone(), ast.ty().unwrap().syntax().clone());
+            }
+            builder.map_node(
+                initializer.syntax().clone(),
+                ast.initializer().unwrap().syntax().clone(),
+            );
+            builder.map_node(diverging.syntax().clone(), ast.let_else().unwrap().syntax().clone());
+            builder.finish(&mut mapping);
+        }
+
+        ast
+    }
+
     pub fn type_arg(&self, ty: ast::Type) -> ast::TypeArg {
         let ast = make::type_arg(ty.clone()).clone_for_update();
 
diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs
index 58200189c46..31caf618be9 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs
@@ -20,6 +20,7 @@ mod edit_algo;
 mod edits;
 mod mapping;
 
+pub use edits::Removable;
 pub use mapping::{SyntaxMapping, SyntaxMappingBuilder};
 
 #[derive(Debug)]
diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs
index 6a9c88b55d7..01c1f0d49bf 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs
@@ -391,7 +391,7 @@ fn report_intersecting_changes(
 fn to_owning_node(element: &SyntaxElement) -> SyntaxNode {
     match element {
         SyntaxElement::Node(node) => node.clone(),
-        SyntaxElement::Token(token) => token.parent().unwrap().clone(),
+        SyntaxElement::Token(token) => token.parent().unwrap(),
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs
index 350cb3e2544..d66ea8aa28c 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edits.rs
@@ -1,7 +1,8 @@
 //! Structural editing for ast using `SyntaxEditor`
 
 use crate::{
-    Direction, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, T,
+    AstToken, Direction, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, T,
+    algo::neighbor,
     ast::{
         self, AstNode, Fn, GenericParam, HasGenericParams, HasName, edit::IndentLevel, make,
         syntax_factory::SyntaxFactory,
@@ -143,6 +144,53 @@ fn normalize_ws_between_braces(editor: &mut SyntaxEditor, node: &SyntaxNode) ->
     Some(())
 }
 
+pub trait Removable: AstNode {
+    fn remove(&self, editor: &mut SyntaxEditor);
+}
+
+impl Removable for ast::Use {
+    fn remove(&self, editor: &mut SyntaxEditor) {
+        let make = SyntaxFactory::without_mappings();
+
+        let next_ws = self
+            .syntax()
+            .next_sibling_or_token()
+            .and_then(|it| it.into_token())
+            .and_then(ast::Whitespace::cast);
+        if let Some(next_ws) = next_ws {
+            let ws_text = next_ws.syntax().text();
+            if let Some(rest) = ws_text.strip_prefix('\n') {
+                if rest.is_empty() {
+                    editor.delete(next_ws.syntax());
+                } else {
+                    editor.replace(next_ws.syntax(), make.whitespace(rest));
+                }
+            }
+        }
+
+        editor.delete(self.syntax());
+    }
+}
+
+impl Removable for ast::UseTree {
+    fn remove(&self, editor: &mut SyntaxEditor) {
+        for dir in [Direction::Next, Direction::Prev] {
+            if let Some(next_use_tree) = neighbor(self, dir) {
+                let separators = self
+                    .syntax()
+                    .siblings_with_tokens(dir)
+                    .skip(1)
+                    .take_while(|it| it.as_node() != Some(next_use_tree.syntax()));
+                for sep in separators {
+                    editor.delete(sep);
+                }
+                break;
+            }
+        }
+        editor.delete(self.syntax());
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use parser::Edition;
diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs
index 2f379d419e8..f6ca5ab6c8c 100644
--- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs
@@ -353,7 +353,7 @@ impl ChangeFixture {
                 )]),
                 CrateOrigin::Local { repo: None, name: None },
                 true,
-                proc_macro_cwd.clone(),
+                proc_macro_cwd,
                 crate_ws_data,
             );
             proc_macros.insert(proc_macros_crate, Ok(proc_macro));
diff --git a/src/tools/rust-analyzer/crates/tt/src/lib.rs b/src/tools/rust-analyzer/crates/tt/src/lib.rs
index 36ccb67f3b8..1dbc07c0929 100644
--- a/src/tools/rust-analyzer/crates/tt/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/tt/src/lib.rs
@@ -728,9 +728,9 @@ fn print_debug_subtree<S: fmt::Debug>(
     };
 
     write!(f, "{align}SUBTREE {delim} ",)?;
-    write!(f, "{:#?}", open)?;
+    write!(f, "{open:#?}")?;
     write!(f, " ")?;
-    write!(f, "{:#?}", close)?;
+    write!(f, "{close:#?}")?;
     for child in iter {
         writeln!(f)?;
         print_debug_token(f, level + 1, child)?;
@@ -855,7 +855,7 @@ impl<S> fmt::Display for Literal<S> {
             }
         }?;
         if let Some(suffix) = &self.suffix {
-            write!(f, "{}", suffix)?;
+            write!(f, "{suffix}")?;
         }
         Ok(())
     }
diff --git a/src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs b/src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs
index e918fd0887d..a03337dbc51 100644
--- a/src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs
@@ -38,8 +38,7 @@ impl loader::Handle for NotifyHandle {
     fn spawn(sender: loader::Sender) -> NotifyHandle {
         let actor = NotifyActor::new(sender);
         let (sender, receiver) = unbounded::<Message>();
-        let thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker)
-            .name("VfsLoader".to_owned())
+        let thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker, "VfsLoader")
             .spawn(move || actor.run(receiver))
             .expect("failed to spawn thread");
         NotifyHandle { sender, _thread: thread }
diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version
index 09c127f6bcd..90e4d65bf96 100644
--- a/src/tools/rust-analyzer/rust-version
+++ b/src/tools/rust-analyzer/rust-version
@@ -1 +1 @@
-21079f53a359d9fc82668d4175d49dafdb600563
+6e23095adf9209614a45f7f75fea36dad7b92afb
diff --git a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs
index 82df78c1a89..824b38fc872 100644
--- a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs
+++ b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs
@@ -414,7 +414,7 @@ fn generate_nodes(kinds: KindsSrc, grammar: &AstSrc) -> String {
         .map(|kind| to_pascal_case(kind))
         .filter(|name| !defined_nodes.iter().any(|&it| it == name))
     {
-        eprintln!("Warning: node {} not defined in AST source", node);
+        eprintln!("Warning: node {node} not defined in AST source");
         drop(node);
     }
 
@@ -670,6 +670,7 @@ fn generate_syntax_kinds(grammar: KindsSrc) -> String {
             [ident] => { $crate::SyntaxKind::IDENT };
             [string] => { $crate::SyntaxKind::STRING };
             [shebang] => { $crate::SyntaxKind::SHEBANG };
+            [frontmatter] => { $crate::SyntaxKind::FRONTMATTER };
         }
 
         impl ::core::marker::Copy for SyntaxKind {}
diff --git a/src/tools/rust-analyzer/xtask/src/codegen/parser_inline_tests.rs b/src/tools/rust-analyzer/xtask/src/codegen/parser_inline_tests.rs
index f3b786b9d86..ae53771fe8e 100644
--- a/src/tools/rust-analyzer/xtask/src/codegen/parser_inline_tests.rs
+++ b/src/tools/rust-analyzer/xtask/src/codegen/parser_inline_tests.rs
@@ -159,7 +159,7 @@ fn collect_tests(s: &str) -> Vec<Test> {
                 (name.to_owned(), Some(edition.to_owned()))
             }
             [name] => (name.to_owned(), None),
-            _ => panic!("invalid test name: {:?}", name),
+            _ => panic!("invalid test name: {name:?}"),
         };
         let text: String = edition
             .as_ref()
@@ -212,7 +212,7 @@ fn existing_tests(dir: &Path, ok: TestKind) -> Result<HashMap<String, (PathBuf,
                 text.lines().next().and_then(|it| it.strip_prefix("// ")).map(ToOwned::to_owned);
             let test = Test { name: name.clone(), text, kind: ok, edition };
             if let Some(old) = res.insert(name, (path, test)) {
-                println!("Duplicate test: {:?}", old);
+                println!("Duplicate test: {old:?}");
             }
         }
     }
diff --git a/src/tools/rust-analyzer/xtask/src/dist.rs b/src/tools/rust-analyzer/xtask/src/dist.rs
index b3d6f06b073..dbfecdbe112 100644
--- a/src/tools/rust-analyzer/xtask/src/dist.rs
+++ b/src/tools/rust-analyzer/xtask/src/dist.rs
@@ -1,9 +1,6 @@
 use anyhow::Context;
 use flate2::{Compression, write::GzEncoder};
-use std::env::consts::EXE_EXTENSION;
-use std::ffi::OsStr;
 use std::{
-    env,
     fs::File,
     io::{self, BufWriter},
     path::{Path, PathBuf},
@@ -12,11 +9,11 @@ use time::OffsetDateTime;
 use xshell::{Cmd, Shell, cmd};
 use zip::{DateTime, ZipWriter, write::SimpleFileOptions};
 
-use crate::flags::PgoTrainingCrate;
 use crate::{
     date_iso,
-    flags::{self, Malloc},
+    flags::{self, Malloc, PgoTrainingCrate},
     project_root,
+    util::detect_target,
 };
 
 const VERSION_STABLE: &str = "0.3";
@@ -28,7 +25,7 @@ impl flags::Dist {
         let stable = sh.var("GITHUB_REF").unwrap_or_default().as_str() == "refs/heads/release";
 
         let project_root = project_root();
-        let target = Target::get(&project_root);
+        let target = Target::get(&project_root, sh);
         let allocator = self.allocator();
         let dist = project_root.join("dist");
         sh.remove_path(&dist)?;
@@ -113,9 +110,9 @@ fn dist_server(
     let command = if linux_target && zig { "zigbuild" } else { "build" };
 
     let pgo_profile = if let Some(train_crate) = pgo {
-        Some(gather_pgo_profile(
+        Some(crate::pgo::gather_pgo_profile(
             sh,
-            build_command(sh, command, &target_name, features),
+            crate::pgo::build_command(sh, command, &target_name, features),
             &target_name,
             train_crate,
         )?)
@@ -151,85 +148,6 @@ fn build_command<'a>(
     )
 }
 
-/// Decorates `ra_build_cmd` to add PGO instrumentation, and then runs the PGO instrumented
-/// Rust Analyzer on itself to gather a PGO profile.
-fn gather_pgo_profile<'a>(
-    sh: &'a Shell,
-    ra_build_cmd: Cmd<'a>,
-    target: &str,
-    train_crate: PgoTrainingCrate,
-) -> anyhow::Result<PathBuf> {
-    let pgo_dir = std::path::absolute("rust-analyzer-pgo")?;
-    // Clear out any stale profiles
-    if pgo_dir.is_dir() {
-        std::fs::remove_dir_all(&pgo_dir)?;
-    }
-    std::fs::create_dir_all(&pgo_dir)?;
-
-    // Figure out a path to `llvm-profdata`
-    let target_libdir = cmd!(sh, "rustc --print=target-libdir")
-        .read()
-        .context("cannot resolve target-libdir from rustc")?;
-    let target_bindir = PathBuf::from(target_libdir).parent().unwrap().join("bin");
-    let llvm_profdata = target_bindir.join("llvm-profdata").with_extension(EXE_EXTENSION);
-
-    // Build RA with PGO instrumentation
-    let cmd_gather =
-        ra_build_cmd.env("RUSTFLAGS", format!("-Cprofile-generate={}", pgo_dir.to_str().unwrap()));
-    cmd_gather.run().context("cannot build rust-analyzer with PGO instrumentation")?;
-
-    let (train_path, label) = match &train_crate {
-        PgoTrainingCrate::RustAnalyzer => (PathBuf::from("."), "itself"),
-        PgoTrainingCrate::GitHub(repo) => {
-            (download_crate_for_training(sh, &pgo_dir, repo)?, repo.as_str())
-        }
-    };
-
-    // Run RA either on itself or on a downloaded crate
-    eprintln!("Training RA on {label}...");
-    cmd!(
-        sh,
-        "target/{target}/release/rust-analyzer analysis-stats -q --run-all-ide-things {train_path}"
-    )
-    .run()
-    .context("cannot generate PGO profiles")?;
-
-    // Merge profiles into a single file
-    let merged_profile = pgo_dir.join("merged.profdata");
-    let profile_files = std::fs::read_dir(pgo_dir)?.filter_map(|entry| {
-        let entry = entry.ok()?;
-        if entry.path().extension() == Some(OsStr::new("profraw")) {
-            Some(entry.path().to_str().unwrap().to_owned())
-        } else {
-            None
-        }
-    });
-    cmd!(sh, "{llvm_profdata} merge {profile_files...} -o {merged_profile}").run().context(
-        "cannot merge PGO profiles. Do you have the rustup `llvm-tools` component installed?",
-    )?;
-
-    Ok(merged_profile)
-}
-
-/// Downloads a crate from GitHub, stores it into `pgo_dir` and returns a path to it.
-fn download_crate_for_training(sh: &Shell, pgo_dir: &Path, repo: &str) -> anyhow::Result<PathBuf> {
-    let mut it = repo.splitn(2, '@');
-    let repo = it.next().unwrap();
-    let revision = it.next();
-
-    // FIXME: switch to `--revision` here around 2035 or so
-    let revision =
-        if let Some(revision) = revision { &["--branch", revision] as &[&str] } else { &[] };
-
-    let normalized_path = repo.replace("/", "-");
-    let target_path = pgo_dir.join(normalized_path);
-    cmd!(sh, "git clone --depth 1 https://github.com/{repo} {revision...} {target_path}")
-        .run()
-        .with_context(|| "cannot download PGO training crate from {repo}")?;
-
-    Ok(target_path)
-}
-
 fn gzip(src_path: &Path, dest_path: &Path) -> anyhow::Result<()> {
     let mut encoder = GzEncoder::new(File::create(dest_path)?, Compression::best());
     let mut input = io::BufReader::new(File::open(src_path)?);
@@ -283,21 +201,8 @@ struct Target {
 }
 
 impl Target {
-    fn get(project_root: &Path) -> Self {
-        let name = match env::var("RA_TARGET") {
-            Ok(target) => target,
-            _ => {
-                if cfg!(target_os = "linux") {
-                    "x86_64-unknown-linux-gnu".to_owned()
-                } else if cfg!(target_os = "windows") {
-                    "x86_64-pc-windows-msvc".to_owned()
-                } else if cfg!(target_os = "macos") {
-                    "x86_64-apple-darwin".to_owned()
-                } else {
-                    panic!("Unsupported OS, maybe try setting RA_TARGET")
-                }
-            }
-        };
+    fn get(project_root: &Path, sh: &Shell) -> Self {
+        let name = detect_target(sh);
         let (name, libc_suffix) = match name.split_once('.') {
             Some((l, r)) => (l.to_owned(), Some(r.to_owned())),
             None => (name, None),
diff --git a/src/tools/rust-analyzer/xtask/src/flags.rs b/src/tools/rust-analyzer/xtask/src/flags.rs
index 700806d178c..2fd471b35c7 100644
--- a/src/tools/rust-analyzer/xtask/src/flags.rs
+++ b/src/tools/rust-analyzer/xtask/src/flags.rs
@@ -4,6 +4,25 @@ use std::{fmt, str::FromStr};
 
 use crate::install::{ClientOpt, ProcMacroServerOpt, ServerOpt};
 
+#[derive(Debug, Clone)]
+pub enum PgoTrainingCrate {
+    // Use RA's own sources for PGO training
+    RustAnalyzer,
+    // Download a Rust crate from `https://github.com/{0}` and use it for PGO training.
+    GitHub(String),
+}
+
+impl FromStr for PgoTrainingCrate {
+    type Err = String;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        match s {
+            "rust-analyzer" => Ok(Self::RustAnalyzer),
+            url => Ok(Self::GitHub(url.to_owned())),
+        }
+    }
+}
+
 xflags::xflags! {
     src "./src/flags.rs"
 
@@ -29,6 +48,9 @@ xflags::xflags! {
 
             /// build in release with debug info set to 2.
             optional --dev-rel
+
+            /// Apply PGO optimizations
+            optional --pgo pgo: PgoTrainingCrate
         }
 
         cmd fuzz-tests {}
@@ -110,17 +132,15 @@ pub enum XtaskCmd {
 }
 
 #[derive(Debug)]
-pub struct Tidy {}
-
-#[derive(Debug)]
 pub struct Install {
     pub client: bool,
     pub code_bin: Option<String>,
     pub server: bool,
-    pub proc_macro_server: bool,
     pub mimalloc: bool,
     pub jemalloc: bool,
+    pub proc_macro_server: bool,
     pub dev_rel: bool,
+    pub pgo: Option<PgoTrainingCrate>,
 }
 
 #[derive(Debug)]
@@ -144,25 +164,6 @@ pub struct RustcPush {
 }
 
 #[derive(Debug)]
-pub enum PgoTrainingCrate {
-    // Use RA's own sources for PGO training
-    RustAnalyzer,
-    // Download a Rust crate from `https://github.com/{0}` and use it for PGO training.
-    GitHub(String),
-}
-
-impl FromStr for PgoTrainingCrate {
-    type Err = String;
-
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        match s {
-            "rust-analyzer" => Ok(Self::RustAnalyzer),
-            url => Ok(Self::GitHub(url.to_owned())),
-        }
-    }
-}
-
-#[derive(Debug)]
 pub struct Dist {
     pub mimalloc: bool,
     pub jemalloc: bool,
@@ -195,6 +196,9 @@ pub struct Codegen {
     pub check: bool,
 }
 
+#[derive(Debug)]
+pub struct Tidy;
+
 impl Xtask {
     #[allow(dead_code)]
     pub fn from_env_or_exit() -> Self {
@@ -324,7 +328,7 @@ impl Install {
         } else {
             Malloc::System
         };
-        Some(ServerOpt { malloc, dev_rel: self.dev_rel })
+        Some(ServerOpt { malloc, dev_rel: self.dev_rel, pgo: self.pgo.clone() })
     }
     pub(crate) fn proc_macro_server(&self) -> Option<ProcMacroServerOpt> {
         if !self.proc_macro_server {
diff --git a/src/tools/rust-analyzer/xtask/src/install.rs b/src/tools/rust-analyzer/xtask/src/install.rs
index 4e2093f0691..f0cc445dfa2 100644
--- a/src/tools/rust-analyzer/xtask/src/install.rs
+++ b/src/tools/rust-analyzer/xtask/src/install.rs
@@ -5,7 +5,10 @@ use std::{env, path::PathBuf, str};
 use anyhow::{Context, bail, format_err};
 use xshell::{Shell, cmd};
 
-use crate::flags::{self, Malloc};
+use crate::{
+    flags::{self, Malloc, PgoTrainingCrate},
+    util::detect_target,
+};
 
 impl flags::Install {
     pub(crate) fn run(self, sh: &Shell) -> anyhow::Result<()> {
@@ -35,6 +38,7 @@ const VS_CODES: &[&str] = &["code", "code-exploration", "code-insiders", "codium
 pub(crate) struct ServerOpt {
     pub(crate) malloc: Malloc,
     pub(crate) dev_rel: bool,
+    pub(crate) pgo: Option<PgoTrainingCrate>,
 }
 
 pub(crate) struct ProcMacroServerOpt {
@@ -135,21 +139,33 @@ fn install_server(sh: &Shell, opts: ServerOpt) -> anyhow::Result<()> {
     let features = opts.malloc.to_features();
     let profile = if opts.dev_rel { "dev-rel" } else { "release" };
 
-    let cmd = cmd!(
+    let mut install_cmd = cmd!(
         sh,
         "cargo install --path crates/rust-analyzer --profile={profile} --locked --force --features force-always-assert {features...}"
     );
-    cmd.run()?;
+
+    if let Some(train_crate) = opts.pgo {
+        let build_cmd = cmd!(
+            sh,
+            "cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --profile={profile} --locked --features force-always-assert {features...}"
+        );
+
+        let target = detect_target(sh);
+        let profile = crate::pgo::gather_pgo_profile(sh, build_cmd, &target, train_crate)?;
+        install_cmd = crate::pgo::apply_pgo_to_cmd(install_cmd, &profile);
+    }
+
+    install_cmd.run()?;
     Ok(())
 }
 
 fn install_proc_macro_server(sh: &Shell, opts: ProcMacroServerOpt) -> anyhow::Result<()> {
     let profile = if opts.dev_rel { "dev-rel" } else { "release" };
 
-    let cmd = cmd!(
+    cmd!(
         sh,
         "cargo +nightly install --path crates/proc-macro-srv-cli --profile={profile} --locked --force --features sysroot-abi"
-    );
-    cmd.run()?;
+    ).run()?;
+
     Ok(())
 }
diff --git a/src/tools/rust-analyzer/xtask/src/main.rs b/src/tools/rust-analyzer/xtask/src/main.rs
index 52ea896c734..aaa8d0e1d4d 100644
--- a/src/tools/rust-analyzer/xtask/src/main.rs
+++ b/src/tools/rust-analyzer/xtask/src/main.rs
@@ -22,6 +22,7 @@ mod codegen;
 mod dist;
 mod install;
 mod metrics;
+mod pgo;
 mod publish;
 mod release;
 mod tidy;
diff --git a/src/tools/rust-analyzer/xtask/src/pgo.rs b/src/tools/rust-analyzer/xtask/src/pgo.rs
new file mode 100644
index 00000000000..7f7b3311d96
--- /dev/null
+++ b/src/tools/rust-analyzer/xtask/src/pgo.rs
@@ -0,0 +1,105 @@
+//! PGO (Profile-Guided Optimization) utilities.
+
+use anyhow::Context;
+use std::env::consts::EXE_EXTENSION;
+use std::ffi::OsStr;
+use std::path::{Path, PathBuf};
+use xshell::{Cmd, Shell, cmd};
+
+use crate::flags::PgoTrainingCrate;
+
+/// Decorates `ra_build_cmd` to add PGO instrumentation, and then runs the PGO instrumented
+/// Rust Analyzer on itself to gather a PGO profile.
+pub(crate) fn gather_pgo_profile<'a>(
+    sh: &'a Shell,
+    ra_build_cmd: Cmd<'a>,
+    target: &str,
+    train_crate: PgoTrainingCrate,
+) -> anyhow::Result<PathBuf> {
+    let pgo_dir = std::path::absolute("rust-analyzer-pgo")?;
+    // Clear out any stale profiles
+    if pgo_dir.is_dir() {
+        std::fs::remove_dir_all(&pgo_dir)?;
+    }
+    std::fs::create_dir_all(&pgo_dir)?;
+
+    // Figure out a path to `llvm-profdata`
+    let target_libdir = cmd!(sh, "rustc --print=target-libdir")
+        .read()
+        .context("cannot resolve target-libdir from rustc")?;
+    let target_bindir = PathBuf::from(target_libdir).parent().unwrap().join("bin");
+    let llvm_profdata = target_bindir.join("llvm-profdata").with_extension(EXE_EXTENSION);
+
+    // Build RA with PGO instrumentation
+    let cmd_gather =
+        ra_build_cmd.env("RUSTFLAGS", format!("-Cprofile-generate={}", pgo_dir.to_str().unwrap()));
+    cmd_gather.run().context("cannot build rust-analyzer with PGO instrumentation")?;
+
+    let (train_path, label) = match &train_crate {
+        PgoTrainingCrate::RustAnalyzer => (PathBuf::from("."), "itself"),
+        PgoTrainingCrate::GitHub(repo) => {
+            (download_crate_for_training(sh, &pgo_dir, repo)?, repo.as_str())
+        }
+    };
+
+    // Run RA either on itself or on a downloaded crate
+    eprintln!("Training RA on {label}...");
+    cmd!(
+        sh,
+        "target/{target}/release/rust-analyzer analysis-stats -q --run-all-ide-things {train_path}"
+    )
+    .run()
+    .context("cannot generate PGO profiles")?;
+
+    // Merge profiles into a single file
+    let merged_profile = pgo_dir.join("merged.profdata");
+    let profile_files = std::fs::read_dir(pgo_dir)?.filter_map(|entry| {
+        let entry = entry.ok()?;
+        if entry.path().extension() == Some(OsStr::new("profraw")) {
+            Some(entry.path().to_str().unwrap().to_owned())
+        } else {
+            None
+        }
+    });
+    cmd!(sh, "{llvm_profdata} merge {profile_files...} -o {merged_profile}").run().context(
+        "cannot merge PGO profiles. Do you have the rustup `llvm-tools` component installed?",
+    )?;
+
+    Ok(merged_profile)
+}
+
+/// Downloads a crate from GitHub, stores it into `pgo_dir` and returns a path to it.
+fn download_crate_for_training(sh: &Shell, pgo_dir: &Path, repo: &str) -> anyhow::Result<PathBuf> {
+    let mut it = repo.splitn(2, '@');
+    let repo = it.next().unwrap();
+    let revision = it.next();
+
+    // FIXME: switch to `--revision` here around 2035 or so
+    let revision =
+        if let Some(revision) = revision { &["--branch", revision] as &[&str] } else { &[] };
+
+    let normalized_path = repo.replace("/", "-");
+    let target_path = pgo_dir.join(normalized_path);
+    cmd!(sh, "git clone --depth 1 https://github.com/{repo} {revision...} {target_path}")
+        .run()
+        .with_context(|| "cannot download PGO training crate from {repo}")?;
+
+    Ok(target_path)
+}
+
+/// Helper function to create a build command for rust-analyzer
+pub(crate) fn build_command<'a>(
+    sh: &'a Shell,
+    command: &str,
+    target_name: &str,
+    features: &[&str],
+) -> Cmd<'a> {
+    cmd!(
+        sh,
+        "cargo {command} --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --target {target_name} {features...} --release"
+    )
+}
+
+pub(crate) fn apply_pgo_to_cmd<'a>(cmd: Cmd<'a>, profile_path: &Path) -> Cmd<'a> {
+    cmd.env("RUSTFLAGS", format!("-Cprofile-use={}", profile_path.to_str().unwrap()))
+}
diff --git a/src/tools/rust-analyzer/xtask/src/util.rs b/src/tools/rust-analyzer/xtask/src/util.rs
index 39f52938c8c..e5404d57171 100644
--- a/src/tools/rust-analyzer/xtask/src/util.rs
+++ b/src/tools/rust-analyzer/xtask/src/util.rs
@@ -1,5 +1,7 @@
 use std::path::{Path, PathBuf};
 
+use xshell::{Shell, cmd};
+
 pub(crate) fn list_rust_files(dir: &Path) -> Vec<PathBuf> {
     let mut res = list_files(dir);
     res.retain(|it| {
@@ -29,3 +31,13 @@ pub(crate) fn list_files(dir: &Path) -> Vec<PathBuf> {
     }
     res
 }
+
+pub(crate) fn detect_target(sh: &Shell) -> String {
+    match std::env::var("RA_TARGET") {
+        Ok(target) => target,
+        _ => match cmd!(sh, "rustc --print=host-tuple").read() {
+            Ok(target) => target,
+            Err(e) => panic!("Failed to detect target: {e}\nPlease set RA_TARGET explicitly"),
+        },
+    }
+}
diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock
index fb584103df5..3b5b31bed14 100644
--- a/src/tools/rustbook/Cargo.lock
+++ b/src/tools/rustbook/Cargo.lock
@@ -19,13 +19,13 @@ dependencies = [
 
 [[package]]
 name = "ammonia"
-version = "4.0.0"
+version = "4.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ab99eae5ee58501ab236beb6f20f6ca39be615267b014899c89b2f0bc18a459"
+checksum = "3ada2ee439075a3e70b6992fce18ac4e407cd05aea9ca3f75d2c0b0c20bbb364"
 dependencies = [
+ "cssparser",
  "html5ever",
  "maplit",
- "once_cell",
  "tendril",
  "url",
 ]
@@ -97,9 +97,9 @@ dependencies = [
 
 [[package]]
 name = "anyhow"
-version = "1.0.97"
+version = "1.0.98"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
+checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
 
 [[package]]
 name = "autocfg"
@@ -156,9 +156,9 @@ checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
 
 [[package]]
 name = "cc"
-version = "1.2.19"
+version = "1.2.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362"
+checksum = "8691782945451c1c383942c4874dbe63814f61cb57ef773cda2972682b7bb3c0"
 dependencies = [
  "shlex",
 ]
@@ -171,9 +171,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "chrono"
-version = "0.4.40"
+version = "0.4.41"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
+checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
 dependencies = [
  "android-tzdata",
  "iana-time-zone",
@@ -185,9 +185,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.5.36"
+version = "4.5.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2df961d8c8a0d08aa9945718ccf584145eee3f3aa06cddbeac12933781102e04"
+checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -195,9 +195,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.36"
+version = "4.5.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "132dbda40fb6753878316a489d5a1242a8ef2f0d9e47ba01c951ea8aa7d013a5"
+checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2"
 dependencies = [
  "anstream",
  "anstyle",
@@ -208,9 +208,9 @@ dependencies = [
 
 [[package]]
 name = "clap_complete"
-version = "4.5.47"
+version = "4.5.48"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c06f5378ea264ad4f82bbc826628b5aad714a75abf6ece087e923010eb937fb6"
+checksum = "be8c97f3a6f02b9e24cadc12aaba75201d18754b53ea0a9d99642f806ccdb4c9"
 dependencies = [
  "clap",
 ]
@@ -274,6 +274,29 @@ dependencies = [
 ]
 
 [[package]]
+name = "cssparser"
+version = "0.35.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e901edd733a1472f944a45116df3f846f54d37e67e68640ac8bb69689aca2aa"
+dependencies = [
+ "cssparser-macros",
+ "dtoa-short",
+ "itoa",
+ "phf",
+ "smallvec",
+]
+
+[[package]]
+name = "cssparser-macros"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
+dependencies = [
+ "quote",
+ "syn",
+]
+
+[[package]]
 name = "darling"
 version = "0.20.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -390,6 +413,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
 
 [[package]]
+name = "dtoa"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04"
+
+[[package]]
+name = "dtoa-short"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87"
+dependencies = [
+ "dtoa",
+]
+
+[[package]]
 name = "elasticlunr-rs"
 version = "3.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -537,9 +575,9 @@ dependencies = [
 
 [[package]]
 name = "hashbrown"
-version = "0.15.2"
+version = "0.15.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
+checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
 
 [[package]]
 name = "heck"
@@ -555,16 +593,14 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
 
 [[package]]
 name = "html5ever"
-version = "0.27.0"
+version = "0.31.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c13771afe0e6e846f1e67d038d4cb29998a6779f93c809212e4e9c32efd244d4"
+checksum = "953cbbe631aae7fc0a112702ad5d3aaf09da38beaf45ea84610d6e1c358f569c"
 dependencies = [
  "log",
  "mac",
  "markup5ever",
- "proc-macro2",
- "quote",
- "syn",
+ "match_token",
 ]
 
 [[package]]
@@ -775,9 +811,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
 
 [[package]]
 name = "jiff"
-version = "0.2.6"
+version = "0.2.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f33145a5cbea837164362c7bd596106eb7c5198f97d1ba6f6ebb3223952e488"
+checksum = "d07d8d955d798e7a4d6f9c58cd1f1916e790b42b092758a9ef6e16fef9f1b3fd"
 dependencies = [
  "jiff-static",
  "log",
@@ -788,9 +824,9 @@ dependencies = [
 
 [[package]]
 name = "jiff-static"
-version = "0.2.6"
+version = "0.2.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43ce13c40ec6956157a3635d97a1ee2df323b263f09ea14165131289cb0f5c19"
+checksum = "f244cfe006d98d26f859c7abd1318d85327e1882dc9cef80f62daeeb0adcf300"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -815,9 +851,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
 
 [[package]]
 name = "libc"
-version = "0.2.171"
+version = "0.2.172"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
+checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
 
 [[package]]
 name = "libdbus-sys"
@@ -880,23 +916,31 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
 
 [[package]]
 name = "markup5ever"
-version = "0.12.1"
+version = "0.16.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "16ce3abbeba692c8b8441d036ef91aea6df8da2c6b6e21c7e14d3c18e526be45"
+checksum = "d0a8096766c229e8c88a3900c9b44b7e06aa7f7343cc229158c3e58ef8f9973a"
 dependencies = [
  "log",
- "phf",
- "phf_codegen",
- "string_cache",
- "string_cache_codegen",
  "tendril",
+ "web_atoms",
+]
+
+[[package]]
+name = "match_token"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
 name = "mdbook"
-version = "0.4.48"
+version = "0.4.49"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b6fbb4ac2d9fd7aa987c3510309ea3c80004a968d063c42f0d34fea070817c1"
+checksum = "d1daacee059634081dee4250d2814763a365b92dfe14bfdef964bc27835209d4"
 dependencies = [
  "ammonia",
  "anyhow",
@@ -971,7 +1015,7 @@ dependencies = [
  "pulldown-cmark-to-cmark 19.0.1",
  "serde_json",
  "thiserror 1.0.69",
- "toml 0.8.20",
+ "toml 0.8.22",
 ]
 
 [[package]]
@@ -1154,6 +1198,7 @@ version = "0.11.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
 dependencies = [
+ "phf_macros",
  "phf_shared",
 ]
 
@@ -1178,6 +1223,19 @@ dependencies = [
 ]
 
 [[package]]
+name = "phf_macros"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216"
+dependencies = [
+ "phf_generator",
+ "phf_shared",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
 name = "phf_shared"
 version = "0.11.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1224,9 +1282,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.94"
+version = "1.0.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
 dependencies = [
  "unicode-ident",
 ]
@@ -1327,9 +1385,9 @@ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
 
 [[package]]
 name = "redox_syscall"
-version = "0.5.11"
+version = "0.5.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3"
+checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af"
 dependencies = [
  "bitflags 2.9.0",
 ]
@@ -1377,9 +1435,9 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "1.0.5"
+version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf"
+checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
 dependencies = [
  "bitflags 2.9.0",
  "errno",
@@ -1464,9 +1522,9 @@ dependencies = [
 
 [[package]]
 name = "sha2"
-version = "0.10.8"
+version = "0.10.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
+checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
 dependencies = [
  "cfg-if",
  "cpufeatures",
@@ -1530,9 +1588,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
 
 [[package]]
 name = "syn"
-version = "2.0.100"
+version = "2.0.101"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
+checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1541,9 +1599,9 @@ dependencies = [
 
 [[package]]
 name = "synstructure"
-version = "0.13.1"
+version = "0.13.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
+checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1671,9 +1729,9 @@ dependencies = [
 
 [[package]]
 name = "toml"
-version = "0.8.20"
+version = "0.8.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148"
+checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae"
 dependencies = [
  "serde",
  "serde_spanned",
@@ -1683,27 +1741,34 @@ dependencies = [
 
 [[package]]
 name = "toml_datetime"
-version = "0.6.8"
+version = "0.6.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
+checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3"
 dependencies = [
  "serde",
 ]
 
 [[package]]
 name = "toml_edit"
-version = "0.22.24"
+version = "0.22.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474"
+checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e"
 dependencies = [
  "indexmap",
  "serde",
  "serde_spanned",
  "toml_datetime",
+ "toml_write",
  "winnow",
 ]
 
 [[package]]
+name = "toml_write"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076"
+
+[[package]]
 name = "topological-sort"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1858,6 +1923,18 @@ dependencies = [
 ]
 
 [[package]]
+name = "web_atoms"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08bcbdcad8fb2e316072ba6bbe09419afdb550285668ac2534f4230a6f2da0ee"
+dependencies = [
+ "phf",
+ "phf_codegen",
+ "string_cache",
+ "string_cache_codegen",
+]
+
+[[package]]
 name = "winapi"
 version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2022,9 +2099,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
 
 [[package]]
 name = "winnow"
-version = "0.7.6"
+version = "0.7.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10"
+checksum = "d9fb597c990f03753e08d3c29efbfcf2019a003b4bf4ba19225c158e1549f0f3"
 dependencies = [
  "memchr",
 ]
diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml
index a0b220c3557..10fde31306d 100644
--- a/src/tools/rustbook/Cargo.toml
+++ b/src/tools/rustbook/Cargo.toml
@@ -15,6 +15,6 @@ mdbook-i18n-helpers = "0.3.3"
 mdbook-spec = { path = "../../doc/reference/mdbook-spec" }
 
 [dependencies.mdbook]
-version = "0.4.48"
+version = "0.4.49"
 default-features = false
 features = ["search"]
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 3c3ebf556c5..4195258af88 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -175,6 +175,9 @@ const EXCEPTIONS_RUSTC_PERF: ExceptionList = &[
 
 const EXCEPTIONS_RUSTBOOK: ExceptionList = &[
     // tidy-alphabetical-start
+    ("cssparser", "MPL-2.0"),
+    ("cssparser-macros", "MPL-2.0"),
+    ("dtoa-short", "MPL-2.0"),
     ("mdbook", "MPL-2.0"),
     ("ryu", "Apache-2.0 OR BSL-1.0"),
     // tidy-alphabetical-end
@@ -459,7 +462,6 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[
     // tidy-alphabetical-start
     "addr2line",
     "adler2",
-    "allocator-api2",
     "cc",
     "cfg-if",
     "compiler_builtins",
@@ -473,8 +475,6 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[
     "memchr",
     "miniz_oxide",
     "object",
-    "proc-macro2",
-    "quote",
     "r-efi",
     "r-efi-alloc",
     "rand",
@@ -483,8 +483,6 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[
     "rustc-demangle",
     "rustc-literal-escaper",
     "shlex",
-    "syn",
-    "unicode-ident",
     "unicode-width",
     "unwinding",
     "wasi",
@@ -498,8 +496,6 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[
     "windows_x86_64_gnu",
     "windows_x86_64_gnullvm",
     "windows_x86_64_msvc",
-    "zerocopy",
-    "zerocopy-derive",
     // tidy-alphabetical-end
 ];
 
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index e6b5aa59622..2f0158609e0 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -276,13 +276,7 @@ ui/auto-traits/issue-23080-2.rs
 ui/auto-traits/issue-23080.rs
 ui/auto-traits/issue-83857-ub.rs
 ui/auto-traits/issue-84075.rs
-ui/auxiliary/issue-13560-1.rs
-ui/auxiliary/issue-13560-2.rs
-ui/auxiliary/issue-13560-3.rs
 ui/auxiliary/issue-16822.rs
-ui/auxiliary/issue-18502.rs
-ui/auxiliary/issue-24106.rs
-ui/auxiliary/issue-76387.rs
 ui/bench/issue-32062.rs
 ui/binding/issue-40402-1.rs
 ui/binding/issue-40402-2.rs
@@ -1378,12 +1372,8 @@ ui/intrinsics/issue-28575.rs
 ui/intrinsics/issue-84297-reifying-copy.rs
 ui/invalid/issue-114435-layout-type-err.rs
 ui/issue-11881.rs
-ui/issue-13560.rs
 ui/issue-15924.rs
 ui/issue-16822.rs
-ui/issue-18502.rs
-ui/issue-24106.rs
-ui/issue-76387-llvm-miscompile.rs
 ui/issues-71798.rs
 ui/issues/auxiliary/issue-11224.rs
 ui/issues/auxiliary/issue-11508.rs
diff --git a/src/version b/src/version
index 59be592144c..636ea711ad9 100644
--- a/src/version
+++ b/src/version
@@ -1 +1 @@
-1.88.0
+1.89.0
diff --git a/tests/assembly/asm/aarch64-types.rs b/tests/assembly/asm/aarch64-types.rs
index 8e4e0850325..ad2770d43e3 100644
--- a/tests/assembly/asm/aarch64-types.rs
+++ b/tests/assembly/asm/aarch64-types.rs
@@ -86,10 +86,12 @@ pub unsafe fn sym_static() {
 
 // Regression test for #75761
 // CHECK-LABEL: {{("#)?}}issue_75761{{"?}}
-// CHECK: str {{.*}}x30
+// aarch64: str {{.*}}x30
+// arm64ec: stp {{.*}}x30
 // CHECK: //APP
 // CHECK: //NO_APP
-// CHECK: ldr {{.*}}x30
+// aarch64: ldr {{.*}}x30
+// arm64ec: ldp {{.*}}x30
 #[no_mangle]
 pub unsafe fn issue_75761() {
     asm!("", out("v0") _, out("x30") _);
diff --git a/tests/codegen/const-vector.rs b/tests/codegen/const-vector.rs
index 289b67371ce..42921442e03 100644
--- a/tests/codegen/const-vector.rs
+++ b/tests/codegen/const-vector.rs
@@ -1,4 +1,8 @@
-//@ compile-flags: -C no-prepopulate-passes -Copt-level=0
+//@ revisions: OPT0 OPT0_S390X
+//@ [OPT0] ignore-s390x
+//@ [OPT0_S390X] only-s390x
+//@ [OPT0] compile-flags: -C no-prepopulate-passes -Copt-level=0
+//@ [OPT0_S390X] compile-flags: -C no-prepopulate-passes -Copt-level=0 -C target-cpu=z13
 
 // This test checks that constants of SIMD type are passed as immediate vectors.
 // We ensure that both vector representations (struct with fields and struct wrapping array) work.
diff --git a/tests/codegen/simd/extract-insert-dyn.rs b/tests/codegen/simd/extract-insert-dyn.rs
index 7d032c6bb3e..729f0145314 100644
--- a/tests/codegen/simd/extract-insert-dyn.rs
+++ b/tests/codegen/simd/extract-insert-dyn.rs
@@ -1,6 +1,12 @@
 //@compile-flags: -C opt-level=3 -C no-prepopulate-passes
 
-#![feature(core_intrinsics, repr_simd, arm_target_feature, mips_target_feature)]
+#![feature(
+    core_intrinsics,
+    repr_simd,
+    arm_target_feature,
+    mips_target_feature,
+    s390x_target_feature
+)]
 #![no_std]
 #![crate_type = "lib"]
 #![allow(non_camel_case_types)]
@@ -25,6 +31,7 @@ pub struct i8x16([i8; 16]);
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
 #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
+#[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))]
 unsafe extern "C" fn dyn_simd_extract(x: i8x16, idx: u32) -> i8 {
     simd_extract_dyn(x, idx)
 }
@@ -36,6 +43,7 @@ unsafe extern "C" fn dyn_simd_extract(x: i8x16, idx: u32) -> i8 {
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
 #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
+#[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))]
 unsafe extern "C" fn literal_dyn_simd_extract(x: i8x16) -> i8 {
     simd_extract_dyn(x, 7)
 }
@@ -47,6 +55,7 @@ unsafe extern "C" fn literal_dyn_simd_extract(x: i8x16) -> i8 {
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
 #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
+#[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))]
 unsafe extern "C" fn const_dyn_simd_extract(x: i8x16) -> i8 {
     simd_extract_dyn(x, const { 3 + 4 })
 }
@@ -58,6 +67,7 @@ unsafe extern "C" fn const_dyn_simd_extract(x: i8x16) -> i8 {
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
 #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
+#[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))]
 unsafe extern "C" fn const_simd_extract(x: i8x16) -> i8 {
     simd_extract(x, const { 3 + 4 })
 }
@@ -69,6 +79,7 @@ unsafe extern "C" fn const_simd_extract(x: i8x16) -> i8 {
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
 #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
+#[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))]
 unsafe extern "C" fn dyn_simd_insert(x: i8x16, e: i8, idx: u32) -> i8x16 {
     simd_insert_dyn(x, idx, e)
 }
@@ -80,6 +91,7 @@ unsafe extern "C" fn dyn_simd_insert(x: i8x16, e: i8, idx: u32) -> i8x16 {
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
 #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
+#[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))]
 unsafe extern "C" fn literal_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 {
     simd_insert_dyn(x, 7, e)
 }
@@ -91,6 +103,7 @@ unsafe extern "C" fn literal_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 {
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
 #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
+#[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))]
 unsafe extern "C" fn const_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 {
     simd_insert_dyn(x, const { 3 + 4 }, e)
 }
@@ -102,6 +115,7 @@ unsafe extern "C" fn const_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 {
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
 #[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
+#[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))]
 unsafe extern "C" fn const_simd_insert(x: i8x16, e: i8) -> i8x16 {
     simd_insert(x, const { 3 + 4 }, e)
 }
diff --git a/tests/coverage/abort.cov-map b/tests/coverage/abort.cov-map
index 26536caeba5..4d8ea874bd7 100644
--- a/tests/coverage/abort.cov-map
+++ b/tests/coverage/abort.cov-map
@@ -1,7 +1,7 @@
 Function name: abort::main
-Raw bytes (83): 0x[01, 01, 07, 05, 01, 05, 0b, 01, 09, 05, 13, 01, 0d, 05, 1b, 01, 11, 0d, 01, 0d, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 19, 09, 00, 1a, 02, 0a, 06, 02, 09, 00, 0a, 02, 02, 0c, 00, 19, 0d, 00, 1a, 00, 31, 0e, 00, 30, 00, 31, 02, 04, 0c, 00, 19, 11, 00, 1a, 00, 31, 16, 00, 30, 00, 31, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02]
+Raw bytes (98): 0x[01, 01, 07, 05, 01, 05, 0b, 01, 09, 05, 13, 01, 0d, 05, 1b, 01, 11, 10, 01, 0d, 01, 00, 1c, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 01, 0b, 00, 18, 02, 01, 0c, 00, 19, 09, 00, 1a, 02, 0a, 06, 02, 09, 00, 0a, 02, 02, 0c, 00, 19, 0d, 00, 1a, 00, 31, 0e, 00, 30, 00, 31, 02, 04, 0c, 00, 19, 11, 00, 1a, 00, 31, 16, 00, 30, 00, 31, 02, 01, 09, 00, 17, 01, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/abort.rs
 Number of expressions: 7
 - expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 - expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
@@ -10,9 +10,11 @@ Number of expressions: 7
 - expression 4 operands: lhs = Counter(0), rhs = Counter(3)
 - expression 5 operands: lhs = Counter(1), rhs = Expression(6, Add)
 - expression 6 operands: lhs = Counter(0), rhs = Counter(4)
-Number of file 0 mappings: 13
-- Code(Counter(0)) at (prev + 13, 1) to (start + 1, 27)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 24)
+Number of file 0 mappings: 16
+- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 24)
 - Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 0, 25)
     = (c1 - c0)
 - Code(Counter(2)) at (prev + 0, 26) to (start + 2, 10)
@@ -30,19 +32,25 @@ Number of file 0 mappings: 13
     = (c1 - (c0 + c4))
 - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 23)
     = (c1 - c0)
-- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c4
 
 Function name: abort::might_abort
-Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 03, 01, 01, 14, 05, 02, 09, 01, 0f, 02, 02, 0c, 03, 02]
+Raw bytes (41): 0x[01, 01, 01, 01, 05, 07, 01, 03, 01, 00, 2e, 01, 01, 08, 00, 14, 05, 01, 09, 00, 11, 05, 00, 12, 00, 1f, 05, 01, 09, 00, 0f, 02, 01, 0c, 02, 06, 02, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/abort.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 3, 1) to (start + 1, 20)
-- Code(Counter(1)) at (prev + 2, 9) to (start + 1, 15)
-- Code(Expression(0, Sub)) at (prev + 2, 12) to (start + 3, 2)
+Number of file 0 mappings: 7
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 20)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(1)) at (prev + 0, 18) to (start + 0, 31)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 2, 6)
+    = (c0 - c1)
+- Code(Expression(0, Sub)) at (prev + 3, 1) to (start + 0, 2)
     = (c0 - c1)
 Highest counter ID seen: c1
 
diff --git a/tests/coverage/assert-ne.cov-map b/tests/coverage/assert-ne.cov-map
index 27d4b0382de..fde0d5184d6 100644
--- a/tests/coverage/assert-ne.cov-map
+++ b/tests/coverage/assert-ne.cov-map
@@ -1,16 +1,23 @@
 Function name: assert_ne::main
-Raw bytes (28): 0x[01, 01, 02, 01, 05, 01, 09, 04, 01, 08, 01, 03, 15, 05, 04, 0d, 00, 13, 02, 02, 0d, 00, 13, 06, 03, 05, 01, 02]
+Raw bytes (55): 0x[01, 01, 03, 01, 05, 01, 09, 01, 09, 09, 01, 08, 01, 00, 0a, 01, 01, 05, 00, 0f, 01, 01, 09, 00, 12, 01, 00, 13, 00, 19, 01, 01, 0c, 00, 15, 05, 01, 0d, 00, 13, 02, 02, 0d, 00, 13, 0a, 03, 05, 00, 07, 0a, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
-Number of expressions: 2
+- file 0 => $DIR/assert-ne.rs
+Number of expressions: 3
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 21)
-- Code(Counter(1)) at (prev + 4, 13) to (start + 0, 19)
+- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 25)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 21)
+- Code(Counter(1)) at (prev + 1, 13) to (start + 0, 19)
 - Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 19)
     = (c0 - c1)
-- Code(Expression(1, Sub)) at (prev + 3, 5) to (start + 1, 2)
+- Code(Expression(2, Sub)) at (prev + 3, 5) to (start + 0, 7)
+    = (c0 - c2)
+- Code(Expression(2, Sub)) at (prev + 1, 1) to (start + 0, 2)
     = (c0 - c2)
 Highest counter ID seen: c1
 
diff --git a/tests/coverage/assert.cov-map b/tests/coverage/assert.cov-map
index 903cccfe9cb..07a0d4c8c27 100644
--- a/tests/coverage/assert.cov-map
+++ b/tests/coverage/assert.cov-map
@@ -1,7 +1,7 @@
 Function name: assert::main
-Raw bytes (61): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 09, 01, 09, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 02, 0a, 06, 02, 13, 00, 20, 0d, 00, 21, 02, 0a, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02]
+Raw bytes (76): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 0c, 01, 09, 01, 00, 1c, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 01, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 02, 0a, 06, 02, 13, 00, 20, 0d, 00, 21, 02, 0a, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/assert.rs
 Number of expressions: 6
 - expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 - expression 1 operands: lhs = Counter(1), rhs = Expression(5, Add)
@@ -9,9 +9,11 @@ Number of expressions: 6
 - expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add)
 - expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3)
 - expression 5 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 9, 1) to (start + 1, 27)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 24)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 9, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 24)
 - Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 0, 26)
     = (c1 - c0)
 - Code(Counter(2)) at (prev + 0, 27) to (start + 2, 10)
@@ -22,18 +24,22 @@ Number of file 0 mappings: 9
     = (c1 - ((c0 + c2) + c3))
 - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 23)
     = (c1 - c0)
-- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c3
 
 Function name: assert::might_fail_assert
-Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 04, 01, 02, 0f, 02, 02, 25, 00, 3d, 05, 01, 01, 00, 02]
+Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 04, 01, 00, 28, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 20, 01, 01, 05, 00, 0f, 02, 00, 25, 00, 3d, 05, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/assert.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 4, 1) to (start + 2, 15)
-- Code(Expression(0, Sub)) at (prev + 2, 37) to (start + 0, 61)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 40)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Expression(0, Sub)) at (prev + 0, 37) to (start + 0, 61)
     = (c0 - c1)
 - Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
diff --git a/tests/coverage/assert_not.cov-map b/tests/coverage/assert_not.cov-map
index 3aef4274edc..e0ec3815244 100644
--- a/tests/coverage/assert_not.cov-map
+++ b/tests/coverage/assert_not.cov-map
@@ -1,13 +1,18 @@
 Function name: assert_not::main
-Raw bytes (29): 0x[01, 01, 00, 05, 01, 06, 01, 01, 11, 01, 02, 05, 00, 13, 01, 01, 05, 00, 13, 01, 01, 05, 00, 15, 01, 01, 01, 00, 02]
+Raw bytes (54): 0x[01, 01, 00, 0a, 01, 06, 01, 00, 0a, 01, 01, 05, 00, 0c, 01, 00, 0d, 00, 11, 01, 01, 05, 00, 0c, 01, 00, 0d, 00, 13, 01, 01, 05, 00, 0c, 01, 00, 0d, 00, 13, 01, 01, 05, 00, 0c, 01, 00, 0d, 00, 15, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/assert_not.rs
 Number of expressions: 0
-Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 17)
-- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 19)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 19)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 21)
+Number of file 0 mappings: 10
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 21)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/async.cov-map b/tests/coverage/async.cov-map
index 521562f6b91..c528ad525b5 100644
--- a/tests/coverage/async.cov-map
+++ b/tests/coverage/async.cov-map
@@ -1,115 +1,125 @@
 Function name: async::c
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 00, 19]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 00, 18]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 25)
+- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 24)
 Highest counter ID seen: c0
 
 Function name: async::c::{closure#0}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0b, 19, 01, 0e, 05, 02, 09, 00, 0a, 02, 02, 09, 00, 0a, 01, 02, 01, 00, 02]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 0b, 19, 00, 1a, 01, 01, 08, 00, 0e, 05, 01, 09, 00, 0a, 02, 02, 09, 00, 0a, 01, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 11, 25) to (start + 1, 14)
-- Code(Counter(1)) at (prev + 2, 9) to (start + 0, 10)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 11, 25) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 14)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 10)
 - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: async::d
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 00, 14]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 00, 13]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 19)
 Highest counter ID seen: c0
 
 Function name: async::d::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 14, 00, 19]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 13, 14, 00, 15, 01, 00, 16, 00, 17, 01, 00, 18, 00, 19]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 19, 20) to (start + 0, 25)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 19, 20) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 25)
 Highest counter ID seen: c0
 
 Function name: async::e (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 00, 14]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 00, 13]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 21, 1) to (start + 0, 20)
+- Code(Zero) at (prev + 21, 1) to (start + 0, 19)
 Highest counter ID seen: (none)
 
 Function name: async::e::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 14, 00, 19]
+Raw bytes (19): 0x[01, 01, 00, 03, 00, 15, 14, 00, 15, 00, 00, 16, 00, 17, 00, 00, 18, 00, 19]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 21, 20) to (start + 0, 25)
+Number of file 0 mappings: 3
+- Code(Zero) at (prev + 21, 20) to (start + 0, 21)
+- Code(Zero) at (prev + 0, 22) to (start + 0, 23)
+- Code(Zero) at (prev + 0, 24) to (start + 0, 25)
 Highest counter ID seen: (none)
 
 Function name: async::f
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 14]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 13]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 19)
 Highest counter ID seen: c0
 
 Function name: async::f::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 14, 00, 19]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 17, 14, 00, 15, 01, 00, 16, 00, 17, 01, 00, 18, 00, 19]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 23, 20) to (start + 0, 25)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 23, 20) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 25)
 Highest counter ID seen: c0
 
 Function name: async::foo (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 01, 00, 1e]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 01, 00, 1d]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 25, 1) to (start + 0, 30)
+- Code(Zero) at (prev + 25, 1) to (start + 0, 29)
 Highest counter ID seen: (none)
 
 Function name: async::foo::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 1e, 00, 2d]
+Raw bytes (19): 0x[01, 01, 00, 03, 00, 19, 1e, 00, 1f, 00, 00, 20, 00, 2b, 00, 00, 2c, 00, 2d]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 25, 30) to (start + 0, 45)
+Number of file 0 mappings: 3
+- Code(Zero) at (prev + 25, 30) to (start + 0, 31)
+- Code(Zero) at (prev + 0, 32) to (start + 0, 43)
+- Code(Zero) at (prev + 0, 44) to (start + 0, 45)
 Highest counter ID seen: (none)
 
 Function name: async::g
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 01, 00, 17]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 01, 00, 16]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 22)
 Highest counter ID seen: c0
 
 Function name: async::g::{closure#0} (unused)
-Raw bytes (59): 0x[01, 01, 00, 0b, 00, 1b, 17, 01, 0c, 00, 02, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
+Raw bytes (64): 0x[01, 01, 00, 0c, 00, 1b, 17, 00, 18, 00, 01, 0b, 00, 0c, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
-Number of file 0 mappings: 11
-- Code(Zero) at (prev + 27, 23) to (start + 1, 12)
-- Code(Zero) at (prev + 2, 9) to (start + 0, 10)
+Number of file 0 mappings: 12
+- Code(Zero) at (prev + 27, 23) to (start + 0, 24)
+- Code(Zero) at (prev + 1, 11) to (start + 0, 12)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 10)
 - Code(Zero) at (prev + 0, 14) to (start + 0, 23)
 - Code(Zero) at (prev + 0, 27) to (start + 0, 28)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
@@ -122,22 +132,23 @@ Number of file 0 mappings: 11
 Highest counter ID seen: (none)
 
 Function name: async::h
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 23, 01, 00, 16]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 23, 01, 00, 15]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 35, 1) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 35, 1) to (start + 0, 21)
 Highest counter ID seen: c0
 
 Function name: async::h::{closure#0} (unused)
-Raw bytes (39): 0x[01, 01, 00, 07, 00, 23, 16, 03, 0c, 00, 04, 09, 00, 0a, 00, 00, 0e, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
+Raw bytes (44): 0x[01, 01, 00, 08, 00, 23, 16, 00, 17, 00, 03, 0b, 00, 0c, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
-Number of file 0 mappings: 7
-- Code(Zero) at (prev + 35, 22) to (start + 3, 12)
-- Code(Zero) at (prev + 4, 9) to (start + 0, 10)
+Number of file 0 mappings: 8
+- Code(Zero) at (prev + 35, 22) to (start + 0, 23)
+- Code(Zero) at (prev + 3, 11) to (start + 0, 12)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 10)
 - Code(Zero) at (prev + 0, 14) to (start + 0, 25)
 - Code(Zero) at (prev + 0, 26) to (start + 0, 27)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
@@ -146,25 +157,27 @@ Number of file 0 mappings: 7
 Highest counter ID seen: (none)
 
 Function name: async::i
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 2c, 01, 00, 13]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 2c, 01, 00, 12]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 44, 1) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 44, 1) to (start + 0, 18)
 Highest counter ID seen: c0
 
 Function name: async::i::{closure#0}
-Raw bytes (65): 0x[01, 01, 03, 05, 09, 11, 15, 0d, 11, 0b, 01, 2c, 13, 04, 0c, 09, 05, 09, 00, 0a, 01, 00, 0e, 00, 18, 05, 00, 1c, 00, 21, 09, 00, 27, 00, 30, 15, 01, 09, 00, 0a, 02, 00, 0e, 00, 17, 11, 00, 1b, 00, 20, 15, 00, 24, 00, 26, 06, 01, 0e, 00, 10, 0b, 02, 01, 00, 02]
+Raw bytes (75): 0x[01, 01, 03, 05, 09, 11, 15, 0d, 11, 0d, 01, 2c, 13, 00, 14, 01, 04, 0b, 00, 0c, 09, 01, 09, 00, 0a, 01, 00, 0e, 00, 0f, 01, 00, 0e, 00, 18, 05, 00, 1c, 00, 21, 09, 00, 27, 00, 30, 15, 01, 09, 00, 0a, 02, 00, 0e, 00, 17, 11, 00, 1b, 00, 20, 15, 00, 24, 00, 26, 06, 01, 0e, 00, 10, 0b, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 3
 - expression 0 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 1 operands: lhs = Counter(4), rhs = Counter(5)
 - expression 2 operands: lhs = Counter(3), rhs = Counter(4)
-Number of file 0 mappings: 11
-- Code(Counter(0)) at (prev + 44, 19) to (start + 4, 12)
-- Code(Counter(2)) at (prev + 5, 9) to (start + 0, 10)
+Number of file 0 mappings: 13
+- Code(Counter(0)) at (prev + 44, 19) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 4, 11) to (start + 0, 12)
+- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 15)
 - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 24)
 - Code(Counter(1)) at (prev + 0, 28) to (start + 0, 33)
 - Code(Counter(2)) at (prev + 0, 39) to (start + 0, 48)
@@ -180,17 +193,18 @@ Number of file 0 mappings: 11
 Highest counter ID seen: c5
 
 Function name: async::j
-Raw bytes (60): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 0a, 01, 37, 01, 00, 0d, 01, 0b, 0b, 00, 0c, 05, 01, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 02, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 06, 01, 0e, 00, 10, 01, 02, 01, 00, 02]
+Raw bytes (65): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 0b, 01, 37, 01, 00, 0c, 01, 0b, 0b, 00, 0c, 05, 01, 09, 00, 0a, 01, 00, 0e, 00, 0f, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 02, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 06, 01, 0e, 00, 10, 01, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 3
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 55, 1) to (start + 0, 13)
+Number of file 0 mappings: 11
+- Code(Counter(0)) at (prev + 55, 1) to (start + 0, 12)
 - Code(Counter(0)) at (prev + 11, 11) to (start + 0, 12)
 - Code(Counter(1)) at (prev + 1, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 15)
 - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 27)
 - Code(Counter(1)) at (prev + 0, 31) to (start + 0, 39)
 - Code(Counter(2)) at (prev + 1, 9) to (start + 0, 10)
@@ -203,60 +217,67 @@ Number of file 0 mappings: 10
 Highest counter ID seen: c2
 
 Function name: async::j::c
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 39, 05, 01, 12, 05, 02, 0d, 00, 0e, 02, 02, 0d, 00, 0e, 01, 02, 05, 00, 06]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 39, 05, 00, 16, 01, 01, 0c, 00, 12, 05, 01, 0d, 00, 0e, 02, 02, 0d, 00, 0e, 01, 02, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 57, 5) to (start + 1, 18)
-- Code(Counter(1)) at (prev + 2, 13) to (start + 0, 14)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 57, 5) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 18)
+- Code(Counter(1)) at (prev + 1, 13) to (start + 0, 14)
 - Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 14)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 2, 5) to (start + 0, 6)
 Highest counter ID seen: c1
 
 Function name: async::j::d
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 40, 05, 00, 17]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 40, 05, 00, 11, 01, 00, 14, 00, 15, 01, 00, 16, 00, 17]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 64, 5) to (start + 0, 23)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 64, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23)
 Highest counter ID seen: c0
 
 Function name: async::j::f
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 41, 05, 00, 17]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 41, 05, 00, 11, 01, 00, 14, 00, 15, 01, 00, 16, 00, 17]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 65, 5) to (start + 0, 23)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 65, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23)
 Highest counter ID seen: c0
 
 Function name: async::k (unused)
-Raw bytes (29): 0x[01, 01, 00, 05, 00, 49, 01, 01, 0c, 00, 02, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 00, 49, 01, 00, 0c, 00, 01, 0b, 00, 0c, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
-Number of file 0 mappings: 5
-- Code(Zero) at (prev + 73, 1) to (start + 1, 12)
-- Code(Zero) at (prev + 2, 14) to (start + 0, 16)
+Number of file 0 mappings: 6
+- Code(Zero) at (prev + 73, 1) to (start + 0, 12)
+- Code(Zero) at (prev + 1, 11) to (start + 0, 12)
+- Code(Zero) at (prev + 1, 14) to (start + 0, 16)
 - Code(Zero) at (prev + 1, 14) to (start + 0, 16)
 - Code(Zero) at (prev + 1, 14) to (start + 0, 16)
 - Code(Zero) at (prev + 2, 1) to (start + 0, 2)
 Highest counter ID seen: (none)
 
 Function name: async::l
-Raw bytes (33): 0x[01, 01, 02, 01, 07, 05, 09, 05, 01, 51, 01, 01, 0c, 02, 02, 0e, 00, 10, 09, 01, 0e, 00, 10, 05, 01, 0e, 00, 10, 01, 02, 01, 00, 02]
+Raw bytes (38): 0x[01, 01, 02, 01, 07, 05, 09, 06, 01, 51, 01, 00, 0c, 01, 01, 0b, 00, 0c, 02, 01, 0e, 00, 10, 09, 01, 0e, 00, 10, 05, 01, 0e, 00, 10, 01, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 2
 - expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 81, 1) to (start + 1, 12)
-- Code(Expression(0, Sub)) at (prev + 2, 14) to (start + 0, 16)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 81, 1) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 11) to (start + 0, 12)
+- Code(Expression(0, Sub)) at (prev + 1, 14) to (start + 0, 16)
     = (c0 - (c1 + c2))
 - Code(Counter(2)) at (prev + 1, 14) to (start + 0, 16)
 - Code(Counter(1)) at (prev + 1, 14) to (start + 0, 16)
@@ -264,29 +285,43 @@ Number of file 0 mappings: 5
 Highest counter ID seen: c2
 
 Function name: async::m
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 59, 01, 00, 19]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 59, 01, 00, 18]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 89, 1) to (start + 0, 25)
+- Code(Counter(0)) at (prev + 89, 1) to (start + 0, 24)
 Highest counter ID seen: c0
 
 Function name: async::m::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 59, 19, 00, 22]
+Raw bytes (19): 0x[01, 01, 00, 03, 00, 59, 19, 00, 1a, 00, 00, 1b, 00, 20, 00, 00, 21, 00, 22]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 89, 25) to (start + 0, 34)
+Number of file 0 mappings: 3
+- Code(Zero) at (prev + 89, 25) to (start + 0, 26)
+- Code(Zero) at (prev + 0, 27) to (start + 0, 32)
+- Code(Zero) at (prev + 0, 33) to (start + 0, 34)
 Highest counter ID seen: (none)
 
 Function name: async::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 5b, 01, 08, 02]
+Raw bytes (69): 0x[01, 01, 00, 0d, 01, 5b, 01, 00, 0a, 01, 01, 0d, 00, 12, 01, 01, 0d, 00, 11, 01, 01, 09, 00, 13, 01, 00, 16, 00, 1e, 01, 00, 1f, 00, 20, 01, 01, 05, 00, 06, 01, 01, 05, 00, 06, 01, 01, 0d, 00, 11, 01, 01, 05, 00, 17, 01, 00, 18, 00, 1e, 01, 00, 1f, 00, 25, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 91, 1) to (start + 8, 2)
+Number of file 0 mappings: 13
+- Code(Counter(0)) at (prev + 91, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 0, 31) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 0, 31) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/async.coverage b/tests/coverage/async.coverage
index aee76b05fb7..9fca1b6997d 100644
--- a/tests/coverage/async.coverage
+++ b/tests/coverage/async.coverage
@@ -25,6 +25,7 @@
    LL|      0|async fn foo() -> [bool; 10] { [false; 10] } // unused function; executor does not block on `h()`
    LL|       |
    LL|      1|pub async fn g(x: u8) {
+                                    ^0
    LL|      0|    match x {
    LL|      0|        y if e().await == y => (),
    LL|      0|        y if f().await == y => (),
@@ -33,8 +34,9 @@
    LL|      0|}
    LL|       |
    LL|      1|async fn h(x: usize) { // The function signature is counted when called, but the body is not
-   LL|      0|                       // executed (not awaited) so the open brace has a `0` count (at least when
-   LL|      0|                       // displayed with `llvm-cov show` in color-mode).
+                                   ^0
+   LL|       |                       // executed (not awaited) so the open brace has a `0` count (at least when
+   LL|       |                       // displayed with `llvm-cov show` in color-mode).
    LL|      0|    match x {
    LL|      0|        y if foo().await[y] => (),
    LL|      0|        _ => (),
@@ -42,9 +44,9 @@
    LL|      0|}
    LL|       |
    LL|      1|async fn i(x: u8) { // line coverage is 1, but there are 2 regions:
-   LL|      1|                    // (a) the function signature, counted when the function is called; and
-   LL|      1|                    // (b) the open brace for the function body, counted once when the body is
-   LL|      1|                    // executed asynchronously.
+   LL|       |                    // (a) the function signature, counted when the function is called; and
+   LL|       |                    // (b) the open brace for the function body, counted once when the body is
+   LL|       |                    // executed asynchronously.
    LL|      1|    match x {
    LL|      1|        y if c(x).await == y + 1 => { d().await; }
                       ^0                            ^0
@@ -91,7 +93,7 @@
    LL|      1|}
    LL|       |
    LL|      1|async fn m(x: u8) -> u8 { x - 1 }
-                                      ^0
+                                      ^0^0    ^0
    LL|       |
    LL|      1|fn main() {
    LL|      1|    let _ = g(10);
diff --git a/tests/coverage/async2.cov-map b/tests/coverage/async2.cov-map
index c2a0645ee9a..cc629517098 100644
--- a/tests/coverage/async2.cov-map
+++ b/tests/coverage/async2.cov-map
@@ -1,59 +1,80 @@
 Function name: async2::async_func
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 01, 00, 17]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 01, 00, 16]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async2.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 15, 1) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 15, 1) to (start + 0, 22)
 Highest counter ID seen: c0
 
 Function name: async2::async_func::{closure#0}
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 0f, 17, 03, 09, 01, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (49): 0x[01, 01, 00, 09, 01, 0f, 17, 00, 18, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 26, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 11, 01, 01, 08, 00, 09, 01, 00, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async2.rs
 Number of expressions: 0
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 15, 23) to (start + 3, 9)
-- Code(Counter(0)) at (prev + 3, 10) to (start + 2, 6)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 15, 23) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 38)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- Code(Counter(0)) at (prev + 0, 10) to (start + 2, 6)
 - 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: c0
 
 Function name: async2::async_func_just_println
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 24]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 23]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async2.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 36)
+- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 35)
 Highest counter ID seen: c0
 
 Function name: async2::async_func_just_println::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 24, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 17, 24, 00, 25, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 33, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async2.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 23, 36) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 23, 36) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 51)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: async2::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 01, 07, 02]
+Raw bytes (49): 0x[01, 01, 00, 09, 01, 1b, 01, 00, 0a, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 23, 01, 02, 05, 00, 13, 01, 02, 05, 00, 17, 01, 00, 18, 00, 22, 01, 01, 05, 00, 17, 01, 00, 18, 00, 2f, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async2.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 27, 1) to (start + 7, 2)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 35)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 47)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: async2::non_async_func
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 07, 01, 03, 09, 01, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (49): 0x[01, 01, 00, 09, 01, 07, 01, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 2a, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 11, 01, 01, 08, 00, 09, 01, 00, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async2.rs
 Number of expressions: 0
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 7, 1) to (start + 3, 9)
-- Code(Counter(0)) at (prev + 3, 10) to (start + 2, 6)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 42)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- Code(Counter(0)) at (prev + 0, 10) to (start + 2, 6)
 - 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: c0
diff --git a/tests/coverage/async2.coverage b/tests/coverage/async2.coverage
index fa56072924b..e9ed8253093 100644
--- a/tests/coverage/async2.coverage
+++ b/tests/coverage/async2.coverage
@@ -28,9 +28,9 @@
    LL|       |
    LL|      1|fn main() {
    LL|      1|    println!("codecovsample::main");
-   LL|      1|
+   LL|       |
    LL|      1|    non_async_func();
-   LL|      1|
+   LL|       |
    LL|      1|    executor::block_on(async_func());
    LL|      1|    executor::block_on(async_func_just_println());
    LL|      1|}
diff --git a/tests/coverage/async_block.cov-map b/tests/coverage/async_block.cov-map
index d9196f446f1..07d4c0eb3cd 100644
--- a/tests/coverage/async_block.cov-map
+++ b/tests/coverage/async_block.cov-map
@@ -1,30 +1,33 @@
 Function name: async_block::main
-Raw bytes (36): 0x[01, 01, 01, 05, 01, 06, 01, 07, 01, 00, 0b, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 13, 02, 01, 0d, 00, 13, 02, 07, 09, 00, 22, 01, 02, 01, 00, 02]
+Raw bytes (41): 0x[01, 01, 01, 05, 01, 07, 01, 07, 01, 00, 0a, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 13, 02, 01, 0d, 00, 13, 02, 07, 09, 00, 1b, 02, 00, 1c, 00, 22, 01, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async_block.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(1), rhs = Counter(0)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 11)
+Number of file 0 mappings: 7
+- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 10)
 - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10)
     = (c1 - c0)
 - Code(Counter(1)) at (prev + 0, 14) to (start + 0, 19)
 - Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 19)
     = (c1 - c0)
-- Code(Expression(0, Sub)) at (prev + 7, 9) to (start + 0, 34)
+- Code(Expression(0, Sub)) at (prev + 7, 9) to (start + 0, 27)
+    = (c1 - c0)
+- Code(Expression(0, Sub)) at (prev + 0, 28) to (start + 0, 34)
     = (c1 - c0)
 - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: async_block::main::{closure#0}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 09, 1c, 01, 17, 05, 01, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 09, 1c, 00, 1d, 01, 01, 10, 00, 17, 05, 00, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async_block.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 9, 28) to (start + 1, 23)
-- Code(Counter(1)) at (prev + 1, 24) to (start + 2, 14)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 9, 28) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 23)
+- Code(Counter(1)) at (prev + 0, 24) to (start + 2, 14)
 - Code(Expression(0, Sub)) at (prev + 2, 20) to (start + 2, 14)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
diff --git a/tests/coverage/async_closure.cov-map b/tests/coverage/async_closure.cov-map
index a4ef0ceeb6d..9f8dc8d6cbb 100644
--- a/tests/coverage/async_closure.cov-map
+++ b/tests/coverage/async_closure.cov-map
@@ -1,38 +1,45 @@
 Function name: async_closure::call_once::<async_closure::main::{closure#0}>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 06, 01, 00, 2b]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 06, 01, 00, 2a]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async_closure.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 43)
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 42)
 Highest counter ID seen: c0
 
 Function name: async_closure::call_once::<async_closure::main::{closure#0}>::{closure#0}
-Raw bytes (16): 0x[01, 01, 01, 05, 09, 02, 01, 06, 2b, 01, 0e, 02, 02, 01, 00, 02]
+Raw bytes (21): 0x[01, 01, 01, 05, 09, 03, 01, 06, 2b, 00, 2c, 01, 01, 05, 00, 0e, 02, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async_closure.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 6, 43) to (start + 1, 14)
-- Code(Expression(0, Sub)) at (prev + 2, 1) to (start + 0, 2)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 6, 43) to (start + 0, 44)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Expression(0, Sub)) at (prev + 1, 1) to (start + 0, 2)
     = (c1 - c2)
 Highest counter ID seen: c0
 
 Function name: async_closure::main
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 0a, 01, 01, 16, 01, 02, 05, 02, 02]
+Raw bytes (44): 0x[01, 01, 00, 08, 01, 0a, 01, 00, 0e, 01, 01, 09, 00, 16, 01, 01, 05, 00, 17, 01, 00, 18, 00, 27, 01, 01, 05, 00, 17, 01, 00, 18, 00, 21, 01, 00, 22, 00, 2f, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async_closure.rs
 Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 10, 1) to (start + 1, 22)
-- Code(Counter(0)) at (prev + 2, 5) to (start + 2, 2)
+Number of file 0 mappings: 8
+- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 39)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 0, 34) to (start + 0, 47)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: async_closure::main::{closure#0}
 Raw bytes (14): 0x[01, 01, 00, 02, 01, 0b, 22, 00, 23, 01, 00, 23, 00, 24]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async_closure.rs
 Number of expressions: 0
 Number of file 0 mappings: 2
 - Code(Counter(0)) at (prev + 11, 34) to (start + 0, 35)
@@ -42,7 +49,7 @@ Highest counter ID seen: c0
 Function name: async_closure::main::{closure#0}
 Raw bytes (14): 0x[01, 01, 00, 02, 01, 0b, 22, 00, 23, 01, 00, 23, 00, 24]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async_closure.rs
 Number of expressions: 0
 Number of file 0 mappings: 2
 - Code(Counter(0)) at (prev + 11, 34) to (start + 0, 35)
@@ -50,11 +57,12 @@ Number of file 0 mappings: 2
 Highest counter ID seen: c0
 
 Function name: async_closure::main::{closure#0}::{closure#0}::<i16>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 22, 00, 24]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 0b, 22, 00, 23, 01, 00, 23, 00, 24]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/async_closure.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 36)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 35)
+- Code(Counter(0)) at (prev + 0, 35) to (start + 0, 36)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/async_closure.coverage b/tests/coverage/async_closure.coverage
index 5aed131de2e..14f043415ea 100644
--- a/tests/coverage/async_closure.coverage
+++ b/tests/coverage/async_closure.coverage
@@ -8,7 +8,8 @@
    LL|      1|}
    LL|       |
    LL|      1|pub fn main() {
-   LL|      2|    let async_closure = async || {};
+   LL|      3|    let async_closure = async || {};
+                      ^1
   ------------------
   | async_closure::main::{closure#0}:
   |   LL|      1|    let async_closure = async || {};
diff --git a/tests/coverage/attr/impl.cov-map b/tests/coverage/attr/impl.cov-map
index 8a23c082082..0562c291e6c 100644
--- a/tests/coverage/attr/impl.cov-map
+++ b/tests/coverage/attr/impl.cov-map
@@ -1,27 +1,30 @@
 Function name: <impl::MyStruct>::off_on (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 0f, 05, 00, 13]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 0f, 05, 00, 10, 00, 00, 12, 00, 13]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/impl.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 15, 5) to (start + 0, 19)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 15, 5) to (start + 0, 16)
+- Code(Zero) at (prev + 0, 18) to (start + 0, 19)
 Highest counter ID seen: (none)
 
 Function name: <impl::MyStruct>::on_inherit (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 17, 05, 00, 17]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 17, 05, 00, 14, 00, 00, 16, 00, 17]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/impl.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 23, 5) to (start + 0, 23)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 23, 5) to (start + 0, 20)
+- Code(Zero) at (prev + 0, 22) to (start + 0, 23)
 Highest counter ID seen: (none)
 
 Function name: <impl::MyStruct>::on_on (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 1a, 05, 00, 12]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 1a, 05, 00, 0f, 00, 00, 11, 00, 12]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/impl.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 26, 5) to (start + 0, 18)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 26, 5) to (start + 0, 15)
+- Code(Zero) at (prev + 0, 17) to (start + 0, 18)
 Highest counter ID seen: (none)
 
diff --git a/tests/coverage/attr/module.cov-map b/tests/coverage/attr/module.cov-map
index 81e20a2c264..88f4915bfe8 100644
--- a/tests/coverage/attr/module.cov-map
+++ b/tests/coverage/attr/module.cov-map
@@ -1,27 +1,30 @@
 Function name: module::off::on (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 0d, 05, 00, 0f]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 0d, 05, 00, 0c, 00, 00, 0e, 00, 0f]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/module.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 13, 5) to (start + 0, 15)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 13, 5) to (start + 0, 12)
+- Code(Zero) at (prev + 0, 14) to (start + 0, 15)
 Highest counter ID seen: (none)
 
 Function name: module::on::inherit (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 05, 00, 14]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 15, 05, 00, 11, 00, 00, 13, 00, 14]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/module.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 21, 5) to (start + 0, 20)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 21, 5) to (start + 0, 17)
+- Code(Zero) at (prev + 0, 19) to (start + 0, 20)
 Highest counter ID seen: (none)
 
 Function name: module::on::on (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 18, 05, 00, 0f]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 18, 05, 00, 0c, 00, 00, 0e, 00, 0f]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/module.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 24, 5) to (start + 0, 15)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 24, 5) to (start + 0, 12)
+- Code(Zero) at (prev + 0, 14) to (start + 0, 15)
 Highest counter ID seen: (none)
 
diff --git a/tests/coverage/attr/nested.cov-map b/tests/coverage/attr/nested.cov-map
index 138b3159ea5..8ca218f7267 100644
--- a/tests/coverage/attr/nested.cov-map
+++ b/tests/coverage/attr/nested.cov-map
@@ -1,20 +1,24 @@
 Function name: nested::closure_expr
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 40, 01, 01, 0f, 01, 0b, 05, 01, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 40, 01, 00, 12, 01, 01, 09, 00, 0f, 01, 0a, 05, 00, 0d, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/nested.rs
 Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 64, 1) to (start + 1, 15)
-- Code(Counter(0)) at (prev + 11, 5) to (start + 1, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 64, 1) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: nested::closure_tail
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 4f, 01, 01, 0f, 01, 11, 05, 01, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 4f, 01, 00, 12, 01, 01, 09, 00, 0f, 01, 10, 05, 00, 0d, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/nested.rs
 Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 79, 1) to (start + 1, 15)
-- Code(Counter(0)) at (prev + 17, 5) to (start + 1, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 79, 1) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 16, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/attr/off-on-sandwich.cov-map b/tests/coverage/attr/off-on-sandwich.cov-map
index c55c5897d8b..c0c6eab5710 100644
--- a/tests/coverage/attr/off-on-sandwich.cov-map
+++ b/tests/coverage/attr/off-on-sandwich.cov-map
@@ -1,30 +1,36 @@
 Function name: off_on_sandwich::dense_a::dense_b
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 05, 02, 10, 01, 07, 05, 00, 06]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 10, 05, 00, 11, 01, 01, 09, 00, 10, 01, 01, 09, 00, 10, 01, 05, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/off-on-sandwich.rs
 Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 16, 5) to (start + 2, 16)
-- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 6)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 16, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 5, 5) to (start + 0, 6)
 Highest counter ID seen: c0
 
 Function name: off_on_sandwich::sparse_a::sparse_b::sparse_c
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 22, 09, 02, 15, 01, 0b, 09, 00, 0a]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 22, 09, 00, 16, 01, 01, 0d, 00, 15, 01, 01, 0d, 00, 15, 01, 09, 09, 00, 0a]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/off-on-sandwich.rs
 Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 34, 9) to (start + 2, 21)
-- Code(Counter(0)) at (prev + 11, 9) to (start + 0, 10)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 34, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 9, 9) to (start + 0, 10)
 Highest counter ID seen: c0
 
 Function name: off_on_sandwich::sparse_a::sparse_b::sparse_c::sparse_d
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 25, 0d, 02, 19, 01, 07, 0d, 00, 0e]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 25, 0d, 00, 1a, 01, 01, 11, 00, 19, 01, 01, 11, 00, 19, 01, 05, 0d, 00, 0e]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/off-on-sandwich.rs
 Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 37, 13) to (start + 2, 25)
-- Code(Counter(0)) at (prev + 7, 13) to (start + 0, 14)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 37, 13) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 17) to (start + 0, 25)
+- Code(Counter(0)) at (prev + 1, 17) to (start + 0, 25)
+- Code(Counter(0)) at (prev + 5, 13) to (start + 0, 14)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/attr/trait-impl-inherit.cov-map b/tests/coverage/attr/trait-impl-inherit.cov-map
index eab9f926bb7..bf10083dd29 100644
--- a/tests/coverage/attr/trait-impl-inherit.cov-map
+++ b/tests/coverage/attr/trait-impl-inherit.cov-map
@@ -1,9 +1,12 @@
 Function name: <trait_impl_inherit::S as trait_impl_inherit::T>::f
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 05, 02, 06]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 11, 05, 00, 10, 01, 01, 09, 00, 11, 01, 00, 12, 00, 1a, 01, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/trait-impl-inherit.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 17, 5) to (start + 2, 6)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 17, 5) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/await_ready.cov-map b/tests/coverage/await_ready.cov-map
index 61fd4c7814d..a7eb051ff09 100644
--- a/tests/coverage/await_ready.cov-map
+++ b/tests/coverage/await_ready.cov-map
@@ -1,21 +1,22 @@
 Function name: await_ready::await_ready
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0e, 01, 00, 1e]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 0e, 01, 00, 1d]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/await_ready.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 29)
 Highest counter ID seen: c0
 
 Function name: await_ready::await_ready::{closure#0}
-Raw bytes (16): 0x[01, 01, 01, 05, 09, 02, 01, 0e, 1e, 03, 0f, 02, 04, 01, 00, 02]
+Raw bytes (21): 0x[01, 01, 01, 05, 09, 03, 01, 0e, 1e, 00, 1f, 01, 02, 05, 01, 0f, 02, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/await_ready.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 14, 30) to (start + 3, 15)
-- Code(Expression(0, Sub)) at (prev + 4, 1) to (start + 0, 2)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 14, 30) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 15)
+- Code(Expression(0, Sub)) at (prev + 2, 1) to (start + 0, 2)
     = (c1 - c2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/await_ready.coverage b/tests/coverage/await_ready.coverage
index 1150d807e76..9a2d8f5a4fd 100644
--- a/tests/coverage/await_ready.coverage
+++ b/tests/coverage/await_ready.coverage
@@ -12,7 +12,7 @@
    LL|       |#[coverage(on)]
    LL|       |#[rustfmt::skip]
    LL|      1|async fn await_ready() -> u8 {
-   LL|      1|    // await should be covered even if the function never yields
+   LL|       |    // await should be covered even if the function never yields
    LL|      1|    ready()
    LL|      1|        .await
    LL|      1|}
diff --git a/tests/coverage/bad_counter_ids.cov-map b/tests/coverage/bad_counter_ids.cov-map
index f08a70a899d..8b1b177f906 100644
--- a/tests/coverage/bad_counter_ids.cov-map
+++ b/tests/coverage/bad_counter_ids.cov-map
@@ -1,84 +1,108 @@
 Function name: bad_counter_ids::eq_bad
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 24, 01, 02, 0f, 00, 03, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 24, 01, 00, 0c, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 00, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/bad_counter_ids.rs
 Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 36, 1) to (start + 2, 15)
-- Code(Zero) at (prev + 3, 1) to (start + 0, 2)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 36, 1) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: bad_counter_ids::eq_bad_message
-Raw bytes (19): 0x[01, 01, 00, 03, 01, 29, 01, 02, 0f, 01, 02, 20, 00, 2b, 00, 01, 01, 00, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 29, 01, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 01, 00, 20, 00, 2b, 00, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/bad_counter_ids.rs
 Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 41, 1) to (start + 2, 15)
-- Code(Counter(0)) at (prev + 2, 32) to (start + 0, 43)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 41, 1) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 0, 32) to (start + 0, 43)
 - Code(Zero) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: bad_counter_ids::eq_good
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 01, 02, 0f, 01, 03, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 10, 01, 00, 0d, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/bad_counter_ids.rs
 Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 16, 1) to (start + 2, 15)
-- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: bad_counter_ids::eq_good_message
-Raw bytes (19): 0x[01, 01, 00, 03, 01, 15, 01, 02, 0f, 00, 02, 20, 00, 2b, 01, 01, 01, 00, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 15, 01, 00, 15, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 00, 00, 20, 00, 2b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/bad_counter_ids.rs
 Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 21, 1) to (start + 2, 15)
-- Code(Zero) at (prev + 2, 32) to (start + 0, 43)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Zero) at (prev + 0, 32) to (start + 0, 43)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: bad_counter_ids::ne_bad
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 2e, 01, 02, 0f, 00, 03, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 2e, 01, 00, 0c, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 00, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/bad_counter_ids.rs
 Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 46, 1) to (start + 2, 15)
-- Code(Zero) at (prev + 3, 1) to (start + 0, 2)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 46, 1) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: bad_counter_ids::ne_bad_message
-Raw bytes (19): 0x[01, 01, 00, 03, 01, 33, 01, 02, 0f, 01, 02, 20, 00, 2b, 00, 01, 01, 00, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 33, 01, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 01, 00, 20, 00, 2b, 00, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/bad_counter_ids.rs
 Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 51, 1) to (start + 2, 15)
-- Code(Counter(0)) at (prev + 2, 32) to (start + 0, 43)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 51, 1) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 0, 32) to (start + 0, 43)
 - Code(Zero) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: bad_counter_ids::ne_good
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 1a, 01, 02, 0f, 01, 03, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 1a, 01, 00, 0d, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/bad_counter_ids.rs
 Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 26, 1) to (start + 2, 15)
-- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 26, 1) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: bad_counter_ids::ne_good_message
-Raw bytes (19): 0x[01, 01, 00, 03, 01, 1f, 01, 02, 0f, 00, 02, 20, 00, 2b, 01, 01, 01, 00, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 1f, 01, 00, 15, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 11, 01, 01, 05, 00, 0f, 00, 00, 20, 00, 2b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/bad_counter_ids.rs
 Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 31, 1) to (start + 2, 15)
-- Code(Zero) at (prev + 2, 32) to (start + 0, 43)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Zero) at (prev + 0, 32) to (start + 0, 43)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/bench.cov-map b/tests/coverage/bench.cov-map
index 9ee6510f690..f2b21ddb70b 100644
--- a/tests/coverage/bench.cov-map
+++ b/tests/coverage/bench.cov-map
@@ -1,9 +1,10 @@
 Function name: bench::my_bench
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 08, 01, 00, 27]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 08, 01, 00, 24, 01, 00, 26, 00, 27]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/bench.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 39)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 36)
+- Code(Counter(0)) at (prev + 0, 38) to (start + 0, 39)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/branch/generics.cov-map b/tests/coverage/branch/generics.cov-map
index 656890634ff..cb03f2a79f7 100644
--- a/tests/coverage/branch/generics.cov-map
+++ b/tests/coverage/branch/generics.cov-map
@@ -1,12 +1,13 @@
 Function name: generics::print_size::<()>
-Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 06, 01, 00, 13, 01, 01, 08, 00, 24, 20, 05, 02, 00, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/generics.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 36)
-- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 8) to (start + 0, 36)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 36)
+- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 36)
     true  = c1
     false = (c0 - c1)
 - Code(Counter(1)) at (prev + 0, 37) to (start + 2, 6)
@@ -16,14 +17,15 @@ Number of file 0 mappings: 5
 Highest counter ID seen: c1
 
 Function name: generics::print_size::<u32>
-Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 06, 01, 00, 13, 01, 01, 08, 00, 24, 20, 05, 02, 00, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/generics.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 36)
-- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 8) to (start + 0, 36)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 36)
+- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 36)
     true  = c1
     false = (c0 - c1)
 - Code(Counter(1)) at (prev + 0, 37) to (start + 2, 6)
@@ -33,14 +35,15 @@ Number of file 0 mappings: 5
 Highest counter ID seen: c1
 
 Function name: generics::print_size::<u64>
-Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 06, 01, 00, 13, 01, 01, 08, 00, 24, 20, 05, 02, 00, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/generics.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 36)
-- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 8) to (start + 0, 36)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 36)
+- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 36)
     true  = c1
     false = (c0 - c1)
 - Code(Counter(1)) at (prev + 0, 37) to (start + 2, 6)
diff --git a/tests/coverage/branch/guard.cov-map b/tests/coverage/branch/guard.cov-map
index 46533df00f7..9c6a9bf40fd 100644
--- a/tests/coverage/branch/guard.cov-map
+++ b/tests/coverage/branch/guard.cov-map
@@ -1,7 +1,7 @@
 Function name: guard::branch_match_guard
-Raw bytes (89): 0x[01, 01, 08, 05, 0d, 09, 05, 05, 0f, 0d, 11, 17, 1b, 01, 05, 1f, 11, 09, 0d, 0d, 01, 0c, 01, 01, 0e, 02, 03, 0b, 00, 0c, 06, 01, 14, 02, 0a, 0d, 03, 0e, 00, 0f, 05, 00, 14, 00, 19, 20, 0d, 02, 00, 14, 00, 1e, 0d, 00, 1d, 02, 0a, 11, 03, 0e, 00, 0f, 02, 00, 14, 00, 19, 20, 11, 0a, 00, 14, 00, 1e, 11, 00, 1d, 02, 0a, 12, 03, 0e, 02, 0a, 01, 04, 01, 00, 02]
+Raw bytes (104): 0x[01, 01, 08, 05, 0d, 09, 05, 05, 0f, 0d, 11, 17, 1b, 01, 05, 1f, 11, 09, 0d, 10, 01, 0c, 01, 00, 26, 01, 01, 05, 00, 0e, 02, 02, 0b, 00, 0c, 06, 01, 14, 02, 0a, 0d, 03, 0e, 00, 0f, 05, 00, 14, 00, 19, 20, 0d, 02, 00, 14, 00, 1e, 0d, 00, 1d, 00, 1e, 0d, 00, 22, 02, 0a, 11, 03, 0e, 00, 0f, 02, 00, 14, 00, 19, 20, 11, 0a, 00, 14, 00, 1e, 11, 00, 1d, 00, 1e, 11, 00, 22, 02, 0a, 12, 03, 0e, 02, 0a, 01, 04, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/guard.rs
 Number of expressions: 8
 - expression 0 operands: lhs = Counter(1), rhs = Counter(3)
 - expression 1 operands: lhs = Counter(2), rhs = Counter(1)
@@ -11,9 +11,10 @@ Number of expressions: 8
 - expression 5 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 6 operands: lhs = Expression(7, Add), rhs = Counter(4)
 - expression 7 operands: lhs = Counter(2), rhs = Counter(3)
-Number of file 0 mappings: 13
-- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14)
-- Code(Expression(0, Sub)) at (prev + 3, 11) to (start + 0, 12)
+Number of file 0 mappings: 16
+- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 38)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Expression(0, Sub)) at (prev + 2, 11) to (start + 0, 12)
     = (c1 - c3)
 - Code(Expression(1, Sub)) at (prev + 1, 20) to (start + 2, 10)
     = (c2 - c1)
@@ -22,14 +23,16 @@ Number of file 0 mappings: 13
 - Branch { true: Counter(3), false: Expression(0, Sub) } at (prev + 0, 20) to (start + 0, 30)
     true  = c3
     false = (c1 - c3)
-- Code(Counter(3)) at (prev + 0, 29) to (start + 2, 10)
+- Code(Counter(3)) at (prev + 0, 29) to (start + 0, 30)
+- Code(Counter(3)) at (prev + 0, 34) to (start + 2, 10)
 - Code(Counter(4)) at (prev + 3, 14) to (start + 0, 15)
 - Code(Expression(0, Sub)) at (prev + 0, 20) to (start + 0, 25)
     = (c1 - c3)
 - Branch { true: Counter(4), false: Expression(2, Sub) } at (prev + 0, 20) to (start + 0, 30)
     true  = c4
     false = (c1 - (c3 + c4))
-- Code(Counter(4)) at (prev + 0, 29) to (start + 2, 10)
+- Code(Counter(4)) at (prev + 0, 29) to (start + 0, 30)
+- Code(Counter(4)) at (prev + 0, 34) to (start + 2, 10)
 - Code(Expression(4, Sub)) at (prev + 3, 14) to (start + 2, 10)
     = ((c0 + c1) - ((c2 + c3) + c4))
 - Code(Counter(0)) at (prev + 4, 1) to (start + 0, 2)
diff --git a/tests/coverage/branch/guard.coverage b/tests/coverage/branch/guard.coverage
index f89b965b5d0..465aefbf066 100644
--- a/tests/coverage/branch/guard.coverage
+++ b/tests/coverage/branch/guard.coverage
@@ -17,7 +17,7 @@
    LL|      1|            println!("zero");
    LL|      1|        }
    LL|      3|        Some(x) if x % 2 == 0 => {
-                           ^2
+                           ^2             ^2
   ------------------
   |  Branch (LL:20): [True: 2, False: 1]
   ------------------
diff --git a/tests/coverage/branch/if-let.cov-map b/tests/coverage/branch/if-let.cov-map
index 7f6b174615a..86bfcadb125 100644
--- a/tests/coverage/branch/if-let.cov-map
+++ b/tests/coverage/branch/if-let.cov-map
@@ -1,12 +1,13 @@
 Function name: if_let::if_let
-Raw bytes (43): 0x[01, 01, 01, 01, 05, 07, 01, 0c, 01, 01, 0e, 20, 02, 05, 03, 0c, 00, 13, 02, 00, 11, 00, 12, 01, 00, 16, 00, 1b, 02, 00, 1c, 02, 06, 05, 02, 0c, 02, 06, 01, 03, 05, 01, 02]
+Raw bytes (58): 0x[01, 01, 01, 01, 05, 0a, 01, 0c, 01, 00, 1f, 01, 01, 05, 00, 0e, 20, 02, 05, 02, 0c, 00, 13, 02, 00, 11, 00, 12, 01, 00, 16, 00, 1b, 02, 00, 1c, 02, 06, 05, 02, 0c, 02, 06, 01, 03, 05, 00, 08, 01, 00, 09, 00, 0f, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/if-let.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14)
-- Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 3, 12) to (start + 0, 19)
+Number of file 0 mappings: 10
+- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 2, 12) to (start + 0, 19)
     true  = (c0 - c1)
     false = c1
 - Code(Expression(0, Sub)) at (prev + 0, 17) to (start + 0, 18)
@@ -15,41 +16,53 @@ Number of file 0 mappings: 7
 - Code(Expression(0, Sub)) at (prev + 0, 28) to (start + 2, 6)
     = (c0 - c1)
 - Code(Counter(1)) at (prev + 2, 12) to (start + 2, 6)
-- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: if_let::if_let_chain
-Raw bytes (74): 0x[01, 01, 08, 01, 05, 01, 1f, 05, 09, 01, 1f, 05, 09, 01, 1f, 05, 09, 05, 09, 0a, 01, 17, 01, 00, 33, 20, 02, 05, 01, 0c, 00, 13, 02, 00, 11, 00, 12, 01, 00, 16, 00, 17, 20, 16, 09, 01, 10, 00, 17, 16, 00, 15, 00, 16, 02, 00, 1a, 00, 1b, 16, 01, 05, 03, 06, 1f, 03, 0c, 02, 06, 01, 03, 05, 01, 02]
+Raw bytes (102): 0x[01, 01, 0c, 01, 05, 01, 2f, 05, 09, 01, 2f, 05, 09, 01, 2f, 05, 09, 01, 2f, 05, 09, 01, 2f, 05, 09, 05, 09, 0e, 01, 17, 01, 00, 32, 20, 02, 05, 01, 0c, 00, 13, 02, 00, 11, 00, 12, 01, 00, 16, 00, 17, 20, 26, 09, 01, 10, 00, 17, 26, 00, 15, 00, 16, 02, 00, 1a, 00, 1b, 26, 01, 05, 03, 06, 26, 01, 09, 00, 0c, 26, 00, 0d, 00, 0e, 2f, 02, 0c, 02, 06, 01, 03, 05, 00, 08, 01, 00, 09, 00, 0f, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
-Number of expressions: 8
+- file 0 => $DIR/if-let.rs
+Number of expressions: 12
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 1 operands: lhs = Counter(0), rhs = Expression(7, Add)
+- expression 1 operands: lhs = Counter(0), rhs = Expression(11, Add)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 3 operands: lhs = Counter(0), rhs = Expression(7, Add)
+- expression 3 operands: lhs = Counter(0), rhs = Expression(11, Add)
 - expression 4 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 5 operands: lhs = Counter(0), rhs = Expression(7, Add)
+- expression 5 operands: lhs = Counter(0), rhs = Expression(11, Add)
 - expression 6 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 7 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 51)
+- expression 7 operands: lhs = Counter(0), rhs = Expression(11, Add)
+- expression 8 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 9 operands: lhs = Counter(0), rhs = Expression(11, Add)
+- expression 10 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 11 operands: lhs = Counter(1), rhs = Counter(2)
+Number of file 0 mappings: 14
+- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 50)
 - Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 1, 12) to (start + 0, 19)
     true  = (c0 - c1)
     false = c1
 - Code(Expression(0, Sub)) at (prev + 0, 17) to (start + 0, 18)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23)
-- Branch { true: Expression(5, Sub), false: Counter(2) } at (prev + 1, 16) to (start + 0, 23)
+- Branch { true: Expression(9, Sub), false: Counter(2) } at (prev + 1, 16) to (start + 0, 23)
     true  = (c0 - (c1 + c2))
     false = c2
-- Code(Expression(5, Sub)) at (prev + 0, 21) to (start + 0, 22)
+- Code(Expression(9, Sub)) at (prev + 0, 21) to (start + 0, 22)
     = (c0 - (c1 + c2))
 - Code(Expression(0, Sub)) at (prev + 0, 26) to (start + 0, 27)
     = (c0 - c1)
-- Code(Expression(5, Sub)) at (prev + 1, 5) to (start + 3, 6)
+- Code(Expression(9, Sub)) at (prev + 1, 5) to (start + 3, 6)
+    = (c0 - (c1 + c2))
+- Code(Expression(9, Sub)) at (prev + 1, 9) to (start + 0, 12)
+    = (c0 - (c1 + c2))
+- Code(Expression(9, Sub)) at (prev + 0, 13) to (start + 0, 14)
     = (c0 - (c1 + c2))
-- Code(Expression(7, Add)) at (prev + 3, 12) to (start + 2, 6)
+- Code(Expression(11, Add)) at (prev + 2, 12) to (start + 2, 6)
     = (c1 + c2)
-- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c2
 
diff --git a/tests/coverage/branch/if.cov-map b/tests/coverage/branch/if.cov-map
index 1d40f032aa8..09a014ce8a1 100644
--- a/tests/coverage/branch/if.cov-map
+++ b/tests/coverage/branch/if.cov-map
@@ -1,14 +1,15 @@
 Function name: if::branch_and
-Raw bytes (54): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 2b, 01, 01, 0e, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 20, 09, 06, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (59): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 09, 01, 2b, 01, 00, 20, 01, 01, 05, 00, 0e, 01, 02, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 20, 09, 06, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/if.rs
 Number of expressions: 3
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 43, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 9)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 43, 1) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 9)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
@@ -23,9 +24,9 @@ Number of file 0 mappings: 8
 Highest counter ID seen: c2
 
 Function name: if::branch_not
-Raw bytes (116): 0x[01, 01, 07, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 01, 11, 01, 11, 12, 01, 0c, 01, 01, 0e, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 01, 09, 00, 10, 02, 01, 05, 00, 06, 01, 01, 08, 00, 0a, 20, 0a, 09, 00, 08, 00, 0a, 0a, 00, 0b, 02, 06, 09, 02, 05, 00, 06, 01, 01, 08, 00, 0b, 20, 0d, 12, 00, 08, 00, 0b, 0d, 00, 0c, 02, 06, 12, 02, 05, 00, 06, 01, 01, 08, 00, 0c, 20, 1a, 11, 00, 08, 00, 0c, 1a, 00, 0d, 02, 06, 11, 02, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (126): 0x[01, 01, 07, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 01, 11, 01, 11, 14, 01, 0c, 01, 00, 17, 01, 01, 05, 00, 0e, 01, 02, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 01, 09, 00, 0c, 05, 00, 0d, 00, 10, 02, 01, 05, 00, 06, 01, 01, 08, 00, 0a, 20, 0a, 09, 00, 08, 00, 0a, 0a, 00, 0b, 02, 06, 09, 02, 05, 00, 06, 01, 01, 08, 00, 0b, 20, 0d, 12, 00, 08, 00, 0b, 0d, 00, 0c, 02, 06, 12, 02, 05, 00, 06, 01, 01, 08, 00, 0c, 20, 1a, 11, 00, 08, 00, 0c, 1a, 00, 0d, 02, 06, 11, 02, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/if.rs
 Number of expressions: 7
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(2)
@@ -34,13 +35,15 @@ Number of expressions: 7
 - expression 4 operands: lhs = Counter(0), rhs = Counter(3)
 - expression 5 operands: lhs = Counter(0), rhs = Counter(4)
 - expression 6 operands: lhs = Counter(0), rhs = Counter(4)
-Number of file 0 mappings: 18
-- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 9)
+Number of file 0 mappings: 20
+- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 9)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
-- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 12)
+- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 16)
 - Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 8) to (start + 0, 10)
@@ -68,18 +71,19 @@ Number of file 0 mappings: 18
 Highest counter ID seen: c4
 
 Function name: if::branch_not_as
-Raw bytes (90): 0x[01, 01, 05, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 0e, 01, 1d, 01, 01, 0e, 01, 03, 08, 00, 14, 20, 02, 05, 00, 08, 00, 14, 02, 00, 15, 02, 06, 05, 02, 05, 00, 06, 01, 01, 08, 00, 15, 20, 09, 0a, 00, 08, 00, 15, 09, 00, 16, 02, 06, 0a, 02, 05, 00, 06, 01, 01, 08, 00, 16, 20, 12, 0d, 00, 08, 00, 16, 12, 00, 17, 02, 06, 0d, 02, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (95): 0x[01, 01, 05, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 0f, 01, 1d, 01, 00, 1a, 01, 01, 05, 00, 0e, 01, 02, 08, 00, 14, 20, 02, 05, 00, 08, 00, 14, 02, 00, 15, 02, 06, 05, 02, 05, 00, 06, 01, 01, 08, 00, 15, 20, 09, 0a, 00, 08, 00, 15, 09, 00, 16, 02, 06, 0a, 02, 05, 00, 06, 01, 01, 08, 00, 16, 20, 12, 0d, 00, 08, 00, 16, 12, 00, 17, 02, 06, 0d, 02, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/if.rs
 Number of expressions: 5
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(2)
 - expression 3 operands: lhs = Counter(0), rhs = Counter(3)
 - expression 4 operands: lhs = Counter(0), rhs = Counter(3)
-Number of file 0 mappings: 14
-- Code(Counter(0)) at (prev + 29, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 20)
+Number of file 0 mappings: 15
+- Code(Counter(0)) at (prev + 29, 1) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 20)
 - Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 0, 8) to (start + 0, 20)
     true  = (c0 - c1)
     false = c1
@@ -104,9 +108,9 @@ Number of file 0 mappings: 14
 Highest counter ID seen: c3
 
 Function name: if::branch_or
-Raw bytes (60): 0x[01, 01, 06, 01, 05, 01, 17, 05, 09, 05, 09, 01, 17, 05, 09, 08, 01, 35, 01, 01, 0e, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 20, 09, 12, 00, 0d, 00, 0e, 17, 00, 0f, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (65): 0x[01, 01, 06, 01, 05, 01, 17, 05, 09, 05, 09, 01, 17, 05, 09, 09, 01, 35, 01, 00, 1f, 01, 01, 05, 00, 0e, 01, 02, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 20, 09, 12, 00, 0d, 00, 0e, 17, 00, 0f, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/if.rs
 Number of expressions: 6
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Expression(5, Add)
@@ -114,9 +118,10 @@ Number of expressions: 6
 - expression 3 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 4 operands: lhs = Counter(0), rhs = Expression(5, Add)
 - expression 5 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 53, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 9)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 53, 1) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 9)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
diff --git a/tests/coverage/branch/lazy-boolean.cov-map b/tests/coverage/branch/lazy-boolean.cov-map
index 5d4fc57eb8f..9ec7c9a7f42 100644
--- a/tests/coverage/branch/lazy-boolean.cov-map
+++ b/tests/coverage/branch/lazy-boolean.cov-map
@@ -1,42 +1,48 @@
 Function name: lazy_boolean::branch_and
-Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 13, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 01, 01, 05, 01, 02]
+Raw bytes (53): 0x[01, 01, 01, 01, 05, 09, 01, 13, 01, 00, 20, 01, 01, 05, 00, 0e, 01, 03, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/lazy-boolean.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 19, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14)
     true  = c1
     false = (c0 - c1)
 - Code(Counter(1)) at (prev + 0, 18) to (start + 0, 19)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: lazy_boolean::branch_or
-Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 1b, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 01, 01, 05, 01, 02]
+Raw bytes (53): 0x[01, 01, 01, 01, 05, 09, 01, 1b, 01, 00, 1f, 01, 01, 05, 00, 0e, 01, 03, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/lazy-boolean.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 27, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14)
     true  = c1
     false = (c0 - c1)
 - Code(Expression(0, Sub)) at (prev + 0, 18) to (start + 0, 19)
     = (c0 - c1)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: lazy_boolean::chain
-Raw bytes (141): 0x[01, 01, 0f, 01, 05, 05, 09, 09, 0d, 01, 11, 01, 11, 01, 3b, 11, 15, 01, 3b, 11, 15, 01, 37, 3b, 19, 11, 15, 01, 37, 3b, 19, 11, 15, 13, 01, 24, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 05, 02, 00, 0d, 00, 12, 05, 00, 16, 00, 1b, 20, 09, 06, 00, 16, 00, 1b, 09, 00, 1f, 00, 24, 20, 0d, 0a, 00, 1f, 00, 24, 0d, 00, 28, 00, 2d, 01, 01, 05, 00, 10, 01, 03, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 11, 12, 00, 0d, 00, 12, 12, 00, 16, 00, 1b, 20, 15, 1e, 00, 16, 00, 1b, 1e, 00, 1f, 00, 24, 20, 19, 32, 00, 1f, 00, 24, 32, 00, 28, 00, 2d, 01, 01, 05, 01, 02]
+Raw bytes (161): 0x[01, 01, 0f, 01, 05, 05, 09, 09, 0d, 01, 11, 01, 11, 01, 3b, 11, 15, 01, 3b, 11, 15, 01, 37, 3b, 19, 11, 15, 01, 37, 3b, 19, 11, 15, 17, 01, 24, 01, 00, 11, 01, 01, 05, 00, 0e, 01, 03, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 05, 02, 00, 0d, 00, 12, 05, 00, 16, 00, 1b, 20, 09, 06, 00, 16, 00, 1b, 09, 00, 1f, 00, 24, 20, 0d, 0a, 00, 1f, 00, 24, 0d, 00, 28, 00, 2d, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 03, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 11, 12, 00, 0d, 00, 12, 12, 00, 16, 00, 1b, 20, 15, 1e, 00, 16, 00, 1b, 1e, 00, 1f, 00, 24, 20, 19, 32, 00, 1f, 00, 24, 32, 00, 28, 00, 2d, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/lazy-boolean.rs
 Number of expressions: 15
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
@@ -53,9 +59,10 @@ Number of expressions: 15
 - expression 12 operands: lhs = Counter(0), rhs = Expression(13, Add)
 - expression 13 operands: lhs = Expression(14, Add), rhs = Counter(6)
 - expression 14 operands: lhs = Counter(4), rhs = Counter(5)
-Number of file 0 mappings: 19
-- Code(Counter(0)) at (prev + 36, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10)
+Number of file 0 mappings: 23
+- Code(Counter(0)) at (prev + 36, 1) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 18)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 18)
     true  = c1
@@ -69,7 +76,8 @@ Number of file 0 mappings: 19
     true  = c3
     false = (c2 - c3)
 - Code(Counter(3)) at (prev + 0, 40) to (start + 0, 45)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
 - Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 18)
 - Branch { true: Counter(4), false: Expression(4, Sub) } at (prev + 0, 13) to (start + 0, 18)
@@ -87,13 +95,15 @@ Number of file 0 mappings: 19
     false = (c0 - ((c4 + c5) + c6))
 - Code(Expression(12, Sub)) at (prev + 0, 40) to (start + 0, 45)
     = (c0 - ((c4 + c5) + c6))
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c6
 
 Function name: lazy_boolean::nested_mixed
-Raw bytes (137): 0x[01, 01, 0d, 01, 05, 01, 1f, 05, 09, 05, 09, 1f, 0d, 05, 09, 1f, 0d, 05, 09, 01, 11, 11, 15, 01, 15, 01, 33, 15, 19, 13, 01, 31, 01, 01, 0e, 01, 04, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 05, 02, 00, 0e, 00, 13, 02, 00, 17, 00, 1d, 20, 09, 06, 00, 17, 00, 1d, 1f, 00, 23, 00, 28, 20, 0d, 1a, 00, 23, 00, 28, 1a, 00, 2c, 00, 33, 01, 01, 05, 00, 10, 01, 03, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 11, 22, 00, 0e, 00, 13, 11, 00, 17, 00, 1c, 20, 15, 26, 00, 17, 00, 1c, 2a, 00, 22, 00, 28, 20, 19, 2e, 00, 22, 00, 28, 19, 00, 2c, 00, 33, 01, 01, 05, 01, 02]
+Raw bytes (157): 0x[01, 01, 0d, 01, 05, 01, 1f, 05, 09, 05, 09, 1f, 0d, 05, 09, 1f, 0d, 05, 09, 01, 11, 11, 15, 01, 15, 01, 33, 15, 19, 17, 01, 31, 01, 00, 18, 01, 01, 05, 00, 0e, 01, 03, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 05, 02, 00, 0e, 00, 13, 02, 00, 17, 00, 1d, 20, 09, 06, 00, 17, 00, 1d, 1f, 00, 23, 00, 28, 20, 0d, 1a, 00, 23, 00, 28, 1a, 00, 2c, 00, 33, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 03, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 11, 22, 00, 0e, 00, 13, 11, 00, 17, 00, 1c, 20, 15, 26, 00, 17, 00, 1c, 2a, 00, 22, 00, 28, 20, 19, 2e, 00, 22, 00, 28, 19, 00, 2c, 00, 33, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/lazy-boolean.rs
 Number of expressions: 13
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Expression(7, Add)
@@ -108,9 +118,10 @@ Number of expressions: 13
 - expression 10 operands: lhs = Counter(0), rhs = Counter(5)
 - expression 11 operands: lhs = Counter(0), rhs = Expression(12, Add)
 - expression 12 operands: lhs = Counter(5), rhs = Counter(6)
-Number of file 0 mappings: 19
-- Code(Counter(0)) at (prev + 49, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10)
+Number of file 0 mappings: 23
+- Code(Counter(0)) at (prev + 49, 1) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 19)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 14) to (start + 0, 19)
     true  = c1
@@ -127,7 +138,8 @@ Number of file 0 mappings: 19
     false = ((c1 + c2) - c3)
 - Code(Expression(6, Sub)) at (prev + 0, 44) to (start + 0, 51)
     = ((c1 + c2) - c3)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
 - Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 19)
 - Branch { true: Counter(4), false: Expression(8, Sub) } at (prev + 0, 14) to (start + 0, 19)
@@ -143,6 +155,8 @@ Number of file 0 mappings: 19
     true  = c6
     false = (c0 - (c5 + c6))
 - Code(Counter(6)) at (prev + 0, 44) to (start + 0, 51)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c6
 
diff --git a/tests/coverage/branch/let-else.cov-map b/tests/coverage/branch/let-else.cov-map
index 78507a32638..61bedbfbff0 100644
--- a/tests/coverage/branch/let-else.cov-map
+++ b/tests/coverage/branch/let-else.cov-map
@@ -1,19 +1,24 @@
 Function name: let_else::let_else
-Raw bytes (43): 0x[01, 01, 01, 01, 05, 07, 01, 0c, 01, 01, 0e, 20, 02, 05, 03, 09, 00, 10, 02, 00, 0e, 00, 0f, 01, 00, 13, 00, 18, 05, 01, 09, 01, 0f, 02, 04, 05, 00, 0a, 01, 01, 01, 00, 02]
+Raw bytes (63): 0x[01, 01, 01, 01, 05, 0b, 01, 0c, 01, 00, 21, 01, 01, 05, 00, 0e, 20, 02, 05, 02, 09, 00, 10, 02, 00, 0e, 00, 0f, 01, 00, 13, 00, 18, 05, 01, 09, 00, 0c, 05, 00, 0d, 00, 13, 05, 01, 09, 00, 0f, 02, 03, 05, 00, 08, 02, 00, 09, 00, 0a, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/let-else.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14)
-- Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 3, 9) to (start + 0, 16)
+Number of file 0 mappings: 11
+- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 2, 9) to (start + 0, 16)
     true  = (c0 - c1)
     false = c1
 - Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 15)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 0, 19) to (start + 0, 24)
-- Code(Counter(1)) at (prev + 1, 9) to (start + 1, 15)
-- Code(Expression(0, Sub)) at (prev + 4, 5) to (start + 0, 10)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 12)
+- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 19)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Expression(0, Sub)) at (prev + 3, 5) to (start + 0, 8)
+    = (c0 - c1)
+- Code(Expression(0, Sub)) at (prev + 0, 9) to (start + 0, 10)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
diff --git a/tests/coverage/branch/match-arms.cov-map b/tests/coverage/branch/match-arms.cov-map
index ef71d12c8af..a2ed0d84ed6 100644
--- a/tests/coverage/branch/match-arms.cov-map
+++ b/tests/coverage/branch/match-arms.cov-map
@@ -1,7 +1,7 @@
 Function name: match_arms::guards
-Raw bytes (88): 0x[01, 01, 08, 15, 05, 19, 09, 1d, 0d, 21, 11, 01, 17, 1b, 11, 1f, 0d, 05, 09, 0c, 01, 30, 01, 01, 0e, 21, 03, 0b, 00, 10, 05, 01, 11, 00, 28, 20, 05, 02, 00, 17, 00, 1b, 09, 01, 11, 00, 28, 20, 09, 06, 00, 17, 00, 1b, 0d, 01, 11, 00, 28, 20, 0d, 0a, 00, 17, 00, 1b, 11, 01, 11, 00, 28, 20, 11, 0e, 00, 17, 00, 1b, 12, 01, 0e, 00, 15, 01, 03, 05, 01, 02]
+Raw bytes (158): 0x[01, 01, 08, 15, 05, 19, 09, 1d, 0d, 21, 11, 01, 17, 1b, 11, 1f, 0d, 05, 09, 1a, 01, 30, 01, 00, 23, 01, 01, 05, 00, 0e, 21, 02, 0b, 00, 10, 05, 01, 11, 00, 12, 20, 05, 02, 00, 17, 00, 1b, 05, 00, 1a, 00, 1b, 05, 00, 1f, 00, 26, 05, 00, 27, 00, 28, 09, 01, 11, 00, 12, 20, 09, 06, 00, 17, 00, 1b, 09, 00, 1a, 00, 1b, 09, 00, 1f, 00, 26, 09, 00, 27, 00, 28, 0d, 01, 11, 00, 12, 20, 0d, 0a, 00, 17, 00, 1b, 0d, 00, 1a, 00, 1b, 0d, 00, 1f, 00, 26, 0d, 00, 27, 00, 28, 11, 01, 11, 00, 12, 20, 11, 0e, 00, 17, 00, 1b, 11, 00, 1a, 00, 1b, 11, 00, 1f, 00, 26, 11, 00, 27, 00, 28, 12, 01, 0e, 00, 15, 01, 03, 05, 00, 0c, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/match-arms.rs
 Number of expressions: 8
 - expression 0 operands: lhs = Counter(5), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(6), rhs = Counter(2)
@@ -11,70 +11,103 @@ Number of expressions: 8
 - expression 5 operands: lhs = Expression(6, Add), rhs = Counter(4)
 - expression 6 operands: lhs = Expression(7, Add), rhs = Counter(3)
 - expression 7 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 12
-- Code(Counter(0)) at (prev + 48, 1) to (start + 1, 14)
-- Code(Counter(8)) at (prev + 3, 11) to (start + 0, 16)
-- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 40)
+Number of file 0 mappings: 26
+- Code(Counter(0)) at (prev + 48, 1) to (start + 0, 35)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(8)) at (prev + 2, 11) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 18)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 23) to (start + 0, 27)
     true  = c1
     false = (c5 - c1)
-- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 40)
+- Code(Counter(1)) at (prev + 0, 26) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 0, 31) to (start + 0, 38)
+- Code(Counter(1)) at (prev + 0, 39) to (start + 0, 40)
+- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 18)
 - Branch { true: Counter(2), false: Expression(1, Sub) } at (prev + 0, 23) to (start + 0, 27)
     true  = c2
     false = (c6 - c2)
-- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 40)
+- Code(Counter(2)) at (prev + 0, 26) to (start + 0, 27)
+- Code(Counter(2)) at (prev + 0, 31) to (start + 0, 38)
+- Code(Counter(2)) at (prev + 0, 39) to (start + 0, 40)
+- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 18)
 - Branch { true: Counter(3), false: Expression(2, Sub) } at (prev + 0, 23) to (start + 0, 27)
     true  = c3
     false = (c7 - c3)
-- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 40)
+- Code(Counter(3)) at (prev + 0, 26) to (start + 0, 27)
+- Code(Counter(3)) at (prev + 0, 31) to (start + 0, 38)
+- Code(Counter(3)) at (prev + 0, 39) to (start + 0, 40)
+- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 18)
 - Branch { true: Counter(4), false: Expression(3, Sub) } at (prev + 0, 23) to (start + 0, 27)
     true  = c4
     false = (c8 - c4)
+- Code(Counter(4)) at (prev + 0, 26) to (start + 0, 27)
+- Code(Counter(4)) at (prev + 0, 31) to (start + 0, 38)
+- Code(Counter(4)) at (prev + 0, 39) to (start + 0, 40)
 - Code(Expression(4, Sub)) at (prev + 1, 14) to (start + 0, 21)
     = (c0 - (((c1 + c2) + c3) + c4))
-- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c8
 
 Function name: match_arms::match_arms
-Raw bytes (45): 0x[01, 01, 03, 01, 07, 0b, 0d, 05, 09, 07, 01, 18, 01, 01, 0e, 01, 03, 0b, 00, 10, 05, 01, 11, 00, 20, 09, 01, 11, 00, 20, 0d, 01, 11, 00, 20, 02, 01, 11, 00, 20, 01, 03, 05, 01, 02]
+Raw bytes (95): 0x[01, 01, 03, 01, 07, 0b, 0d, 05, 09, 11, 01, 18, 01, 00, 1b, 01, 01, 05, 00, 0e, 01, 02, 0b, 00, 10, 05, 01, 11, 00, 12, 05, 00, 17, 00, 1e, 05, 00, 1f, 00, 20, 09, 01, 11, 00, 12, 09, 00, 17, 00, 1e, 09, 00, 1f, 00, 20, 0d, 01, 11, 00, 12, 0d, 00, 17, 00, 1e, 0d, 00, 1f, 00, 20, 02, 01, 11, 00, 12, 02, 00, 17, 00, 1e, 02, 00, 1f, 00, 20, 01, 03, 05, 00, 0c, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/match-arms.rs
 Number of expressions: 3
 - expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add)
 - expression 1 operands: lhs = Expression(2, Add), rhs = Counter(3)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 24, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 11) to (start + 0, 16)
-- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 32)
-- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 32)
-- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 32)
-- Code(Expression(0, Sub)) at (prev + 1, 17) to (start + 0, 32)
+Number of file 0 mappings: 17
+- Code(Counter(0)) at (prev + 24, 1) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 11) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 18)
+- Code(Counter(1)) at (prev + 0, 23) to (start + 0, 30)
+- Code(Counter(1)) at (prev + 0, 31) to (start + 0, 32)
+- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 18)
+- Code(Counter(2)) at (prev + 0, 23) to (start + 0, 30)
+- Code(Counter(2)) at (prev + 0, 31) to (start + 0, 32)
+- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 18)
+- Code(Counter(3)) at (prev + 0, 23) to (start + 0, 30)
+- Code(Counter(3)) at (prev + 0, 31) to (start + 0, 32)
+- Code(Expression(0, Sub)) at (prev + 1, 17) to (start + 0, 18)
     = (c0 - ((c1 + c2) + c3))
-- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
+- Code(Expression(0, Sub)) at (prev + 0, 23) to (start + 0, 30)
+    = (c0 - ((c1 + c2) + c3))
+- Code(Expression(0, Sub)) at (prev + 0, 31) to (start + 0, 32)
+    = (c0 - ((c1 + c2) + c3))
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c3
 
 Function name: match_arms::or_patterns
-Raw bytes (57): 0x[01, 01, 04, 05, 09, 01, 0b, 03, 0d, 01, 03, 09, 01, 25, 01, 01, 0e, 01, 03, 0b, 00, 10, 05, 01, 11, 00, 12, 09, 00, 1e, 00, 1f, 03, 00, 24, 00, 2d, 0d, 01, 11, 00, 12, 06, 00, 1e, 00, 1f, 0e, 00, 24, 00, 2d, 01, 03, 05, 01, 02]
+Raw bytes (79): 0x[01, 01, 05, 05, 09, 01, 0b, 03, 0d, 01, 03, 01, 03, 0d, 01, 25, 01, 00, 1c, 01, 01, 05, 00, 0e, 01, 02, 0b, 00, 10, 05, 01, 11, 00, 12, 09, 00, 1e, 00, 1f, 03, 00, 24, 00, 2b, 03, 00, 2c, 00, 2d, 0d, 01, 11, 00, 12, 06, 00, 1e, 00, 1f, 12, 00, 24, 00, 2b, 12, 00, 2c, 00, 2d, 01, 03, 05, 00, 0c, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
-Number of expressions: 4
+- file 0 => $DIR/match-arms.rs
+Number of expressions: 5
 - expression 0 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
 - expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3)
 - expression 3 operands: lhs = Counter(0), rhs = Expression(0, Add)
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 37, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 11) to (start + 0, 16)
+- expression 4 operands: lhs = Counter(0), rhs = Expression(0, Add)
+Number of file 0 mappings: 13
+- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 11) to (start + 0, 16)
 - Code(Counter(1)) at (prev + 1, 17) to (start + 0, 18)
 - Code(Counter(2)) at (prev + 0, 30) to (start + 0, 31)
-- Code(Expression(0, Add)) at (prev + 0, 36) to (start + 0, 45)
+- Code(Expression(0, Add)) at (prev + 0, 36) to (start + 0, 43)
+    = (c1 + c2)
+- Code(Expression(0, Add)) at (prev + 0, 44) to (start + 0, 45)
     = (c1 + c2)
 - Code(Counter(3)) at (prev + 1, 17) to (start + 0, 18)
 - Code(Expression(1, Sub)) at (prev + 0, 30) to (start + 0, 31)
     = (c0 - ((c1 + c2) + c3))
-- Code(Expression(3, Sub)) at (prev + 0, 36) to (start + 0, 45)
+- Code(Expression(4, Sub)) at (prev + 0, 36) to (start + 0, 43)
+    = (c0 - (c1 + c2))
+- Code(Expression(4, Sub)) at (prev + 0, 44) to (start + 0, 45)
     = (c0 - (c1 + c2))
-- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c3
 
diff --git a/tests/coverage/branch/match-trivial.cov-map b/tests/coverage/branch/match-trivial.cov-map
index 1b0c6d12e3d..a88e89523ae 100644
--- a/tests/coverage/branch/match-trivial.cov-map
+++ b/tests/coverage/branch/match-trivial.cov-map
@@ -1,19 +1,24 @@
 Function name: match_trivial::_uninhabited (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 16, 01, 01, 0e]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 16, 01, 00, 20, 00, 01, 05, 00, 0e]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/match-trivial.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 22, 1) to (start + 1, 14)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 22, 1) to (start + 0, 32)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 14)
 Highest counter ID seen: (none)
 
 Function name: match_trivial::trivial
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 1e, 01, 01, 0e, 01, 03, 0b, 05, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 1e, 01, 00, 17, 01, 01, 05, 00, 0e, 01, 02, 0b, 00, 0c, 01, 01, 1b, 00, 22, 01, 03, 05, 00, 0c, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/match-trivial.rs
 Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 11) to (start + 5, 2)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 30, 1) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 11) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 27) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/branch/match-trivial.coverage b/tests/coverage/branch/match-trivial.coverage
index 4ffb172e1b6..6e7bf2d29ab 100644
--- a/tests/coverage/branch/match-trivial.coverage
+++ b/tests/coverage/branch/match-trivial.coverage
@@ -32,8 +32,8 @@
    LL|       |
    LL|      1|    match x {
    LL|      1|        Trivial::Value => consume("trivial"),
-   LL|      1|    }
-   LL|      1|
+   LL|       |    }
+   LL|       |
    LL|      1|    consume("done");
    LL|      1|}
    LL|       |
diff --git a/tests/coverage/branch/no-mir-spans.cov-map b/tests/coverage/branch/no-mir-spans.cov-map
index 8fb44ef30fd..4f893cba1f8 100644
--- a/tests/coverage/branch/no-mir-spans.cov-map
+++ b/tests/coverage/branch/no-mir-spans.cov-map
@@ -1,40 +1,40 @@
 Function name: no_mir_spans::while_cond
-Raw bytes (18): 0x[01, 01, 01, 05, 01, 02, 01, 10, 01, 00, 11, 20, 02, 01, 04, 0b, 00, 10]
+Raw bytes (18): 0x[01, 01, 01, 05, 01, 02, 01, 10, 01, 00, 10, 20, 02, 01, 04, 0b, 00, 10]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/no-mir-spans.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 16)
 - Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 4, 11) to (start + 0, 16)
     true  = (c1 - c0)
     false = c0
 Highest counter ID seen: c0
 
 Function name: no_mir_spans::while_cond_not
-Raw bytes (18): 0x[01, 01, 01, 05, 01, 02, 01, 19, 01, 00, 15, 20, 02, 01, 04, 0b, 00, 14]
+Raw bytes (18): 0x[01, 01, 01, 05, 01, 02, 01, 19, 01, 00, 14, 20, 02, 01, 04, 0b, 00, 14]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/no-mir-spans.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 25, 1) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 25, 1) to (start + 0, 20)
 - Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 4, 11) to (start + 0, 20)
     true  = (c1 - c0)
     false = c0
 Highest counter ID seen: c0
 
 Function name: no_mir_spans::while_op_and
-Raw bytes (31): 0x[01, 01, 04, 09, 05, 09, 01, 0f, 09, 01, 05, 03, 01, 22, 01, 00, 13, 20, 05, 02, 05, 0b, 00, 10, 20, 06, 0a, 00, 14, 00, 19]
+Raw bytes (31): 0x[01, 01, 04, 09, 05, 09, 01, 0f, 09, 01, 05, 03, 01, 22, 01, 00, 12, 20, 05, 02, 05, 0b, 00, 10, 20, 06, 0a, 00, 14, 00, 19]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/no-mir-spans.rs
 Number of expressions: 4
 - expression 0 operands: lhs = Counter(2), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(2), rhs = Counter(0)
 - expression 2 operands: lhs = Expression(3, Add), rhs = Counter(2)
 - expression 3 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 34, 1) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 34, 1) to (start + 0, 18)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 5, 11) to (start + 0, 16)
     true  = c1
     false = (c2 - c1)
@@ -44,15 +44,15 @@ Number of file 0 mappings: 3
 Highest counter ID seen: c1
 
 Function name: no_mir_spans::while_op_or
-Raw bytes (29): 0x[01, 01, 03, 09, 05, 09, 0b, 01, 05, 03, 01, 2d, 01, 00, 12, 20, 05, 02, 05, 0b, 00, 10, 20, 06, 01, 00, 14, 00, 19]
+Raw bytes (29): 0x[01, 01, 03, 09, 05, 09, 0b, 01, 05, 03, 01, 2d, 01, 00, 11, 20, 05, 02, 05, 0b, 00, 10, 20, 06, 01, 00, 14, 00, 19]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/no-mir-spans.rs
 Number of expressions: 3
 - expression 0 operands: lhs = Counter(2), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(2), rhs = Expression(2, Add)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 45, 1) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 45, 1) to (start + 0, 17)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 5, 11) to (start + 0, 16)
     true  = c1
     false = (c2 - c1)
diff --git a/tests/coverage/branch/while.cov-map b/tests/coverage/branch/while.cov-map
index 67746af051b..767a7e46495 100644
--- a/tests/coverage/branch/while.cov-map
+++ b/tests/coverage/branch/while.cov-map
@@ -1,12 +1,14 @@
 Function name: while::while_cond
-Raw bytes (38): 0x[01, 01, 01, 05, 01, 06, 01, 0c, 01, 01, 0e, 01, 03, 09, 00, 12, 05, 01, 0b, 00, 10, 20, 02, 01, 00, 0b, 00, 10, 02, 00, 11, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (48): 0x[01, 01, 01, 05, 01, 08, 01, 0c, 01, 00, 10, 01, 01, 05, 00, 0e, 01, 02, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0b, 00, 10, 20, 02, 01, 00, 0b, 00, 10, 02, 00, 11, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/while.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(1), rhs = Counter(0)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 18)
+Number of file 0 mappings: 8
+- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
 - Code(Counter(1)) at (prev + 1, 11) to (start + 0, 16)
 - Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 0, 11) to (start + 0, 16)
     true  = (c1 - c0)
@@ -17,14 +19,16 @@ Number of file 0 mappings: 6
 Highest counter ID seen: c1
 
 Function name: while::while_cond_not
-Raw bytes (38): 0x[01, 01, 01, 05, 01, 06, 01, 15, 01, 01, 0e, 01, 03, 09, 00, 12, 05, 01, 0b, 00, 14, 20, 02, 01, 00, 0b, 00, 14, 02, 00, 15, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (48): 0x[01, 01, 01, 05, 01, 08, 01, 15, 01, 00, 14, 01, 01, 05, 00, 0e, 01, 02, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0b, 00, 14, 20, 02, 01, 00, 0b, 00, 14, 02, 00, 15, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/while.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(1), rhs = Counter(0)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 21, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 18)
+Number of file 0 mappings: 8
+- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
 - Code(Counter(1)) at (prev + 1, 11) to (start + 0, 20)
 - Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 0, 11) to (start + 0, 20)
     true  = (c1 - c0)
@@ -35,19 +39,23 @@ Number of file 0 mappings: 6
 Highest counter ID seen: c1
 
 Function name: while::while_op_and
-Raw bytes (58): 0x[01, 01, 05, 05, 09, 05, 01, 0f, 05, 01, 09, 05, 01, 08, 01, 1e, 01, 01, 0e, 01, 03, 09, 01, 12, 05, 02, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 09, 00, 14, 00, 19, 20, 12, 0a, 00, 14, 00, 19, 12, 00, 1a, 03, 06, 01, 04, 01, 00, 02]
+Raw bytes (78): 0x[01, 01, 05, 05, 09, 05, 01, 0f, 05, 01, 09, 05, 01, 0c, 01, 1e, 01, 00, 12, 01, 01, 05, 00, 0e, 01, 02, 09, 00, 0e, 01, 00, 11, 00, 12, 01, 01, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 09, 00, 14, 00, 19, 20, 12, 0a, 00, 14, 00, 19, 12, 00, 1a, 03, 06, 01, 04, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/while.rs
 Number of expressions: 5
 - expression 0 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(0)
 - expression 2 operands: lhs = Expression(3, Add), rhs = Counter(1)
 - expression 3 operands: lhs = Counter(0), rhs = Counter(2)
 - expression 4 operands: lhs = Counter(1), rhs = Counter(0)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 9) to (start + 1, 18)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 16)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 30, 1) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
+- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 16)
 - Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 11) to (start + 0, 16)
     true  = c2
     false = (c1 - c2)
@@ -61,18 +69,22 @@ Number of file 0 mappings: 8
 Highest counter ID seen: c2
 
 Function name: while::while_op_or
-Raw bytes (56): 0x[01, 01, 04, 05, 09, 05, 0b, 01, 09, 05, 01, 08, 01, 29, 01, 01, 0e, 01, 03, 09, 01, 12, 05, 02, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 02, 00, 14, 00, 19, 20, 06, 01, 00, 14, 00, 19, 0e, 00, 1a, 03, 06, 01, 04, 01, 00, 02]
+Raw bytes (76): 0x[01, 01, 04, 05, 09, 05, 0b, 01, 09, 05, 01, 0c, 01, 29, 01, 00, 11, 01, 01, 05, 00, 0e, 01, 02, 09, 00, 0e, 01, 00, 11, 00, 12, 01, 01, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 02, 00, 14, 00, 19, 20, 06, 01, 00, 14, 00, 19, 0e, 00, 1a, 03, 06, 01, 04, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/while.rs
 Number of expressions: 4
 - expression 0 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(2)
 - expression 3 operands: lhs = Counter(1), rhs = Counter(0)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 41, 1) to (start + 1, 14)
-- Code(Counter(0)) at (prev + 3, 9) to (start + 1, 18)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 16)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 41, 1) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
+- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 16)
 - Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 11) to (start + 0, 16)
     true  = c2
     false = (c1 - c2)
diff --git a/tests/coverage/closure.cov-map b/tests/coverage/closure.cov-map
index 2d784ba09b6..5f7e4ce58e9 100644
--- a/tests/coverage/closure.cov-map
+++ b/tests/coverage/closure.cov-map
@@ -1,18 +1,56 @@
 Function name: closure::main
-Raw bytes (126): 0x[01, 01, 01, 01, 05, 18, 01, 09, 01, 0d, 1b, 01, 1a, 05, 02, 0a, 01, 0c, 05, 11, 1b, 01, 1e, 05, 02, 0a, 01, 0c, 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]
+Raw bytes (336): 0x[01, 01, 01, 01, 05, 42, 01, 09, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 11, 01, 00, 14, 00, 1c, 01, 02, 09, 00, 18, 01, 00, 1b, 00, 43, 01, 01, 05, 00, 0d, 01, 01, 09, 00, 20, 01, 02, 09, 00, 14, 01, 02, 0d, 00, 1b, 01, 0d, 05, 00, 10, 01, 00, 13, 00, 3b, 01, 02, 09, 00, 0a, 01, 0a, 05, 00, 0d, 01, 01, 09, 00, 20, 01, 02, 09, 00, 14, 01, 02, 0d, 00, 1b, 01, 02, 0d, 00, 0e, 01, 04, 05, 00, 10, 01, 00, 13, 00, 17, 01, 01, 05, 00, 0d, 01, 01, 09, 00, 20, 01, 02, 09, 00, 14, 01, 02, 0d, 00, 1b, 01, 0d, 05, 00, 10, 01, 00, 13, 00, 17, 01, 02, 09, 00, 0a, 01, 0a, 05, 00, 0d, 01, 01, 09, 00, 20, 01, 02, 09, 00, 14, 01, 02, 0d, 00, 1b, 01, 02, 0d, 00, 0e, 01, 05, 09, 00, 16, 01, 0a, 05, 00, 0d, 01, 01, 09, 00, 28, 01, 02, 09, 00, 1a, 01, 01, 0e, 00, 12, 01, 01, 0e, 00, 11, 01, 02, 0d, 00, 1a, 01, 02, 0e, 00, 15, 01, 04, 09, 00, 18, 01, 0c, 09, 00, 16, 01, 00, 19, 00, 1b, 01, 01, 09, 00, 1e, 01, 03, 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, 05, 01, 09, 00, 30, 02, 03, 05, 00, 06, 01, 01, 05, 00, 28, 01, 01, 05, 00, 46, 01, 01, 05, 00, 43, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 24
-- Code(Counter(0)) at (prev + 9, 1) to (start + 13, 27)
-- Code(Counter(0)) at (prev + 26, 5) to (start + 2, 10)
-- Code(Counter(0)) at (prev + 12, 5) to (start + 17, 27)
-- Code(Counter(0)) at (prev + 30, 5) to (start + 2, 10)
-- Code(Counter(0)) at (prev + 12, 5) to (start + 12, 22)
-- Code(Counter(0)) at (prev + 22, 5) to (start + 13, 24)
-- Code(Counter(0)) at (prev + 25, 9) to (start + 1, 30)
-- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 41)
+Number of file 0 mappings: 66
+- Code(Counter(0)) at (prev + 9, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 0, 27) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 13, 5) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 59)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 13, 5) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 5, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 40)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 14) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 14) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 2, 14) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 12, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 41)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 45)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 36)
 - Code(Counter(0)) at (prev + 5, 9) to (start + 0, 36)
@@ -27,238 +65,277 @@ 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, 5) to (start + 0, 6)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 48)
+- Code(Expression(0, Sub)) at (prev + 3, 5) to (start + 0, 6)
     = (c0 - c1)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 3, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 40)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 70)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 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, 09, 00, 0a, 01, 01, 09, 01, 06]
+Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 28, 05, 00, 06, 01, 01, 0d, 00, 1a, 01, 00, 1d, 00, 1e, 01, 01, 0c, 00, 14, 05, 00, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 00, 17, 01, 00, 18, 00, 20, 01, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(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)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 40, 5) to (start + 0, 6)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 0, 29) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 20)
+- Code(Counter(1)) at (prev + 0, 21) to (start + 2, 10)
 - 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)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: c1
 
 Function name: closure::main::{closure#10} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 00, 9b, 01, 07, 00, 21]
+Raw bytes (25): 0x[01, 01, 00, 04, 00, 9b, 01, 07, 00, 08, 00, 00, 09, 00, 11, 00, 00, 12, 00, 1e, 00, 00, 20, 00, 21]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 155, 7) to (start + 0, 33)
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 155, 7) to (start + 0, 8)
+- Code(Zero) at (prev + 0, 9) to (start + 0, 17)
+- Code(Zero) at (prev + 0, 18) to (start + 0, 30)
+- Code(Zero) at (prev + 0, 32) to (start + 0, 33)
 Highest counter ID seen: (none)
 
 Function name: closure::main::{closure#11} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 00, 9f, 01, 07, 00, 21]
+Raw bytes (25): 0x[01, 01, 00, 04, 00, 9f, 01, 07, 00, 08, 00, 00, 09, 00, 11, 00, 00, 12, 00, 1e, 00, 00, 20, 00, 21]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 159, 7) to (start + 0, 33)
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 159, 7) to (start + 0, 8)
+- Code(Zero) at (prev + 0, 9) to (start + 0, 17)
+- Code(Zero) at (prev + 0, 18) to (start + 0, 30)
+- Code(Zero) at (prev + 0, 32) to (start + 0, 33)
 Highest counter ID seen: (none)
 
 Function name: closure::main::{closure#12} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 00, a7, 01, 01, 00, 17]
+Raw bytes (10): 0x[01, 01, 00, 01, 00, a7, 01, 0a, 00, 16]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 167, 1) to (start + 0, 23)
+- Code(Zero) at (prev + 167, 10) to (start + 0, 22)
 Highest counter ID seen: (none)
 
 Function name: closure::main::{closure#13} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 00, ac, 01, 0d, 02, 0e]
+Raw bytes (10): 0x[01, 01, 00, 01, 00, ad, 01, 11, 00, 1d]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 172, 13) to (start + 2, 14)
+- Code(Zero) at (prev + 173, 17) to (start + 0, 29)
 Highest counter ID seen: (none)
 
 Function name: closure::main::{closure#14}
-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]
+Raw bytes (27): 0x[01, 01, 01, 01, 05, 04, 01, b4, 01, 11, 00, 21, 01, 01, 14, 00, 1b, 05, 00, 1e, 00, 25, 02, 00, 2f, 00, 33]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-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)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 180, 17) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 37)
 - Code(Expression(0, Sub)) at (prev + 0, 47) to (start + 0, 51)
     = (c0 - c1)
 Highest counter ID seen: c1
 
 Function name: closure::main::{closure#15}
-Raw bytes (37): 0x[01, 01, 01, 01, 05, 06, 01, bb, 01, 09, 00, 0a, 01, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 02, 09, 00, 0a]
+Raw bytes (42): 0x[01, 01, 01, 01, 05, 07, 01, bb, 01, 09, 00, 0a, 01, 01, 0d, 00, 15, 01, 01, 11, 00, 21, 01, 01, 14, 00, 1b, 05, 00, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 02, 09, 00, 0a]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 6
+Number of file 0 mappings: 7
 - Code(Counter(0)) at (prev + 187, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 1, 13) to (start + 0, 21)
-- Code(Counter(0)) at (prev + 1, 17) to (start + 1, 27)
-- Code(Counter(1)) at (prev + 1, 30) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 17) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 37)
 - Code(Expression(0, Sub)) at (prev + 0, 47) to (start + 0, 51)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
 Highest counter ID seen: c1
 
 Function name: closure::main::{closure#16}
-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]
+Raw bytes (27): 0x[01, 01, 01, 01, 05, 04, 01, c6, 01, 11, 00, 21, 01, 01, 14, 00, 1b, 05, 00, 1e, 00, 25, 02, 00, 2f, 00, 33]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-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)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 198, 17) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 37)
 - Code(Expression(0, Sub)) at (prev + 0, 47) to (start + 0, 51)
     = (c0 - c1)
 Highest counter ID seen: c1
 
 Function name: closure::main::{closure#17}
-Raw bytes (37): 0x[01, 01, 01, 01, 05, 06, 01, cd, 01, 09, 00, 0a, 01, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 02, 09, 00, 0a]
+Raw bytes (42): 0x[01, 01, 01, 01, 05, 07, 01, cd, 01, 09, 00, 0a, 01, 01, 0d, 00, 15, 01, 01, 11, 00, 21, 01, 01, 14, 00, 1b, 05, 00, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 02, 09, 00, 0a]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 6
+Number of file 0 mappings: 7
 - Code(Counter(0)) at (prev + 205, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 1, 13) to (start + 0, 21)
-- Code(Counter(0)) at (prev + 1, 17) to (start + 1, 27)
-- Code(Counter(1)) at (prev + 1, 30) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 17) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 37)
 - Code(Expression(0, Sub)) at (prev + 0, 47) to (start + 0, 51)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
 Highest counter ID seen: c1
 
 Function name: closure::main::{closure#18}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 19, 0d, 02, 1c, 05, 02, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 01, 0e]
+Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 19, 0d, 00, 0e, 01, 01, 15, 00, 22, 01, 00, 25, 00, 26, 01, 01, 14, 00, 1c, 05, 00, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 00, 1f, 01, 00, 20, 00, 28, 01, 01, 0d, 00, 0e]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 25, 13) to (start + 2, 28)
-- Code(Counter(1)) at (prev + 2, 29) to (start + 2, 18)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 25, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 1, 21) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 0, 37) to (start + 0, 38)
+- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 28)
+- Code(Counter(1)) at (prev + 0, 29) to (start + 2, 18)
 - 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)
+- Code(Counter(0)) at (prev + 1, 17) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 0, 32) to (start + 0, 40)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14)
 Highest counter ID seen: c1
 
 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, 11, 00, 12, 01, 01, 11, 01, 0e]
+Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 43, 0d, 00, 0e, 01, 01, 15, 00, 22, 01, 00, 25, 00, 26, 01, 01, 14, 00, 1c, 05, 00, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 00, 1f, 01, 00, 20, 00, 28, 01, 01, 0d, 00, 0e]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(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)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 67, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 1, 21) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 0, 37) to (start + 0, 38)
+- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 28)
+- Code(Counter(1)) at (prev + 0, 29) to (start + 2, 18)
 - 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)
+- Code(Counter(0)) at (prev + 1, 17) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 0, 32) to (start + 0, 40)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 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, 09, 00, 0a, 01, 01, 09, 01, 06]
+Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 52, 05, 00, 06, 01, 01, 0d, 00, 1a, 01, 00, 1d, 00, 1e, 01, 01, 0c, 00, 14, 05, 00, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 00, 17, 01, 00, 18, 00, 20, 01, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(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)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 82, 5) to (start + 0, 6)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 0, 29) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 20)
+- Code(Counter(1)) at (prev + 0, 21) to (start + 2, 10)
 - 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)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 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, 09, 00, 0a, 01, 01, 09, 01, 06]
+Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 68, 05, 00, 06, 01, 01, 0d, 00, 1a, 01, 00, 1d, 00, 1e, 01, 01, 0c, 00, 14, 05, 00, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 11, 00, 17, 01, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(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)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 104, 5) to (start + 0, 6)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 0, 29) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 20)
+- Code(Counter(1)) at (prev + 0, 21) to (start + 2, 10)
 - 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)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 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, 09, 00, 0a, 00, 01, 09, 01, 06]
+Raw bytes (40): 0x[01, 01, 00, 07, 00, 81, 01, 05, 00, 06, 00, 01, 0c, 00, 14, 00, 00, 15, 02, 0a, 00, 02, 09, 00, 0a, 00, 01, 09, 00, 23, 00, 00, 24, 00, 2c, 00, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 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)
+Number of file 0 mappings: 7
+- Code(Zero) at (prev + 129, 5) to (start + 0, 6)
+- Code(Zero) at (prev + 1, 12) to (start + 0, 20)
+- Code(Zero) at (prev + 0, 21) to (start + 2, 10)
 - 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)
-
-Function name: closure::main::{closure#4} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 00, 89, 01, 35, 00, 43]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 137, 53) to (start + 0, 67)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 35)
+- Code(Zero) at (prev + 0, 36) to (start + 0, 44)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: (none)
 
 Function name: closure::main::{closure#5}
-Raw bytes (10): 0x[01, 01, 00, 01, 01, 8c, 01, 3d, 00, 4f]
+Raw bytes (10): 0x[01, 01, 00, 01, 01, 8c, 01, 46, 00, 4e]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 140, 61) to (start + 0, 79)
+- Code(Counter(0)) at (prev + 140, 70) to (start + 0, 78)
 Highest counter ID seen: c0
 
 Function name: closure::main::{closure#6}
-Raw bytes (10): 0x[01, 01, 00, 01, 01, 8d, 01, 41, 00, 57]
+Raw bytes (10): 0x[01, 01, 00, 01, 01, 8d, 01, 4a, 00, 56]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 141, 65) to (start + 0, 87)
+- Code(Counter(0)) at (prev + 141, 74) to (start + 0, 86)
 Highest counter ID seen: c0
 
 Function name: closure::main::{closure#7} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 00, 8e, 01, 3b, 00, 51]
+Raw bytes (10): 0x[01, 01, 00, 01, 00, 8e, 01, 44, 00, 50]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 142, 59) to (start + 0, 81)
+- Code(Zero) at (prev + 142, 68) to (start + 0, 80)
 Highest counter ID seen: (none)
 
 Function name: closure::main::{closure#8} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 00, 93, 01, 3b, 00, 55]
+Raw bytes (25): 0x[01, 01, 00, 04, 00, 93, 01, 3b, 00, 3c, 00, 00, 3d, 00, 45, 00, 00, 46, 00, 52, 00, 00, 54, 00, 55]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 147, 59) to (start + 0, 85)
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 147, 59) to (start + 0, 60)
+- Code(Zero) at (prev + 0, 61) to (start + 0, 69)
+- Code(Zero) at (prev + 0, 70) to (start + 0, 82)
+- Code(Zero) at (prev + 0, 84) to (start + 0, 85)
 Highest counter ID seen: (none)
 
 Function name: closure::main::{closure#9} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 00, 95, 01, 38, 02, 06]
+Raw bytes (25): 0x[01, 01, 00, 04, 00, 95, 01, 38, 00, 39, 00, 01, 09, 00, 11, 00, 00, 12, 00, 1e, 00, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 149, 56) to (start + 2, 6)
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 149, 56) to (start + 0, 57)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 17)
+- Code(Zero) at (prev + 0, 18) to (start + 0, 30)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: (none)
 
diff --git a/tests/coverage/closure.coverage b/tests/coverage/closure.coverage
index 2deeb9806c4..14285269228 100644
--- a/tests/coverage/closure.coverage
+++ b/tests/coverage/closure.coverage
@@ -7,18 +7,18 @@
    LL|       |
    LL|       |#[rustfmt::skip]
    LL|      1|fn main() {
-   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-   LL|      1|    // dependent conditions.
+   LL|       |    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|       |    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|       |    // dependent conditions.
    LL|      1|    let is_true = std::env::args().len() == 1;
    LL|      1|    let is_false = !is_true;
-   LL|      1|
+   LL|       |
    LL|      1|    let mut some_string = Some(String::from("the string content"));
    LL|      1|    println!(
    LL|      1|        "The string or alt: {}"
-   LL|      1|        ,
+   LL|       |        ,
    LL|      1|        some_string
-   LL|      1|            .
+   LL|       |            .
    LL|      1|            unwrap_or_else
    LL|       |        (
    LL|       |            ||
@@ -33,7 +33,7 @@
    LL|       |    );
    LL|       |
    LL|      1|    some_string = Some(String::from("the string content"));
-   LL|      1|    let
+   LL|       |    let
    LL|      1|        a
    LL|       |    =
    LL|       |        ||
@@ -46,21 +46,21 @@
    LL|      0|    };
    LL|      1|    println!(
    LL|      1|        "The string or alt: {}"
-   LL|      1|        ,
+   LL|       |        ,
    LL|      1|        some_string
-   LL|      1|            .
+   LL|       |            .
    LL|      1|            unwrap_or_else
-   LL|      1|        (
+   LL|       |        (
    LL|      1|            a
-   LL|      1|        )
-   LL|      1|    );
-   LL|      1|
+   LL|       |        )
+   LL|       |    );
+   LL|       |
    LL|      1|    some_string = None;
    LL|      1|    println!(
    LL|      1|        "The string or alt: {}"
-   LL|      1|        ,
+   LL|       |        ,
    LL|      1|        some_string
-   LL|      1|            .
+   LL|       |            .
    LL|      1|            unwrap_or_else
    LL|       |        (
    LL|       |            ||
@@ -75,7 +75,7 @@
    LL|       |    );
    LL|       |
    LL|      1|    some_string = None;
-   LL|      1|    let
+   LL|       |    let
    LL|      1|        a
    LL|       |    =
    LL|       |        ||
@@ -88,16 +88,16 @@
    LL|      1|    };
    LL|      1|    println!(
    LL|      1|        "The string or alt: {}"
-   LL|      1|        ,
+   LL|       |        ,
    LL|      1|        some_string
-   LL|      1|            .
+   LL|       |            .
    LL|      1|            unwrap_or_else
-   LL|      1|        (
+   LL|       |        (
    LL|      1|            a
-   LL|      1|        )
-   LL|      1|    );
-   LL|      1|
-   LL|      1|    let
+   LL|       |        )
+   LL|       |    );
+   LL|       |
+   LL|       |    let
    LL|      1|        quote_closure
    LL|       |    =
    LL|       |        |val|
@@ -110,17 +110,17 @@
    LL|      5|    };
    LL|      1|    println!(
    LL|      1|        "Repeated, quoted string: {:?}"
-   LL|      1|        ,
+   LL|       |        ,
    LL|      1|        std::iter::repeat("repeat me")
    LL|      1|            .take(5)
    LL|      1|            .map
-   LL|      1|        (
+   LL|       |        (
    LL|      1|            quote_closure
-   LL|      1|        )
+   LL|       |        )
    LL|      1|            .collect::<Vec<_>>()
-   LL|      1|    );
-   LL|      1|
-   LL|      1|    let
+   LL|       |    );
+   LL|       |
+   LL|       |    let
    LL|      1|        _unused_closure
    LL|       |    =
    LL|       |        |
@@ -135,22 +135,22 @@
    LL|       |
    LL|      1|    let mut countdown = 10;
    LL|      1|    let _short_unused_closure = | _unused_arg: u8 | countdown += 1;
-                                                                  ^0
    LL|       |
    LL|       |
    LL|      1|    let short_used_covered_closure_macro = | used_arg: u8 | println!("called");
    LL|      1|    let short_used_not_covered_closure_macro = | used_arg: u8 | println!("not called");
-                                                                              ^0
+                                                                                       ^0
    LL|      1|    let _short_unused_closure_macro = | _unused_arg: u8 | println!("not called");
-                                                                        ^0
+                                                                                 ^0
    LL|       |
    LL|       |
    LL|       |
    LL|       |
    LL|      1|    let _short_unused_closure_block = | _unused_arg: u8 | { println!("not called") };
-                                                                        ^0
+                                                                        ^0^0       ^0            ^0
    LL|       |
    LL|      1|    let _shortish_unused_closure = | _unused_arg: u8 | {
+                                                                     ^0
    LL|      0|        println!("not called")
    LL|      0|    };
    LL|       |
@@ -173,14 +173,14 @@
    LL|       |
    LL|      1|    let _short_unused_closure_line_break_no_block2 =
    LL|       |        | _unused_arg: u8 |
-   LL|      0|            println!(
+   LL|       |            println!(
    LL|      0|                "not called"
-   LL|      0|            )
+   LL|       |            )
    LL|       |    ;
    LL|       |
    LL|      1|    let short_used_not_covered_closure_line_break_no_block_embedded_branch =
    LL|       |        | _unused_arg: u8 |
-   LL|      0|            println!(
+   LL|       |            println!(
    LL|      0|                "not called: {}",
    LL|      0|                if is_true { "check" } else { "me" }
    LL|       |            )
@@ -198,7 +198,7 @@
    LL|       |
    LL|      1|    let short_used_covered_closure_line_break_no_block_embedded_branch =
    LL|       |        | _unused_arg: u8 |
-   LL|      1|            println!(
+   LL|       |            println!(
    LL|      1|                "not called: {}",
    LL|      1|                if is_true { "check" } else { "me" }
                                                             ^0
diff --git a/tests/coverage/closure_bug.cov-map b/tests/coverage/closure_bug.cov-map
index 40a8bdf9c1d..a7087c69dcb 100644
--- a/tests/coverage/closure_bug.cov-map
+++ b/tests/coverage/closure_bug.cov-map
@@ -1,44 +1,51 @@
 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, 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]
+Raw bytes (132): 0x[01, 01, 04, 01, 05, 01, 09, 01, 0d, 01, 11, 18, 01, 07, 01, 00, 0a, 01, 01, 09, 00, 0f, 01, 00, 12, 00, 2d, 01, 02, 09, 00, 0a, 01, 06, 05, 00, 08, 01, 01, 08, 00, 0e, 05, 00, 0f, 00, 17, 02, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 00, 08, 01, 01, 08, 00, 0e, 09, 00, 0f, 00, 17, 06, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 00, 08, 01, 01, 08, 00, 0e, 0d, 00, 0f, 00, 17, 0a, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 00, 08, 01, 01, 08, 00, 0e, 11, 00, 0f, 00, 17, 0e, 00, 16, 00, 17, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure_bug.rs
 Number of expressions: 4
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(3)
 - expression 3 operands: lhs = Counter(0), rhs = Counter(4)
-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)
+Number of file 0 mappings: 24
+- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 45)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 14)
+- Code(Counter(1)) at (prev + 0, 15) to (start + 0, 23)
 - 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(Counter(0)) at (prev + 6, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 14)
+- Code(Counter(2)) at (prev + 0, 15) to (start + 0, 23)
 - 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(Counter(0)) at (prev + 6, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 14)
+- Code(Counter(3)) at (prev + 0, 15) to (start + 0, 23)
 - 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(Counter(0)) at (prev + 6, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 14)
+- Code(Counter(4)) at (prev + 0, 15) to (start + 0, 23)
 - 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
 
 Function name: closure_bug::main::{closure#0}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0e, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0e, 0c, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure_bug.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 14, 9) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 14, 12) to (start + 0, 18)
 - Code(Counter(1)) at (prev + 0, 21) to (start + 0, 25)
 - Code(Expression(0, Sub)) at (prev + 0, 35) to (start + 0, 40)
     = (c0 - c1)
@@ -46,13 +53,13 @@ Number of file 0 mappings: 4
 Highest counter ID seen: c1
 
 Function name: closure_bug::main::{closure#1}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 17, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 17, 0c, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure_bug.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 23, 9) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 23, 12) to (start + 0, 18)
 - Code(Counter(1)) at (prev + 0, 21) to (start + 0, 25)
 - Code(Expression(0, Sub)) at (prev + 0, 35) to (start + 0, 40)
     = (c0 - c1)
@@ -60,13 +67,13 @@ Number of file 0 mappings: 4
 Highest counter ID seen: c1
 
 Function name: closure_bug::main::{closure#2}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 20, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 20, 0c, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure_bug.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 32, 9) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 32, 12) to (start + 0, 18)
 - Code(Counter(1)) at (prev + 0, 21) to (start + 0, 25)
 - Code(Expression(0, Sub)) at (prev + 0, 35) to (start + 0, 40)
     = (c0 - c1)
@@ -74,13 +81,13 @@ Number of file 0 mappings: 4
 Highest counter ID seen: c1
 
 Function name: closure_bug::main::{closure#3}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 29, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 29, 0c, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 01, 00, 29, 00, 2a]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure_bug.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 41, 9) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 41, 12) to (start + 0, 18)
 - Code(Counter(1)) at (prev + 0, 21) to (start + 0, 25)
 - Code(Expression(0, Sub)) at (prev + 0, 35) to (start + 0, 40)
     = (c0 - c1)
diff --git a/tests/coverage/closure_bug.coverage b/tests/coverage/closure_bug.coverage
index cc64470baa7..b85375d1850 100644
--- a/tests/coverage/closure_bug.coverage
+++ b/tests/coverage/closure_bug.coverage
@@ -6,7 +6,7 @@
    LL|       |#[rustfmt::skip]
    LL|      1|fn main() {
    LL|      1|    let truthy = std::env::args().len() == 1;
-   LL|      1|
+   LL|       |
    LL|      1|    let a
    LL|       |        =
    LL|       |        |
diff --git a/tests/coverage/closure_macro.cov-map b/tests/coverage/closure_macro.cov-map
index 9dd99c8fab3..3ab1d7f5fba 100644
--- a/tests/coverage/closure_macro.cov-map
+++ b/tests/coverage/closure_macro.cov-map
@@ -1,41 +1,57 @@
 Function name: closure_macro::load_configuration_files
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1d, 01, 02, 02]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 1d, 01, 00, 38, 01, 01, 05, 00, 1f, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure_macro.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 29, 1) to (start + 2, 2)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 29, 1) to (start + 0, 56)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: closure_macro::main
-Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 21, 01, 01, 20, 02, 02, 09, 00, 0f, 01, 00, 12, 00, 34, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02]
+Raw bytes (66): 0x[01, 01, 01, 01, 05, 0c, 01, 21, 01, 00, 24, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 20, 02, 01, 09, 00, 0f, 01, 00, 12, 00, 1b, 01, 00, 1c, 00, 34, 05, 00, 54, 00, 55, 02, 02, 09, 00, 1f, 02, 00, 22, 00, 2e, 02, 01, 0d, 00, 2d, 02, 01, 05, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure_macro.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 33, 1) to (start + 1, 32)
-- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 36)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 32)
+- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15)
     = (c0 - c1)
-- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 52)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 0, 28) to (start + 0, 52)
 - Code(Counter(1)) at (prev + 0, 84) to (start + 0, 85)
-- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 2, 11)
+- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 31)
     = (c0 - c1)
-- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
+- Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 46)
+    = (c0 - c1)
+- Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 45)
+    = (c0 - c1)
+- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 11)
+    = (c0 - c1)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: closure_macro::main::{closure#0}
-Raw bytes (35): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 05, 01, 10, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 06, 00, 17, 00, 1e, 01, 02, 09, 00, 0a]
+Raw bytes (60): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 0a, 01, 10, 1c, 00, 1d, 01, 02, 11, 00, 18, 01, 00, 1b, 00, 22, 01, 01, 10, 00, 21, 05, 01, 11, 00, 19, 05, 00, 1a, 00, 1e, 05, 01, 11, 00, 27, 02, 02, 11, 00, 16, 06, 00, 17, 00, 1e, 01, 02, 09, 00, 0a]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure_macro.rs
 Number of expressions: 3
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 16, 28) to (start + 3, 33)
-- Code(Counter(1)) at (prev + 4, 17) to (start + 1, 39)
-- Code(Expression(0, Sub)) at (prev + 3, 17) to (start + 0, 22)
+Number of file 0 mappings: 10
+- Code(Counter(0)) at (prev + 16, 28) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 2, 17) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 0, 27) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 33)
+- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 25)
+- Code(Counter(1)) at (prev + 0, 26) to (start + 0, 30)
+- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 39)
+- Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 22)
     = (c0 - c1)
 - Code(Expression(1, Sub)) at (prev + 0, 23) to (start + 0, 30)
     = (c0 - (c1 + c2))
diff --git a/tests/coverage/closure_macro.coverage b/tests/coverage/closure_macro.coverage
index 00022bbff89..b1d7a8327a4 100644
--- a/tests/coverage/closure_macro.coverage
+++ b/tests/coverage/closure_macro.coverage
@@ -14,7 +14,7 @@
    LL|       |macro_rules! on_error {
    LL|       |    ($value:expr, $error_message:expr) => {
    LL|      0|        $value.or_else(|e| {
-   LL|      0|            // This closure, which is declared in a macro, should be instrumented.
+   LL|       |            // This closure, which is declared in a macro, should be instrumented.
    LL|      0|            let message = format!($error_message, e);
    LL|      0|            if message.len() > 0 {
    LL|      0|                println!("{}", message);
diff --git a/tests/coverage/closure_macro_async.cov-map b/tests/coverage/closure_macro_async.cov-map
index 2548754d754..b5f4cee0ec4 100644
--- a/tests/coverage/closure_macro_async.cov-map
+++ b/tests/coverage/closure_macro_async.cov-map
@@ -1,50 +1,66 @@
 Function name: closure_macro_async::load_configuration_files
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 21, 01, 00, 38, 01, 01, 05, 00, 1f, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure_macro_async.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 56)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: closure_macro_async::test
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 25, 01, 00, 2b]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 25, 01, 00, 2a]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure_macro_async.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 43)
+- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 42)
 Highest counter ID seen: c0
 
 Function name: closure_macro_async::test::{closure#0}
-Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 25, 2b, 01, 20, 02, 02, 09, 00, 0f, 01, 00, 12, 00, 34, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02]
+Raw bytes (66): 0x[01, 01, 01, 01, 05, 0c, 01, 25, 2b, 00, 2c, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 20, 02, 01, 09, 00, 0f, 01, 00, 12, 00, 1b, 01, 00, 1c, 00, 34, 05, 00, 54, 00, 55, 02, 02, 09, 00, 1f, 02, 00, 22, 00, 2e, 02, 01, 0d, 00, 2d, 02, 01, 05, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure_macro_async.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 37, 43) to (start + 1, 32)
-- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 37, 43) to (start + 0, 44)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 32)
+- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15)
     = (c0 - c1)
-- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 52)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 0, 28) to (start + 0, 52)
 - Code(Counter(1)) at (prev + 0, 84) to (start + 0, 85)
-- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 2, 11)
+- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 31)
+    = (c0 - c1)
+- Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 46)
+    = (c0 - c1)
+- Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 45)
+    = (c0 - c1)
+- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 11)
     = (c0 - c1)
-- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: closure_macro_async::test::{closure#0}::{closure#0}
-Raw bytes (35): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 05, 01, 14, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 06, 00, 17, 00, 1e, 01, 02, 09, 00, 0a]
+Raw bytes (60): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 0a, 01, 14, 1c, 00, 1d, 01, 02, 11, 00, 18, 01, 00, 1b, 00, 22, 01, 01, 10, 00, 21, 05, 01, 11, 00, 19, 05, 00, 1a, 00, 1e, 05, 01, 11, 00, 27, 02, 02, 11, 00, 16, 06, 00, 17, 00, 1e, 01, 02, 09, 00, 0a]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure_macro_async.rs
 Number of expressions: 3
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 20, 28) to (start + 3, 33)
-- Code(Counter(1)) at (prev + 4, 17) to (start + 1, 39)
-- Code(Expression(0, Sub)) at (prev + 3, 17) to (start + 0, 22)
+Number of file 0 mappings: 10
+- Code(Counter(0)) at (prev + 20, 28) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 2, 17) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 0, 27) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 33)
+- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 25)
+- Code(Counter(1)) at (prev + 0, 26) to (start + 0, 30)
+- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 39)
+- Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 22)
     = (c0 - c1)
 - Code(Expression(1, Sub)) at (prev + 0, 23) to (start + 0, 30)
     = (c0 - (c1 + c2))
diff --git a/tests/coverage/closure_macro_async.coverage b/tests/coverage/closure_macro_async.coverage
index 1e1ffec9f76..7bfea3c9bb3 100644
--- a/tests/coverage/closure_macro_async.coverage
+++ b/tests/coverage/closure_macro_async.coverage
@@ -18,7 +18,7 @@
    LL|       |macro_rules! on_error {
    LL|       |    ($value:expr, $error_message:expr) => {
    LL|      0|        $value.or_else(|e| {
-   LL|      0|            // This closure, which is declared in a macro, should be instrumented.
+   LL|       |            // This closure, which is declared in a macro, should be instrumented.
    LL|      0|            let message = format!($error_message, e);
    LL|      0|            if message.len() > 0 {
    LL|      0|                println!("{}", message);
diff --git a/tests/coverage/closure_unit_return.cov-map b/tests/coverage/closure_unit_return.cov-map
index 9a66e0b0e77..f665d93e6e1 100644
--- a/tests/coverage/closure_unit_return.cov-map
+++ b/tests/coverage/closure_unit_return.cov-map
@@ -1,38 +1,49 @@
 Function name: closure_unit_return::explicit_unit
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 07, 01, 01, 10, 01, 05, 05, 02, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 07, 01, 00, 13, 01, 01, 09, 00, 10, 01, 04, 05, 00, 09, 01, 00, 0a, 00, 11, 01, 01, 05, 00, 07, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure_unit_return.rs
 Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 16)
-- Code(Counter(0)) at (prev + 5, 5) to (start + 2, 2)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 9)
+- Code(Counter(0)) at (prev + 0, 10) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 7)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: closure_unit_return::explicit_unit::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 08, 16, 02, 06]
+Raw bytes (19): 0x[01, 01, 00, 03, 00, 08, 16, 00, 17, 00, 01, 09, 00, 0b, 00, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure_unit_return.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 8, 22) to (start + 2, 6)
+Number of file 0 mappings: 3
+- Code(Zero) at (prev + 8, 22) to (start + 0, 23)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 11)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: (none)
 
 Function name: closure_unit_return::implicit_unit
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 01, 01, 10, 01, 05, 05, 02, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 10, 01, 00, 13, 01, 01, 09, 00, 10, 01, 04, 05, 00, 09, 01, 00, 0a, 00, 11, 01, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure_unit_return.rs
 Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 16, 1) to (start + 1, 16)
-- Code(Counter(0)) at (prev + 5, 5) to (start + 2, 2)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 9)
+- Code(Counter(0)) at (prev + 0, 10) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: closure_unit_return::implicit_unit::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 16, 02, 06]
+Raw bytes (19): 0x[01, 01, 00, 03, 00, 11, 16, 00, 17, 00, 01, 09, 00, 0b, 00, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/closure_unit_return.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 17, 22) to (start + 2, 6)
+Number of file 0 mappings: 3
+- Code(Zero) at (prev + 17, 22) to (start + 0, 23)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 11)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: (none)
 
diff --git a/tests/coverage/closure_unit_return.coverage b/tests/coverage/closure_unit_return.coverage
index 5e57e0db160..02ea63b6dc3 100644
--- a/tests/coverage/closure_unit_return.coverage
+++ b/tests/coverage/closure_unit_return.coverage
@@ -6,6 +6,7 @@
    LL|       |
    LL|      1|fn explicit_unit() {
    LL|      1|    let closure = || {
+                                   ^0
    LL|      0|        ();
    LL|      0|    };
    LL|       |
@@ -15,11 +16,12 @@
    LL|       |
    LL|      1|fn implicit_unit() {
    LL|      1|    let closure = || {
+                                   ^0
    LL|      0|        ();
    LL|      0|    };
    LL|       |
    LL|      1|    drop(closure);
-   LL|      1|    // implicit return of `()`
+   LL|       |    // implicit return of `()`
    LL|      1|}
    LL|       |
    LL|       |#[coverage(off)]
diff --git a/tests/coverage/condition/conditions.cov-map b/tests/coverage/condition/conditions.cov-map
index c34075a0bcf..fda5dd1b97d 100644
--- a/tests/coverage/condition/conditions.cov-map
+++ b/tests/coverage/condition/conditions.cov-map
@@ -1,15 +1,15 @@
 Function name: conditions::assign_3_and_or
-Raw bytes (65): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 09, 01, 1c, 01, 00, 2f, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 20, 0d, 0e, 00, 17, 00, 18, 01, 01, 05, 01, 02]
+Raw bytes (75): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 0b, 01, 1c, 01, 00, 2e, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 20, 0d, 0e, 00, 17, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/conditions.rs
 Number of expressions: 5
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(2)
 - expression 3 operands: lhs = Counter(0), rhs = Expression(4, Add)
 - expression 4 operands: lhs = Counter(2), rhs = Counter(3)
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 28, 1) to (start + 0, 47)
+Number of file 0 mappings: 11
+- Code(Counter(0)) at (prev + 28, 1) to (start + 0, 46)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14)
@@ -24,20 +24,22 @@ Number of file 0 mappings: 9
 - Branch { true: Counter(3), false: Expression(3, Sub) } at (prev + 0, 23) to (start + 0, 24)
     true  = c3
     false = (c0 - (c2 + c3))
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c3
 
 Function name: conditions::assign_3_or_and
-Raw bytes (63): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 09, 01, 17, 01, 00, 2f, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 09, 00, 17, 00, 18, 20, 0d, 0e, 00, 17, 00, 18, 01, 01, 05, 01, 02]
+Raw bytes (73): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 0b, 01, 17, 01, 00, 2e, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 09, 00, 17, 00, 18, 20, 0d, 0e, 00, 17, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/conditions.rs
 Number of expressions: 4
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 3 operands: lhs = Counter(2), rhs = Counter(3)
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 47)
+Number of file 0 mappings: 11
+- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 46)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14)
@@ -52,18 +54,20 @@ Number of file 0 mappings: 9
 - Branch { true: Counter(3), false: Expression(3, Sub) } at (prev + 0, 23) to (start + 0, 24)
     true  = c3
     false = (c2 - c3)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c3
 
 Function name: conditions::assign_and
-Raw bytes (47): 0x[01, 01, 02, 01, 05, 05, 09, 07, 01, 0d, 01, 00, 21, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 01, 01, 05, 01, 02]
+Raw bytes (57): 0x[01, 01, 02, 01, 05, 05, 09, 09, 01, 0d, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/conditions.rs
 Number of expressions: 2
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 33)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 32)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14)
@@ -73,19 +77,21 @@ Number of file 0 mappings: 7
 - Branch { true: Counter(2), false: Expression(1, Sub) } at (prev + 0, 18) to (start + 0, 19)
     true  = c2
     false = (c1 - c2)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c2
 
 Function name: conditions::assign_or
-Raw bytes (49): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 07, 01, 12, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 01, 01, 05, 01, 02]
+Raw bytes (59): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 09, 01, 12, 01, 00, 1f, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/conditions.rs
 Number of expressions: 3
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 18, 1) to (start + 0, 32)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 18, 1) to (start + 0, 31)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14)
@@ -96,27 +102,32 @@ Number of file 0 mappings: 7
 - Branch { true: Counter(2), false: Expression(1, Sub) } at (prev + 0, 18) to (start + 0, 19)
     true  = c2
     false = (c0 - (c1 + c2))
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c2
 
 Function name: conditions::foo
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 21, 01, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/conditions.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: conditions::func_call
-Raw bytes (47): 0x[01, 01, 02, 01, 05, 05, 09, 07, 01, 25, 01, 00, 20, 01, 01, 05, 00, 08, 01, 00, 09, 00, 0a, 20, 05, 02, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 20, 09, 06, 00, 0e, 00, 0f, 01, 01, 01, 00, 02]
+Raw bytes (47): 0x[01, 01, 02, 01, 05, 05, 09, 07, 01, 25, 01, 00, 1f, 01, 01, 05, 00, 08, 01, 00, 09, 00, 0a, 20, 05, 02, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 20, 09, 06, 00, 0e, 00, 0f, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/conditions.rs
 Number of expressions: 2
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 31)
 - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 8)
 - Code(Counter(0)) at (prev + 0, 9) to (start + 0, 10)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 9) to (start + 0, 10)
@@ -130,11 +141,16 @@ Number of file 0 mappings: 7
 Highest counter ID seen: c2
 
 Function name: conditions::simple_assign
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 08, 01, 03, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 08, 01, 00, 1a, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/conditions.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 2)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/conditions.cov-map b/tests/coverage/conditions.cov-map
index 2d12f4bf774..29d9604085e 100644
--- a/tests/coverage/conditions.cov-map
+++ b/tests/coverage/conditions.cov-map
@@ -1,8 +1,8 @@
 Function name: conditions::main
-Raw bytes (533): 0x[01, 01, 47, 05, 09, 01, 05, 09, 5d, 09, 27, 5d, 61, 27, 65, 5d, 61, 09, 23, 27, 65, 5d, 61, 01, 03, 03, 0d, 11, 51, 11, 4f, 51, 55, 4f, 59, 51, 55, 11, 4b, 4f, 59, 51, 55, 03, 97, 01, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 97, 01, 15, 0d, 11, 19, 45, 19, 8f, 01, 45, 49, 8f, 01, 4d, 45, 49, 19, 8b, 01, 8f, 01, 4d, 45, 49, 97, 01, db, 01, 0d, 11, 15, 19, 15, 19, 15, 19, 1d, 21, 15, 19, db, 01, 1d, 15, 19, 21, 39, 21, d3, 01, 39, 3d, d3, 01, 41, 39, 3d, 21, cf, 01, d3, 01, 41, 39, 3d, db, 01, 97, 02, 15, 19, 1d, 21, 25, 29, 1d, 21, 97, 02, 25, 1d, 21, 29, 2d, 29, 8f, 02, 2d, 31, 8f, 02, 35, 2d, 31, 29, 8b, 02, 8f, 02, 35, 2d, 31, 97, 02, 9b, 02, 1d, 21, 25, 29, 44, 01, 03, 01, 02, 0c, 01, 02, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 03, 09, 00, 0a, 01, 00, 10, 00, 1d, 05, 01, 09, 01, 0a, 06, 02, 0f, 00, 1c, 09, 01, 0c, 00, 19, 0a, 00, 1d, 00, 2a, 0e, 00, 2e, 00, 3c, 23, 00, 3d, 02, 0a, 1e, 02, 09, 00, 0a, 09, 01, 09, 01, 12, 2a, 03, 09, 00, 0f, 03, 03, 09, 01, 0c, 03, 01, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 02, 08, 00, 15, 0d, 00, 16, 02, 06, 2e, 02, 0f, 00, 1c, 11, 01, 0c, 00, 19, 32, 00, 1d, 00, 2a, 36, 00, 2e, 00, 3c, 4b, 00, 3d, 02, 0a, 46, 02, 09, 00, 0a, 11, 01, 09, 00, 17, 52, 02, 09, 00, 0f, 97, 01, 03, 08, 00, 0c, 97, 01, 01, 0d, 01, 10, 97, 01, 01, 11, 02, 0a, 00, 02, 09, 00, 0a, 97, 01, 02, 0c, 00, 19, 15, 00, 1a, 02, 0a, 6a, 04, 11, 00, 1e, 19, 01, 10, 00, 1d, 72, 00, 21, 00, 2e, 76, 00, 32, 00, 40, 8b, 01, 00, 41, 02, 0e, 86, 01, 02, 0d, 00, 0e, 19, 01, 0d, 00, 1b, 92, 01, 02, 0d, 00, 13, 00, 02, 05, 00, 06, db, 01, 02, 09, 01, 0c, db, 01, 01, 0d, 02, 06, 00, 02, 05, 00, 06, 97, 02, 02, 09, 00, 0a, db, 01, 00, 10, 00, 1d, 1d, 00, 1e, 02, 06, ae, 01, 02, 0f, 00, 1c, 21, 01, 0c, 00, 19, b6, 01, 00, 1d, 00, 2a, ba, 01, 00, 2e, 00, 3c, cf, 01, 00, 3d, 02, 0a, ca, 01, 02, 09, 00, 0a, 21, 01, 09, 00, 17, d6, 01, 02, 0d, 02, 0f, 9b, 02, 05, 09, 00, 0a, 97, 02, 00, 10, 00, 1d, 25, 00, 1e, 02, 06, ea, 01, 02, 0f, 00, 1c, 29, 01, 0c, 00, 19, f2, 01, 00, 1d, 00, 2a, f6, 01, 00, 2e, 00, 3c, 8b, 02, 00, 3d, 02, 0a, 86, 02, 02, 09, 00, 0a, 29, 01, 09, 00, 17, 92, 02, 02, 09, 00, 0f, 01, 02, 01, 00, 02]
+Raw bytes (656): 0x[01, 01, 57, 05, 09, 01, 05, 09, 5d, 09, 27, 5d, 61, 27, 65, 5d, 61, 09, 23, 27, 65, 5d, 61, 01, 03, 03, 0d, 11, 51, 11, 4f, 51, 55, 4f, 59, 51, 55, 11, 4b, 4f, 59, 51, 55, 03, 9f, 01, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 9f, 01, 15, 0d, 11, 19, 45, 19, 97, 01, 45, 49, 97, 01, 4d, 45, 49, 19, 93, 01, 97, 01, 4d, 45, 49, 9f, 01, 9b, 02, 0d, 11, 15, 19, 15, 19, 15, 19, 15, 19, 15, 19, 1d, 21, 15, 19, 9b, 02, 1d, 15, 19, 21, 39, 21, e3, 01, 39, 3d, e3, 01, 41, 39, 3d, 21, df, 01, e3, 01, 41, 39, 3d, 9b, 02, d7, 02, 15, 19, 1d, 21, 9b, 02, d7, 02, 15, 19, 1d, 21, 9b, 02, d7, 02, 15, 19, 1d, 21, 9b, 02, d7, 02, 15, 19, 1d, 21, 9b, 02, d7, 02, 15, 19, 1d, 21, 25, 29, 1d, 21, d7, 02, 25, 1d, 21, 29, 2d, 29, cf, 02, 2d, 31, cf, 02, 35, 2d, 31, 29, cb, 02, cf, 02, 35, 2d, 31, d7, 02, db, 02, 1d, 21, 25, 29, 53, 01, 03, 01, 00, 0a, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0c, 01, 00, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 03, 09, 00, 0a, 01, 00, 10, 00, 1d, 05, 01, 09, 00, 17, 05, 01, 09, 00, 0a, 06, 01, 0f, 00, 1c, 09, 01, 0c, 00, 19, 0a, 00, 1d, 00, 2a, 0e, 00, 2e, 00, 3c, 23, 00, 3d, 02, 0a, 1e, 02, 09, 00, 0a, 09, 01, 09, 00, 17, 09, 01, 09, 00, 12, 2a, 02, 09, 00, 0f, 03, 03, 09, 00, 16, 03, 00, 19, 00, 1a, 03, 01, 08, 00, 0c, 03, 00, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 02, 08, 00, 15, 0d, 00, 16, 02, 06, 2e, 02, 0f, 00, 1c, 11, 01, 0c, 00, 19, 32, 00, 1d, 00, 2a, 36, 00, 2e, 00, 3c, 4b, 00, 3d, 02, 0a, 46, 02, 09, 00, 0a, 11, 01, 09, 00, 17, 52, 02, 09, 00, 0f, 9f, 01, 03, 08, 00, 0c, 9f, 01, 01, 0d, 00, 1a, 9f, 01, 00, 1d, 00, 1e, 9f, 01, 01, 0c, 00, 10, 9f, 01, 00, 11, 02, 0a, 00, 02, 09, 00, 0a, 9f, 01, 02, 0c, 00, 19, 15, 00, 1a, 02, 0a, 72, 04, 11, 00, 1e, 19, 01, 10, 00, 1d, 7a, 00, 21, 00, 2e, 7e, 00, 32, 00, 40, 93, 01, 00, 41, 02, 0e, 8e, 01, 02, 0d, 00, 0e, 19, 01, 0d, 00, 1b, 9a, 01, 02, 0d, 00, 13, 00, 02, 05, 00, 06, 9b, 02, 02, 09, 00, 16, 9b, 02, 00, 19, 00, 1a, 9b, 02, 01, 08, 00, 0c, 9b, 02, 00, 0d, 02, 06, 00, 02, 05, 00, 06, d7, 02, 02, 09, 00, 0a, 9b, 02, 00, 10, 00, 1d, 1d, 00, 1e, 02, 06, be, 01, 02, 0f, 00, 1c, 21, 01, 0c, 00, 19, c6, 01, 00, 1d, 00, 2a, ca, 01, 00, 2e, 00, 3c, df, 01, 00, 3d, 02, 0a, da, 01, 02, 09, 00, 0a, 21, 01, 09, 00, 17, 96, 02, 02, 0d, 00, 20, 96, 02, 00, 23, 00, 2c, 96, 02, 01, 09, 00, 11, 96, 02, 00, 12, 00, 1b, 96, 02, 01, 09, 00, 0f, db, 02, 03, 09, 00, 0a, d7, 02, 00, 10, 00, 1d, 25, 00, 1e, 02, 06, aa, 02, 02, 0f, 00, 1c, 29, 01, 0c, 00, 19, b2, 02, 00, 1d, 00, 2a, b6, 02, 00, 2e, 00, 3c, cb, 02, 00, 3d, 02, 0a, c6, 02, 02, 09, 00, 0a, 29, 01, 09, 00, 17, d2, 02, 02, 09, 00, 0f, 01, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
-Number of expressions: 71
+- file 0 => $DIR/conditions.rs
+Number of expressions: 87
 - expression 0 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 2 operands: lhs = Counter(2), rhs = Counter(23)
@@ -23,66 +23,86 @@ Number of expressions: 71
 - expression 17 operands: lhs = Counter(4), rhs = Expression(18, Add)
 - expression 18 operands: lhs = Expression(19, Add), rhs = Counter(22)
 - expression 19 operands: lhs = Counter(20), rhs = Counter(21)
-- expression 20 operands: lhs = Expression(0, Add), rhs = Expression(37, Add)
+- expression 20 operands: lhs = Expression(0, Add), rhs = Expression(39, Add)
 - expression 21 operands: lhs = Counter(3), rhs = Counter(4)
 - expression 22 operands: lhs = Counter(3), rhs = Counter(4)
 - expression 23 operands: lhs = Counter(3), rhs = Counter(4)
 - expression 24 operands: lhs = Counter(3), rhs = Counter(4)
 - expression 25 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 26 operands: lhs = Expression(37, Add), rhs = Counter(5)
+- expression 26 operands: lhs = Counter(3), rhs = Counter(4)
 - expression 27 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 28 operands: lhs = Counter(6), rhs = Counter(17)
-- expression 29 operands: lhs = Counter(6), rhs = Expression(35, Add)
-- expression 30 operands: lhs = Counter(17), rhs = Counter(18)
-- expression 31 operands: lhs = Expression(35, Add), rhs = Counter(19)
+- expression 28 operands: lhs = Expression(39, Add), rhs = Counter(5)
+- expression 29 operands: lhs = Counter(3), rhs = Counter(4)
+- expression 30 operands: lhs = Counter(6), rhs = Counter(17)
+- expression 31 operands: lhs = Counter(6), rhs = Expression(37, Add)
 - expression 32 operands: lhs = Counter(17), rhs = Counter(18)
-- expression 33 operands: lhs = Counter(6), rhs = Expression(34, Add)
-- expression 34 operands: lhs = Expression(35, Add), rhs = Counter(19)
-- expression 35 operands: lhs = Counter(17), rhs = Counter(18)
-- expression 36 operands: lhs = Expression(37, Add), rhs = Expression(54, Add)
-- expression 37 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 38 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 39 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 33 operands: lhs = Expression(37, Add), rhs = Counter(19)
+- expression 34 operands: lhs = Counter(17), rhs = Counter(18)
+- expression 35 operands: lhs = Counter(6), rhs = Expression(36, Add)
+- expression 36 operands: lhs = Expression(37, Add), rhs = Counter(19)
+- expression 37 operands: lhs = Counter(17), rhs = Counter(18)
+- expression 38 operands: lhs = Expression(39, Add), rhs = Expression(70, Add)
+- expression 39 operands: lhs = Counter(3), rhs = Counter(4)
 - expression 40 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 41 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 41 operands: lhs = Counter(5), rhs = Counter(6)
 - expression 42 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 43 operands: lhs = Expression(54, Add), rhs = Counter(7)
+- expression 43 operands: lhs = Counter(5), rhs = Counter(6)
 - expression 44 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 45 operands: lhs = Counter(8), rhs = Counter(14)
-- expression 46 operands: lhs = Counter(8), rhs = Expression(52, Add)
-- expression 47 operands: lhs = Counter(14), rhs = Counter(15)
-- expression 48 operands: lhs = Expression(52, Add), rhs = Counter(16)
-- expression 49 operands: lhs = Counter(14), rhs = Counter(15)
-- expression 50 operands: lhs = Counter(8), rhs = Expression(51, Add)
-- expression 51 operands: lhs = Expression(52, Add), rhs = Counter(16)
-- expression 52 operands: lhs = Counter(14), rhs = Counter(15)
-- expression 53 operands: lhs = Expression(54, Add), rhs = Expression(69, Add)
-- expression 54 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 55 operands: lhs = Counter(7), rhs = Counter(8)
-- expression 56 operands: lhs = Counter(9), rhs = Counter(10)
-- expression 57 operands: lhs = Counter(7), rhs = Counter(8)
-- expression 58 operands: lhs = Expression(69, Add), rhs = Counter(9)
+- expression 45 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 46 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 47 operands: lhs = Expression(70, Add), rhs = Counter(7)
+- expression 48 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 49 operands: lhs = Counter(8), rhs = Counter(14)
+- expression 50 operands: lhs = Counter(8), rhs = Expression(56, Add)
+- expression 51 operands: lhs = Counter(14), rhs = Counter(15)
+- expression 52 operands: lhs = Expression(56, Add), rhs = Counter(16)
+- expression 53 operands: lhs = Counter(14), rhs = Counter(15)
+- expression 54 operands: lhs = Counter(8), rhs = Expression(55, Add)
+- expression 55 operands: lhs = Expression(56, Add), rhs = Counter(16)
+- expression 56 operands: lhs = Counter(14), rhs = Counter(15)
+- expression 57 operands: lhs = Expression(70, Add), rhs = Expression(85, Add)
+- expression 58 operands: lhs = Counter(5), rhs = Counter(6)
 - expression 59 operands: lhs = Counter(7), rhs = Counter(8)
-- expression 60 operands: lhs = Counter(10), rhs = Counter(11)
-- expression 61 operands: lhs = Counter(10), rhs = Expression(67, Add)
-- expression 62 operands: lhs = Counter(11), rhs = Counter(12)
-- expression 63 operands: lhs = Expression(67, Add), rhs = Counter(13)
-- expression 64 operands: lhs = Counter(11), rhs = Counter(12)
-- expression 65 operands: lhs = Counter(10), rhs = Expression(66, Add)
-- expression 66 operands: lhs = Expression(67, Add), rhs = Counter(13)
-- expression 67 operands: lhs = Counter(11), rhs = Counter(12)
-- expression 68 operands: lhs = Expression(69, Add), rhs = Expression(70, Add)
-- expression 69 operands: lhs = Counter(7), rhs = Counter(8)
-- expression 70 operands: lhs = Counter(9), rhs = Counter(10)
-Number of file 0 mappings: 68
-- Code(Counter(0)) at (prev + 3, 1) to (start + 2, 12)
-- Code(Counter(0)) at (prev + 2, 13) to (start + 2, 6)
+- expression 60 operands: lhs = Expression(70, Add), rhs = Expression(85, Add)
+- expression 61 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 62 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 63 operands: lhs = Expression(70, Add), rhs = Expression(85, Add)
+- expression 64 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 65 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 66 operands: lhs = Expression(70, Add), rhs = Expression(85, Add)
+- expression 67 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 68 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 69 operands: lhs = Expression(70, Add), rhs = Expression(85, Add)
+- expression 70 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 71 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 72 operands: lhs = Counter(9), rhs = Counter(10)
+- expression 73 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 74 operands: lhs = Expression(85, Add), rhs = Counter(9)
+- expression 75 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 76 operands: lhs = Counter(10), rhs = Counter(11)
+- expression 77 operands: lhs = Counter(10), rhs = Expression(83, Add)
+- expression 78 operands: lhs = Counter(11), rhs = Counter(12)
+- expression 79 operands: lhs = Expression(83, Add), rhs = Counter(13)
+- expression 80 operands: lhs = Counter(11), rhs = Counter(12)
+- expression 81 operands: lhs = Counter(10), rhs = Expression(82, Add)
+- expression 82 operands: lhs = Expression(83, Add), rhs = Counter(13)
+- expression 83 operands: lhs = Counter(11), rhs = Counter(12)
+- expression 84 operands: lhs = Expression(85, Add), rhs = Expression(86, Add)
+- expression 85 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 86 operands: lhs = Counter(9), rhs = Counter(10)
+Number of file 0 mappings: 83
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 2, 6)
 - Code(Zero) at (prev + 2, 5) to (start + 0, 6)
 - Code(Expression(0, Add)) at (prev + 3, 9) to (start + 0, 10)
     = (c1 + c2)
 - Code(Counter(0)) at (prev + 0, 16) to (start + 0, 29)
-- Code(Counter(1)) at (prev + 1, 9) to (start + 1, 10)
-- Code(Expression(1, Sub)) at (prev + 2, 15) to (start + 0, 28)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 23)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 10)
+- Code(Expression(1, Sub)) at (prev + 1, 15) to (start + 0, 28)
     = (c0 - c1)
 - Code(Counter(2)) at (prev + 1, 12) to (start + 0, 25)
 - Code(Expression(2, Sub)) at (prev + 0, 29) to (start + 0, 42)
@@ -93,12 +113,17 @@ Number of file 0 mappings: 68
     = ((c23 + c24) + c25)
 - Code(Expression(7, Sub)) at (prev + 2, 9) to (start + 0, 10)
     = (c2 - ((c23 + c24) + c25))
-- Code(Counter(2)) at (prev + 1, 9) to (start + 1, 18)
-- Code(Expression(10, Sub)) at (prev + 3, 9) to (start + 0, 15)
+- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 23)
+- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 18)
+- Code(Expression(10, Sub)) at (prev + 2, 9) to (start + 0, 15)
     = (c0 - (c1 + c2))
-- Code(Expression(0, Add)) at (prev + 3, 9) to (start + 1, 12)
+- Code(Expression(0, Add)) at (prev + 3, 9) to (start + 0, 22)
     = (c1 + c2)
-- Code(Expression(0, Add)) at (prev + 1, 13) to (start + 2, 6)
+- Code(Expression(0, Add)) at (prev + 0, 25) to (start + 0, 26)
+    = (c1 + c2)
+- Code(Expression(0, Add)) at (prev + 1, 8) to (start + 0, 12)
+    = (c1 + c2)
+- Code(Expression(0, Add)) at (prev + 0, 13) to (start + 2, 6)
     = (c1 + c2)
 - Code(Zero) at (prev + 2, 5) to (start + 0, 6)
 - Code(Expression(0, Add)) at (prev + 2, 8) to (start + 0, 21)
@@ -118,73 +143,89 @@ Number of file 0 mappings: 68
 - Code(Counter(4)) at (prev + 1, 9) to (start + 0, 23)
 - Code(Expression(20, Sub)) at (prev + 2, 9) to (start + 0, 15)
     = ((c1 + c2) - (c3 + c4))
-- Code(Expression(37, Add)) at (prev + 3, 8) to (start + 0, 12)
+- Code(Expression(39, Add)) at (prev + 3, 8) to (start + 0, 12)
+    = (c3 + c4)
+- Code(Expression(39, Add)) at (prev + 1, 13) to (start + 0, 26)
     = (c3 + c4)
-- Code(Expression(37, Add)) at (prev + 1, 13) to (start + 1, 16)
+- Code(Expression(39, Add)) at (prev + 0, 29) to (start + 0, 30)
     = (c3 + c4)
-- Code(Expression(37, Add)) at (prev + 1, 17) to (start + 2, 10)
+- Code(Expression(39, Add)) at (prev + 1, 12) to (start + 0, 16)
+    = (c3 + c4)
+- Code(Expression(39, Add)) at (prev + 0, 17) to (start + 2, 10)
     = (c3 + c4)
 - Code(Zero) at (prev + 2, 9) to (start + 0, 10)
-- Code(Expression(37, Add)) at (prev + 2, 12) to (start + 0, 25)
+- Code(Expression(39, Add)) at (prev + 2, 12) to (start + 0, 25)
     = (c3 + c4)
 - Code(Counter(5)) at (prev + 0, 26) to (start + 2, 10)
-- Code(Expression(26, Sub)) at (prev + 4, 17) to (start + 0, 30)
+- Code(Expression(28, Sub)) at (prev + 4, 17) to (start + 0, 30)
     = ((c3 + c4) - c5)
 - Code(Counter(6)) at (prev + 1, 16) to (start + 0, 29)
-- Code(Expression(28, Sub)) at (prev + 0, 33) to (start + 0, 46)
+- Code(Expression(30, Sub)) at (prev + 0, 33) to (start + 0, 46)
     = (c6 - c17)
-- Code(Expression(29, Sub)) at (prev + 0, 50) to (start + 0, 64)
+- Code(Expression(31, Sub)) at (prev + 0, 50) to (start + 0, 64)
     = (c6 - (c17 + c18))
-- Code(Expression(34, Add)) at (prev + 0, 65) to (start + 2, 14)
+- Code(Expression(36, Add)) at (prev + 0, 65) to (start + 2, 14)
     = ((c17 + c18) + c19)
-- Code(Expression(33, Sub)) at (prev + 2, 13) to (start + 0, 14)
+- Code(Expression(35, Sub)) at (prev + 2, 13) to (start + 0, 14)
     = (c6 - ((c17 + c18) + c19))
 - Code(Counter(6)) at (prev + 1, 13) to (start + 0, 27)
-- Code(Expression(36, Sub)) at (prev + 2, 13) to (start + 0, 19)
+- Code(Expression(38, Sub)) at (prev + 2, 13) to (start + 0, 19)
     = ((c3 + c4) - (c5 + c6))
 - Code(Zero) at (prev + 2, 5) to (start + 0, 6)
-- Code(Expression(54, Add)) at (prev + 2, 9) to (start + 1, 12)
+- Code(Expression(70, Add)) at (prev + 2, 9) to (start + 0, 22)
+    = (c5 + c6)
+- Code(Expression(70, Add)) at (prev + 0, 25) to (start + 0, 26)
     = (c5 + c6)
-- Code(Expression(54, Add)) at (prev + 1, 13) to (start + 2, 6)
+- Code(Expression(70, Add)) at (prev + 1, 8) to (start + 0, 12)
+    = (c5 + c6)
+- Code(Expression(70, Add)) at (prev + 0, 13) to (start + 2, 6)
     = (c5 + c6)
 - Code(Zero) at (prev + 2, 5) to (start + 0, 6)
-- Code(Expression(69, Add)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Expression(85, Add)) at (prev + 2, 9) to (start + 0, 10)
     = (c7 + c8)
-- Code(Expression(54, Add)) at (prev + 0, 16) to (start + 0, 29)
+- Code(Expression(70, Add)) at (prev + 0, 16) to (start + 0, 29)
     = (c5 + c6)
 - Code(Counter(7)) at (prev + 0, 30) to (start + 2, 6)
-- Code(Expression(43, Sub)) at (prev + 2, 15) to (start + 0, 28)
+- Code(Expression(47, Sub)) at (prev + 2, 15) to (start + 0, 28)
     = ((c5 + c6) - c7)
 - Code(Counter(8)) at (prev + 1, 12) to (start + 0, 25)
-- Code(Expression(45, Sub)) at (prev + 0, 29) to (start + 0, 42)
+- Code(Expression(49, Sub)) at (prev + 0, 29) to (start + 0, 42)
     = (c8 - c14)
-- Code(Expression(46, Sub)) at (prev + 0, 46) to (start + 0, 60)
+- Code(Expression(50, Sub)) at (prev + 0, 46) to (start + 0, 60)
     = (c8 - (c14 + c15))
-- Code(Expression(51, Add)) at (prev + 0, 61) to (start + 2, 10)
+- Code(Expression(55, Add)) at (prev + 0, 61) to (start + 2, 10)
     = ((c14 + c15) + c16)
-- Code(Expression(50, Sub)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Expression(54, Sub)) at (prev + 2, 9) to (start + 0, 10)
     = (c8 - ((c14 + c15) + c16))
 - Code(Counter(8)) at (prev + 1, 9) to (start + 0, 23)
-- Code(Expression(53, Sub)) at (prev + 2, 13) to (start + 2, 15)
+- Code(Expression(69, Sub)) at (prev + 2, 13) to (start + 0, 32)
+    = ((c5 + c6) - (c7 + c8))
+- Code(Expression(69, Sub)) at (prev + 0, 35) to (start + 0, 44)
+    = ((c5 + c6) - (c7 + c8))
+- Code(Expression(69, Sub)) at (prev + 1, 9) to (start + 0, 17)
+    = ((c5 + c6) - (c7 + c8))
+- Code(Expression(69, Sub)) at (prev + 0, 18) to (start + 0, 27)
+    = ((c5 + c6) - (c7 + c8))
+- Code(Expression(69, Sub)) at (prev + 1, 9) to (start + 0, 15)
     = ((c5 + c6) - (c7 + c8))
-- Code(Expression(70, Add)) at (prev + 5, 9) to (start + 0, 10)
+- Code(Expression(86, Add)) at (prev + 3, 9) to (start + 0, 10)
     = (c9 + c10)
-- Code(Expression(69, Add)) at (prev + 0, 16) to (start + 0, 29)
+- Code(Expression(85, Add)) at (prev + 0, 16) to (start + 0, 29)
     = (c7 + c8)
 - Code(Counter(9)) at (prev + 0, 30) to (start + 2, 6)
-- Code(Expression(58, Sub)) at (prev + 2, 15) to (start + 0, 28)
+- Code(Expression(74, Sub)) at (prev + 2, 15) to (start + 0, 28)
     = ((c7 + c8) - c9)
 - Code(Counter(10)) at (prev + 1, 12) to (start + 0, 25)
-- Code(Expression(60, Sub)) at (prev + 0, 29) to (start + 0, 42)
+- Code(Expression(76, Sub)) at (prev + 0, 29) to (start + 0, 42)
     = (c10 - c11)
-- Code(Expression(61, Sub)) at (prev + 0, 46) to (start + 0, 60)
+- Code(Expression(77, Sub)) at (prev + 0, 46) to (start + 0, 60)
     = (c10 - (c11 + c12))
-- Code(Expression(66, Add)) at (prev + 0, 61) to (start + 2, 10)
+- Code(Expression(82, Add)) at (prev + 0, 61) to (start + 2, 10)
     = ((c11 + c12) + c13)
-- Code(Expression(65, Sub)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Expression(81, Sub)) at (prev + 2, 9) to (start + 0, 10)
     = (c10 - ((c11 + c12) + c13))
 - Code(Counter(10)) at (prev + 1, 9) to (start + 0, 23)
-- Code(Expression(68, Sub)) at (prev + 2, 9) to (start + 0, 15)
+- Code(Expression(84, Sub)) at (prev + 2, 9) to (start + 0, 15)
     = ((c7 + c8) - (c9 + c10))
 - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
 Highest counter ID seen: c10
diff --git a/tests/coverage/continue.cov-map b/tests/coverage/continue.cov-map
index d926741cbcb..1a839f19a0f 100644
--- a/tests/coverage/continue.cov-map
+++ b/tests/coverage/continue.cov-map
@@ -1,75 +1,88 @@
 Function name: continue::main
-Raw bytes (198): 0x[01, 01, 16, 05, 01, 05, 0b, 01, 09, 0d, 01, 0d, 1f, 01, 11, 0d, 1f, 01, 11, 15, 01, 15, 2b, 01, 19, 1d, 01, 1d, 37, 01, 21, 25, 01, 25, 43, 01, 29, 25, 01, 2d, 01, 53, 2d, 01, 31, 2d, 01, 1e, 01, 03, 01, 03, 12, 05, 04, 0e, 00, 13, 02, 01, 0f, 00, 16, 09, 02, 11, 00, 19, 06, 02, 12, 04, 0e, 0d, 06, 0e, 00, 13, 0e, 01, 0f, 00, 16, 1a, 01, 16, 02, 0e, 11, 04, 11, 00, 19, 1a, 03, 09, 00, 0e, 15, 02, 0e, 00, 13, 22, 01, 0f, 00, 16, 19, 01, 15, 02, 0e, 26, 04, 11, 00, 19, 19, 03, 09, 00, 0e, 1d, 02, 0e, 00, 13, 2e, 01, 0c, 00, 13, 21, 01, 0d, 00, 15, 32, 01, 0a, 01, 0e, 25, 03, 0e, 00, 13, 46, 01, 0f, 00, 16, 3e, 01, 16, 02, 0e, 29, 03, 12, 02, 0e, 46, 04, 09, 00, 0e, 2d, 02, 0e, 00, 13, 31, 01, 0f, 00, 16, 56, 01, 16, 02, 0e, 4e, 04, 11, 00, 16, 56, 03, 09, 00, 0e, 01, 02, 0d, 01, 02]
+Raw bytes (241): 0x[01, 01, 1a, 05, 01, 05, 13, 01, 09, 05, 13, 01, 09, 0d, 01, 0d, 27, 01, 11, 0d, 27, 01, 11, 15, 01, 15, 33, 01, 19, 1d, 01, 1d, 47, 01, 21, 1d, 47, 01, 21, 25, 01, 25, 53, 01, 29, 25, 01, 2d, 01, 63, 2d, 01, 31, 2d, 01, 25, 01, 03, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0e, 00, 13, 02, 01, 0f, 00, 16, 09, 02, 11, 00, 19, 0e, 02, 12, 02, 0e, 0e, 04, 09, 00, 0e, 0d, 02, 0e, 00, 13, 16, 01, 0f, 00, 16, 22, 01, 16, 02, 0e, 11, 04, 11, 00, 19, 22, 03, 09, 00, 0e, 15, 02, 0e, 00, 13, 2a, 01, 0f, 00, 16, 19, 01, 15, 02, 0e, 2e, 04, 11, 00, 19, 19, 03, 09, 00, 0e, 1d, 02, 0e, 00, 13, 36, 01, 0c, 00, 13, 21, 01, 0d, 00, 15, 42, 01, 09, 00, 0a, 42, 01, 09, 00, 0e, 25, 02, 0e, 00, 13, 56, 01, 0f, 00, 16, 4e, 01, 16, 02, 0e, 29, 03, 12, 02, 0e, 56, 04, 09, 00, 0e, 2d, 02, 0e, 00, 13, 31, 01, 0f, 00, 16, 66, 01, 16, 02, 0e, 5e, 04, 11, 00, 16, 66, 03, 09, 00, 0e, 01, 02, 0d, 00, 0e, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
-Number of expressions: 22
+- file 0 => $DIR/continue.rs
+Number of expressions: 26
 - expression 0 operands: lhs = Counter(1), rhs = Counter(0)
-- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
+- expression 1 operands: lhs = Counter(1), rhs = Expression(4, Add)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(2)
-- expression 3 operands: lhs = Counter(3), rhs = Counter(0)
-- expression 4 operands: lhs = Counter(3), rhs = Expression(7, Add)
-- expression 5 operands: lhs = Counter(0), rhs = Counter(4)
-- expression 6 operands: lhs = Counter(3), rhs = Expression(7, Add)
+- expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add)
+- expression 4 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 5 operands: lhs = Counter(3), rhs = Counter(0)
+- expression 6 operands: lhs = Counter(3), rhs = Expression(9, Add)
 - expression 7 operands: lhs = Counter(0), rhs = Counter(4)
-- expression 8 operands: lhs = Counter(5), rhs = Counter(0)
-- expression 9 operands: lhs = Counter(5), rhs = Expression(10, Add)
-- expression 10 operands: lhs = Counter(0), rhs = Counter(6)
-- expression 11 operands: lhs = Counter(7), rhs = Counter(0)
-- expression 12 operands: lhs = Counter(7), rhs = Expression(13, Add)
-- expression 13 operands: lhs = Counter(0), rhs = Counter(8)
-- expression 14 operands: lhs = Counter(9), rhs = Counter(0)
-- expression 15 operands: lhs = Counter(9), rhs = Expression(16, Add)
-- expression 16 operands: lhs = Counter(0), rhs = Counter(10)
-- expression 17 operands: lhs = Counter(9), rhs = Counter(0)
-- expression 18 operands: lhs = Counter(11), rhs = Counter(0)
-- expression 19 operands: lhs = Expression(20, Add), rhs = Counter(11)
-- expression 20 operands: lhs = Counter(0), rhs = Counter(12)
-- expression 21 operands: lhs = Counter(11), rhs = Counter(0)
-Number of file 0 mappings: 30
-- Code(Counter(0)) at (prev + 3, 1) to (start + 3, 18)
-- Code(Counter(1)) at (prev + 4, 14) to (start + 0, 19)
+- expression 8 operands: lhs = Counter(3), rhs = Expression(9, Add)
+- expression 9 operands: lhs = Counter(0), rhs = Counter(4)
+- expression 10 operands: lhs = Counter(5), rhs = Counter(0)
+- expression 11 operands: lhs = Counter(5), rhs = Expression(12, Add)
+- expression 12 operands: lhs = Counter(0), rhs = Counter(6)
+- expression 13 operands: lhs = Counter(7), rhs = Counter(0)
+- expression 14 operands: lhs = Counter(7), rhs = Expression(17, Add)
+- expression 15 operands: lhs = Counter(0), rhs = Counter(8)
+- expression 16 operands: lhs = Counter(7), rhs = Expression(17, Add)
+- expression 17 operands: lhs = Counter(0), rhs = Counter(8)
+- expression 18 operands: lhs = Counter(9), rhs = Counter(0)
+- expression 19 operands: lhs = Counter(9), rhs = Expression(20, Add)
+- expression 20 operands: lhs = Counter(0), rhs = Counter(10)
+- expression 21 operands: lhs = Counter(9), rhs = Counter(0)
+- expression 22 operands: lhs = Counter(11), rhs = Counter(0)
+- expression 23 operands: lhs = Expression(24, Add), rhs = Counter(11)
+- expression 24 operands: lhs = Counter(0), rhs = Counter(12)
+- expression 25 operands: lhs = Counter(11), rhs = Counter(0)
+Number of file 0 mappings: 37
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
+- Code(Counter(1)) at (prev + 1, 14) to (start + 0, 19)
 - Code(Expression(0, Sub)) at (prev + 1, 15) to (start + 0, 22)
     = (c1 - c0)
 - Code(Counter(2)) at (prev + 2, 17) to (start + 0, 25)
-- Code(Expression(1, Sub)) at (prev + 2, 18) to (start + 4, 14)
+- Code(Expression(3, Sub)) at (prev + 2, 18) to (start + 2, 14)
     = (c1 - (c0 + c2))
-- Code(Counter(3)) at (prev + 6, 14) to (start + 0, 19)
-- Code(Expression(3, Sub)) at (prev + 1, 15) to (start + 0, 22)
+- Code(Expression(3, Sub)) at (prev + 4, 9) to (start + 0, 14)
+    = (c1 - (c0 + c2))
+- Code(Counter(3)) at (prev + 2, 14) to (start + 0, 19)
+- Code(Expression(5, Sub)) at (prev + 1, 15) to (start + 0, 22)
     = (c3 - c0)
-- Code(Expression(6, Sub)) at (prev + 1, 22) to (start + 2, 14)
+- Code(Expression(8, Sub)) at (prev + 1, 22) to (start + 2, 14)
     = (c3 - (c0 + c4))
 - Code(Counter(4)) at (prev + 4, 17) to (start + 0, 25)
-- Code(Expression(6, Sub)) at (prev + 3, 9) to (start + 0, 14)
+- Code(Expression(8, Sub)) at (prev + 3, 9) to (start + 0, 14)
     = (c3 - (c0 + c4))
 - Code(Counter(5)) at (prev + 2, 14) to (start + 0, 19)
-- Code(Expression(8, Sub)) at (prev + 1, 15) to (start + 0, 22)
+- Code(Expression(10, Sub)) at (prev + 1, 15) to (start + 0, 22)
     = (c5 - c0)
 - Code(Counter(6)) at (prev + 1, 21) to (start + 2, 14)
-- Code(Expression(9, Sub)) at (prev + 4, 17) to (start + 0, 25)
+- Code(Expression(11, Sub)) at (prev + 4, 17) to (start + 0, 25)
     = (c5 - (c0 + c6))
 - Code(Counter(6)) at (prev + 3, 9) to (start + 0, 14)
 - Code(Counter(7)) at (prev + 2, 14) to (start + 0, 19)
-- Code(Expression(11, Sub)) at (prev + 1, 12) to (start + 0, 19)
+- Code(Expression(13, Sub)) at (prev + 1, 12) to (start + 0, 19)
     = (c7 - c0)
 - Code(Counter(8)) at (prev + 1, 13) to (start + 0, 21)
-- Code(Expression(12, Sub)) at (prev + 1, 10) to (start + 1, 14)
+- Code(Expression(16, Sub)) at (prev + 1, 9) to (start + 0, 10)
+    = (c7 - (c0 + c8))
+- Code(Expression(16, Sub)) at (prev + 1, 9) to (start + 0, 14)
     = (c7 - (c0 + c8))
-- Code(Counter(9)) at (prev + 3, 14) to (start + 0, 19)
-- Code(Expression(17, Sub)) at (prev + 1, 15) to (start + 0, 22)
+- Code(Counter(9)) at (prev + 2, 14) to (start + 0, 19)
+- Code(Expression(21, Sub)) at (prev + 1, 15) to (start + 0, 22)
     = (c9 - c0)
-- Code(Expression(15, Sub)) at (prev + 1, 22) to (start + 2, 14)
+- Code(Expression(19, Sub)) at (prev + 1, 22) to (start + 2, 14)
     = (c9 - (c0 + c10))
 - Code(Counter(10)) at (prev + 3, 18) to (start + 2, 14)
-- Code(Expression(17, Sub)) at (prev + 4, 9) to (start + 0, 14)
+- Code(Expression(21, Sub)) at (prev + 4, 9) to (start + 0, 14)
     = (c9 - c0)
 - Code(Counter(11)) at (prev + 2, 14) to (start + 0, 19)
 - Code(Counter(12)) at (prev + 1, 15) to (start + 0, 22)
-- Code(Expression(21, Sub)) at (prev + 1, 22) to (start + 2, 14)
+- Code(Expression(25, Sub)) at (prev + 1, 22) to (start + 2, 14)
     = (c11 - c0)
-- Code(Expression(19, Sub)) at (prev + 4, 17) to (start + 0, 22)
+- Code(Expression(23, Sub)) at (prev + 4, 17) to (start + 0, 22)
     = ((c0 + c12) - c11)
-- Code(Expression(21, Sub)) at (prev + 3, 9) to (start + 0, 14)
+- Code(Expression(25, Sub)) at (prev + 3, 9) to (start + 0, 14)
     = (c11 - c0)
-- Code(Counter(0)) at (prev + 2, 13) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c12
 
diff --git a/tests/coverage/continue.coverage b/tests/coverage/continue.coverage
index 4916cac0038..17fe4874d15 100644
--- a/tests/coverage/continue.coverage
+++ b/tests/coverage/continue.coverage
@@ -2,7 +2,7 @@
    LL|       |
    LL|      1|fn main() {
    LL|      1|    let is_true = std::env::args().len() == 1;
-   LL|      1|
+   LL|       |
    LL|      1|    let mut x = 0;
    LL|     11|    for _ in 0..10 {
    LL|     10|        match is_true {
@@ -12,7 +12,7 @@
    LL|      0|            _ => {
    LL|      0|                x = 1;
    LL|      0|            }
-   LL|      0|        }
+   LL|       |        }
    LL|      0|        x = 3;
    LL|       |    }
    LL|     11|    for _ in 0..10 {
diff --git a/tests/coverage/coroutine.cov-map b/tests/coverage/coroutine.cov-map
index fee32376d83..daa42915a4a 100644
--- a/tests/coverage/coroutine.cov-map
+++ b/tests/coverage/coroutine.cov-map
@@ -1,31 +1,40 @@
 Function name: coroutine::get_u32
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0b, 01, 01, 0b, 05, 02, 09, 00, 0e, 02, 02, 09, 00, 28, 01, 02, 01, 00, 02]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 0b, 01, 00, 2d, 01, 01, 08, 00, 0b, 05, 01, 09, 00, 0e, 02, 02, 09, 00, 28, 01, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/coroutine.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 11, 1) to (start + 1, 11)
-- Code(Counter(1)) at (prev + 2, 9) to (start + 0, 14)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 45)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 11)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 14)
 - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 40)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: coroutine::main
-Raw bytes (53): 0x[01, 01, 02, 01, 05, 05, 09, 09, 01, 13, 01, 02, 16, 01, 08, 0b, 00, 2d, 05, 01, 2b, 00, 2d, 02, 01, 0e, 00, 14, 05, 02, 0b, 00, 2e, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 14, 09, 02, 01, 00, 02]
+Raw bytes (93): 0x[01, 01, 02, 01, 05, 05, 09, 11, 01, 13, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 16, 01, 06, 0b, 00, 13, 01, 00, 14, 00, 22, 01, 00, 24, 00, 2a, 01, 00, 2b, 00, 2d, 05, 01, 2b, 00, 2d, 02, 01, 0e, 00, 14, 05, 02, 0b, 00, 13, 05, 00, 0b, 00, 2e, 05, 00, 14, 00, 22, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 14, 09, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/coroutine.rs
 Number of expressions: 2
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 19, 1) to (start + 2, 22)
-- Code(Counter(0)) at (prev + 8, 11) to (start + 0, 45)
+Number of file 0 mappings: 17
+- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 6, 11) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 0, 36) to (start + 0, 42)
+- Code(Counter(0)) at (prev + 0, 43) to (start + 0, 45)
 - Code(Counter(1)) at (prev + 1, 43) to (start + 0, 45)
 - Code(Expression(0, Sub)) at (prev + 1, 14) to (start + 0, 20)
     = (c0 - c1)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 46)
+- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 19)
+- Code(Counter(1)) at (prev + 0, 11) to (start + 0, 46)
+- Code(Counter(1)) at (prev + 0, 20) to (start + 0, 34)
 - Code(Counter(3)) at (prev + 1, 34) to (start + 0, 39)
 - Code(Counter(2)) at (prev + 0, 44) to (start + 0, 46)
 - Code(Expression(1, Sub)) at (prev + 1, 14) to (start + 0, 20)
@@ -34,12 +43,14 @@ Number of file 0 mappings: 9
 Highest counter ID seen: c3
 
 Function name: coroutine::main::{closure#0}
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 16, 08, 01, 1f, 05, 02, 10, 01, 06]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 16, 08, 00, 09, 01, 01, 09, 00, 1f, 05, 01, 10, 00, 15, 05, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/coroutine.rs
 Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 22, 8) to (start + 1, 31)
-- Code(Counter(1)) at (prev + 2, 16) to (start + 1, 6)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 22, 8) to (start + 0, 9)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 31)
+- Code(Counter(1)) at (prev + 1, 16) to (start + 0, 21)
+- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: c1
 
diff --git a/tests/coverage/coverage_attr_closure.cov-map b/tests/coverage/coverage_attr_closure.cov-map
index fb861996a0d..deba65f22cc 100644
--- a/tests/coverage/coverage_attr_closure.cov-map
+++ b/tests/coverage/coverage_attr_closure.cov-map
@@ -1,38 +1,48 @@
 Function name: coverage_attr_closure::GLOBAL_CLOSURE_ON::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 06, 0f, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 06, 0f, 00, 10, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 17, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/coverage_attr_closure.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 6, 15) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 6, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: coverage_attr_closure::contains_closures_off::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 1d, 13, 02, 06]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 1d, 13, 00, 14, 00, 01, 09, 00, 11, 00, 00, 12, 00, 1b, 00, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/coverage_attr_closure.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 29, 19) to (start + 2, 6)
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 29, 19) to (start + 0, 20)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 17)
+- Code(Zero) at (prev + 0, 18) to (start + 0, 27)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: (none)
 
 Function name: coverage_attr_closure::contains_closures_on
-Raw bytes (19): 0x[01, 01, 00, 03, 01, 0f, 01, 01, 1a, 01, 05, 09, 00, 1b, 01, 04, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 0f, 01, 00, 1a, 01, 01, 09, 00, 1a, 01, 04, 09, 00, 1b, 01, 04, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/coverage_attr_closure.rs
 Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 15, 1) to (start + 1, 26)
-- Code(Counter(0)) at (prev + 5, 9) to (start + 0, 27)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 15, 1) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 27)
 - Code(Counter(0)) at (prev + 4, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: coverage_attr_closure::contains_closures_on::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 13, 02, 06]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 11, 13, 00, 14, 00, 01, 09, 00, 11, 00, 00, 12, 00, 1b, 00, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/coverage_attr_closure.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 17, 19) to (start + 2, 6)
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 17, 19) to (start + 0, 20)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 17)
+- Code(Zero) at (prev + 0, 18) to (start + 0, 27)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: (none)
 
diff --git a/tests/coverage/dead_code.cov-map b/tests/coverage/dead_code.cov-map
index 897372fe0b5..ae4146dc246 100644
--- a/tests/coverage/dead_code.cov-map
+++ b/tests/coverage/dead_code.cov-map
@@ -1,37 +1,52 @@
 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, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 1b, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0f, 05, 00, 10, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/dead_code.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(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)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 15)
+- Code(Counter(1)) at (prev + 0, 16) to (start + 2, 6)
 - 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, 05, 00, 06, 00, 01, 01, 00, 02]
+Raw bytes (49): 0x[01, 01, 00, 09, 00, 0f, 01, 00, 0f, 00, 04, 09, 00, 10, 00, 00, 13, 00, 2e, 00, 02, 09, 00, 16, 00, 00, 19, 00, 1a, 00, 01, 08, 00, 0f, 00, 00, 10, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/dead_code.rs
 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)
+Number of file 0 mappings: 9
+- Code(Zero) at (prev + 15, 1) to (start + 0, 15)
+- Code(Zero) at (prev + 4, 9) to (start + 0, 16)
+- Code(Zero) at (prev + 0, 19) to (start + 0, 46)
+- Code(Zero) at (prev + 2, 9) to (start + 0, 22)
+- Code(Zero) at (prev + 0, 25) to (start + 0, 26)
+- Code(Zero) at (prev + 1, 8) to (start + 0, 15)
+- Code(Zero) at (prev + 0, 16) to (start + 2, 6)
 - 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, 05, 00, 06, 00, 01, 01, 00, 02]
+Raw bytes (49): 0x[01, 01, 00, 09, 00, 03, 01, 00, 26, 00, 04, 09, 00, 10, 00, 00, 13, 00, 2e, 00, 02, 09, 00, 16, 00, 00, 19, 00, 1a, 00, 01, 08, 00, 0f, 00, 00, 10, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/dead_code.rs
 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)
+Number of file 0 mappings: 9
+- Code(Zero) at (prev + 3, 1) to (start + 0, 38)
+- Code(Zero) at (prev + 4, 9) to (start + 0, 16)
+- Code(Zero) at (prev + 0, 19) to (start + 0, 46)
+- Code(Zero) at (prev + 2, 9) to (start + 0, 22)
+- Code(Zero) at (prev + 0, 25) to (start + 0, 26)
+- Code(Zero) at (prev + 1, 8) to (start + 0, 15)
+- Code(Zero) at (prev + 0, 16) to (start + 2, 6)
 - 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 55d196f8160..fbb4a001d95 100644
--- a/tests/coverage/dead_code.coverage
+++ b/tests/coverage/dead_code.coverage
@@ -1,11 +1,11 @@
    LL|       |#![allow(dead_code, unused_assignments, unused_variables)]
    LL|       |
    LL|      0|pub fn unused_pub_fn_not_in_library() {
-   LL|      0|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-   LL|      0|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-   LL|      0|    // dependent conditions.
+   LL|       |    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|       |    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|       |    // dependent conditions.
    LL|      0|    let is_true = std::env::args().len() == 1;
-   LL|      0|
+   LL|       |
    LL|      0|    let mut countdown = 0;
    LL|      0|    if is_true {
    LL|      0|        countdown = 10;
@@ -13,11 +13,11 @@
    LL|      0|}
    LL|       |
    LL|      0|fn unused_fn() {
-   LL|      0|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-   LL|      0|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-   LL|      0|    // dependent conditions.
+   LL|       |    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|       |    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|       |    // dependent conditions.
    LL|      0|    let is_true = std::env::args().len() == 1;
-   LL|      0|
+   LL|       |
    LL|      0|    let mut countdown = 0;
    LL|      0|    if is_true {
    LL|      0|        countdown = 10;
@@ -25,11 +25,11 @@
    LL|      0|}
    LL|       |
    LL|      1|fn main() {
-   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-   LL|      1|    // dependent conditions.
+   LL|       |    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|       |    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|       |    // dependent conditions.
    LL|      1|    let is_true = std::env::args().len() == 1;
-   LL|      1|
+   LL|       |
    LL|      1|    let mut countdown = 0;
    LL|      1|    if is_true {
    LL|      1|        countdown = 10;
diff --git a/tests/coverage/drop_trait.cov-map b/tests/coverage/drop_trait.cov-map
index 16facf2eddf..dcf9dbd8c64 100644
--- a/tests/coverage/drop_trait.cov-map
+++ b/tests/coverage/drop_trait.cov-map
@@ -1,21 +1,33 @@
 Function name: <drop_trait::Firework as core::ops::drop::Drop>::drop
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 09, 05, 02, 06]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 09, 05, 00, 17, 01, 01, 09, 00, 11, 01, 00, 12, 00, 24, 01, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/drop_trait.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 9, 5) to (start + 2, 6)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 36)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: c0
 
 Function name: drop_trait::main
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 0e, 01, 05, 0c, 01, 06, 09, 01, 16, 00, 02, 06, 04, 0b, 01, 05, 01, 00, 02]
+Raw bytes (69): 0x[01, 01, 00, 0d, 01, 0e, 01, 00, 1c, 01, 01, 09, 00, 15, 01, 00, 18, 00, 30, 01, 02, 09, 00, 0d, 01, 00, 10, 00, 2a, 01, 02, 08, 00, 0c, 01, 01, 09, 00, 11, 01, 00, 12, 00, 29, 01, 01, 10, 00, 16, 00, 01, 05, 00, 06, 00, 02, 0d, 00, 28, 00, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/drop_trait.rs
 Number of expressions: 0
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 14, 1) to (start + 5, 12)
-- Code(Counter(0)) at (prev + 6, 9) to (start + 1, 22)
-- Code(Zero) at (prev + 2, 6) to (start + 4, 11)
-- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 2)
+Number of file 0 mappings: 13
+- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 48)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 42)
+- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 41)
+- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 22)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 6)
+- Code(Zero) at (prev + 2, 13) to (start + 0, 40)
+- Code(Zero) at (prev + 2, 5) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/drop_trait.coverage b/tests/coverage/drop_trait.coverage
index 85d557573cf..10ed8c0f154 100644
--- a/tests/coverage/drop_trait.coverage
+++ b/tests/coverage/drop_trait.coverage
@@ -13,16 +13,16 @@
    LL|       |
    LL|      1|fn main() -> Result<(), u8> {
    LL|      1|    let _firecracker = Firework { strength: 1 };
-   LL|      1|
+   LL|       |
    LL|      1|    let _tnt = Firework { strength: 100 };
-   LL|      1|
+   LL|       |
    LL|      1|    if true {
    LL|      1|        println!("Exiting with error...");
    LL|      1|        return Err(1);
    LL|      0|    }
-   LL|      0|
+   LL|       |
    LL|      0|    let _ = Firework { strength: 1000 };
-   LL|      0|
+   LL|       |
    LL|      0|    Ok(())
    LL|      1|}
    LL|       |
diff --git a/tests/coverage/fn_sig_into_try.cov-map b/tests/coverage/fn_sig_into_try.cov-map
index 6d6034928c9..fc57a4892be 100644
--- a/tests/coverage/fn_sig_into_try.cov-map
+++ b/tests/coverage/fn_sig_into_try.cov-map
@@ -1,44 +1,52 @@
 Function name: fn_sig_into_try::a
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 01, 05, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 0a, 01, 00, 16, 01, 03, 05, 00, 0f, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/fn_sig_into_try.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 10, 1) to (start + 5, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: fn_sig_into_try::b
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 11, 01, 03, 0f, 00, 03, 0f, 00, 10, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 11, 01, 00, 16, 01, 03, 05, 00, 0f, 00, 00, 0f, 00, 10, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/fn_sig_into_try.rs
 Number of expressions: 0
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 17, 1) to (start + 3, 15)
-- Code(Zero) at (prev + 3, 15) to (start + 0, 16)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 15)
+- Code(Zero) at (prev + 0, 15) to (start + 0, 16)
 - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: fn_sig_into_try::c
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 18, 01, 03, 17, 00, 03, 17, 00, 18, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 18, 01, 00, 16, 01, 03, 0d, 00, 17, 00, 00, 17, 00, 18, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/fn_sig_into_try.rs
 Number of expressions: 0
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 24, 1) to (start + 3, 23)
-- Code(Zero) at (prev + 3, 23) to (start + 0, 24)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 24, 1) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 3, 13) to (start + 0, 23)
+- Code(Zero) at (prev + 0, 23) to (start + 0, 24)
 - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: fn_sig_into_try::d
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 1f, 01, 04, 0f, 00, 04, 0f, 00, 10, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
+Raw bytes (39): 0x[01, 01, 00, 07, 01, 1f, 01, 00, 16, 01, 03, 0c, 00, 0e, 01, 00, 11, 00, 13, 01, 01, 05, 00, 0f, 00, 00, 0f, 00, 10, 01, 01, 05, 00, 0c, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/fn_sig_into_try.rs
 Number of expressions: 0
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 31, 1) to (start + 4, 15)
-- Code(Zero) at (prev + 4, 15) to (start + 0, 16)
+Number of file 0 mappings: 7
+- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 3, 12) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Zero) at (prev + 0, 15) to (start + 0, 16)
 - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 12)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
diff --git a/tests/coverage/fn_sig_into_try.coverage b/tests/coverage/fn_sig_into_try.coverage
index cabe747ce5a..bc744db4b69 100644
--- a/tests/coverage/fn_sig_into_try.coverage
+++ b/tests/coverage/fn_sig_into_try.coverage
@@ -8,31 +8,31 @@
    LL|       |// signature should be handled in the same way.
    LL|       |
    LL|      1|fn a() -> Option<i32>
-   LL|      1|//
-   LL|      1|{
+   LL|       |//
+   LL|       |{
    LL|      1|    Some(7i32);
    LL|      1|    Some(0)
    LL|      1|}
    LL|       |
    LL|      1|fn b() -> Option<i32>
-   LL|      1|//
-   LL|      1|{
+   LL|       |//
+   LL|       |{
    LL|      1|    Some(7i32)?;
                             ^0
    LL|      1|    Some(0)
    LL|      1|}
    LL|       |
    LL|      1|fn c() -> Option<i32>
-   LL|      1|//
-   LL|      1|{
+   LL|       |//
+   LL|       |{
    LL|      1|    let _ = Some(7i32)?;
                                     ^0
    LL|      1|    Some(0)
    LL|      1|}
    LL|       |
    LL|      1|fn d() -> Option<i32>
-   LL|      1|//
-   LL|      1|{
+   LL|       |//
+   LL|       |{
    LL|      1|    let _: () = ();
    LL|      1|    Some(7i32)?;
                             ^0
diff --git a/tests/coverage/generic-unused-impl.cov-map b/tests/coverage/generic-unused-impl.cov-map
index 5878de231ba..da9e5495a72 100644
--- a/tests/coverage/generic-unused-impl.cov-map
+++ b/tests/coverage/generic-unused-impl.cov-map
@@ -1,18 +1,23 @@
 Function name: <generic_unused_impl::W<_> as core::convert::From<[<_ as generic_unused_impl::Foo>::Assoc; 1]>>::from (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 0b, 05, 03, 06]
+Raw bytes (29): 0x[01, 01, 00, 05, 00, 0b, 05, 00, 29, 00, 01, 0e, 00, 12, 00, 00, 16, 00, 1a, 00, 01, 09, 00, 1b, 00, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/generic-unused-impl.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 11, 5) to (start + 3, 6)
+Number of file 0 mappings: 5
+- Code(Zero) at (prev + 11, 5) to (start + 0, 41)
+- Code(Zero) at (prev + 1, 14) to (start + 0, 18)
+- Code(Zero) at (prev + 0, 22) to (start + 0, 26)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 27)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: (none)
 
 Function name: generic_unused_impl::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 01, 00, 0d]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 11, 01, 00, 0a, 01, 00, 0c, 00, 0d]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/generic-unused-impl.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 13)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/generics.cov-map b/tests/coverage/generics.cov-map
index bc5661afdc1..7f9b7ee0f47 100644
--- a/tests/coverage/generics.cov-map
+++ b/tests/coverage/generics.cov-map
@@ -1,48 +1,73 @@
 Function name: <generics::Firework<f64> as core::ops::drop::Drop>::drop
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 05, 02, 06]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 11, 05, 00, 17, 01, 01, 09, 00, 11, 01, 00, 12, 00, 24, 01, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/generics.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 17, 5) to (start + 2, 6)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 17, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 36)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: c0
 
 Function name: <generics::Firework<f64>>::set_strength
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 05, 02, 06]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 0a, 05, 00, 30, 01, 01, 09, 00, 25, 01, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/generics.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 10, 5) to (start + 2, 6)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 48)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: c0
 
 Function name: <generics::Firework<i32> as core::ops::drop::Drop>::drop
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 05, 02, 06]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 11, 05, 00, 17, 01, 01, 09, 00, 11, 01, 00, 12, 00, 24, 01, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/generics.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 17, 5) to (start + 2, 6)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 17, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 36)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: c0
 
 Function name: <generics::Firework<i32>>::set_strength
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 05, 02, 06]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 0a, 05, 00, 30, 01, 01, 09, 00, 25, 01, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/generics.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 10, 5) to (start + 2, 6)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 48)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: c0
 
 Function name: generics::main
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 16, 01, 08, 0c, 01, 09, 09, 01, 16, 00, 02, 06, 04, 0b, 01, 05, 01, 00, 02]
+Raw bytes (99): 0x[01, 01, 00, 13, 01, 16, 01, 00, 1c, 01, 01, 09, 00, 18, 01, 00, 1b, 00, 33, 01, 01, 05, 00, 10, 01, 00, 11, 00, 1d, 01, 02, 09, 00, 10, 01, 00, 13, 00, 2f, 01, 01, 05, 00, 08, 01, 00, 09, 00, 15, 01, 01, 05, 00, 08, 01, 00, 09, 00, 15, 01, 02, 08, 00, 0c, 01, 01, 09, 00, 11, 01, 00, 12, 00, 29, 01, 01, 10, 00, 16, 00, 01, 05, 00, 06, 00, 02, 0d, 00, 28, 00, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/generics.rs
 Number of expressions: 0
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 22, 1) to (start + 8, 12)
-- Code(Counter(0)) at (prev + 9, 9) to (start + 1, 22)
-- Code(Zero) at (prev + 2, 6) to (start + 4, 11)
-- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 2)
+Number of file 0 mappings: 19
+- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 0, 27) to (start + 0, 51)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 47)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 41)
+- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 22)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 6)
+- Code(Zero) at (prev + 2, 13) to (start + 0, 40)
+- Code(Zero) at (prev + 2, 5) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/generics.coverage b/tests/coverage/generics.coverage
index a2cd1465d26..43697cacb9a 100644
--- a/tests/coverage/generics.coverage
+++ b/tests/coverage/generics.coverage
@@ -44,18 +44,18 @@
    LL|      1|fn main() -> Result<(), u8> {
    LL|      1|    let mut firecracker = Firework { strength: 1 };
    LL|      1|    firecracker.set_strength(2);
-   LL|      1|
+   LL|       |
    LL|      1|    let mut tnt = Firework { strength: 100.1 };
    LL|      1|    tnt.set_strength(200.1);
    LL|      1|    tnt.set_strength(300.3);
-   LL|      1|
+   LL|       |
    LL|      1|    if true {
    LL|      1|        println!("Exiting with error...");
    LL|      1|        return Err(1);
    LL|      0|    }
-   LL|      0|
+   LL|       |
    LL|      0|    let _ = Firework { strength: 1000 };
-   LL|      0|
+   LL|       |
    LL|      0|    Ok(())
    LL|      1|}
    LL|       |
diff --git a/tests/coverage/holes.cov-map b/tests/coverage/holes.cov-map
index 6e2d243e8dd..c2158c44150 100644
--- a/tests/coverage/holes.cov-map
+++ b/tests/coverage/holes.cov-map
@@ -1,57 +1,81 @@
 Function name: <holes::main::MyStruct>::_method (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 2b, 09, 00, 1d]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 2b, 09, 00, 1a, 00, 00, 1c, 00, 1d]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/holes.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 43, 9) to (start + 0, 29)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 43, 9) to (start + 0, 26)
+- Code(Zero) at (prev + 0, 28) to (start + 0, 29)
 Highest counter ID seen: (none)
 
 Function name: holes::main
-Raw bytes (69): 0x[01, 01, 00, 0d, 01, 08, 01, 01, 11, 01, 05, 05, 00, 11, 01, 07, 09, 00, 11, 01, 09, 05, 00, 11, 01, 04, 05, 00, 11, 01, 07, 05, 00, 11, 01, 06, 05, 00, 11, 01, 04, 05, 00, 11, 01, 04, 05, 00, 11, 01, 06, 05, 03, 0f, 01, 0a, 05, 03, 0f, 01, 0a, 05, 06, 27, 01, 13, 05, 01, 02]
+Raw bytes (154): 0x[01, 01, 00, 1e, 01, 08, 01, 00, 0a, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 04, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 07, 09, 00, 11, 01, 09, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 04, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 07, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 06, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 04, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 04, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 06, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 03, 09, 00, 0f, 01, 07, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 03, 09, 00, 0f, 01, 07, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 06, 09, 00, 27, 01, 0d, 05, 00, 0e, 01, 00, 0f, 00, 11, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/holes.rs
 Number of expressions: 0
-Number of file 0 mappings: 13
-- Code(Counter(0)) at (prev + 8, 1) to (start + 1, 17)
-- Code(Counter(0)) at (prev + 5, 5) to (start + 0, 17)
+Number of file 0 mappings: 30
+- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
 - Code(Counter(0)) at (prev + 7, 9) to (start + 0, 17)
-- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 17)
-- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 17)
-- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 17)
-- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 17)
-- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 17)
-- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 17)
-- Code(Counter(0)) at (prev + 6, 5) to (start + 3, 15)
-- Code(Counter(0)) at (prev + 10, 5) to (start + 3, 15)
-- Code(Counter(0)) at (prev + 10, 5) to (start + 6, 39)
-- Code(Counter(0)) at (prev + 19, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 6, 9) to (start + 0, 39)
+- Code(Counter(0)) at (prev + 13, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: holes::main::_unused_fn (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 1f, 05, 00, 17]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 1f, 05, 00, 14, 00, 00, 16, 00, 17]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/holes.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 31, 5) to (start + 0, 23)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 31, 5) to (start + 0, 20)
+- Code(Zero) at (prev + 0, 22) to (start + 0, 23)
 Highest counter ID seen: (none)
 
 Function name: holes::main::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 18, 09, 02, 0a]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 18, 09, 00, 0a, 00, 01, 0d, 00, 16, 00, 00, 17, 00, 19, 00, 01, 09, 00, 0a]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/holes.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 24, 9) to (start + 2, 10)
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 24, 9) to (start + 0, 10)
+- Code(Zero) at (prev + 1, 13) to (start + 0, 22)
+- Code(Zero) at (prev + 0, 23) to (start + 0, 25)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 10)
 Highest counter ID seen: (none)
 
 Function name: holes::main::{closure#1} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 4b, 09, 02, 0a]
+Raw bytes (19): 0x[01, 01, 00, 03, 00, 4b, 09, 00, 0a, 00, 01, 0d, 00, 12, 00, 01, 09, 00, 0a]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/holes.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 75, 9) to (start + 2, 10)
+Number of file 0 mappings: 3
+- Code(Zero) at (prev + 75, 9) to (start + 0, 10)
+- Code(Zero) at (prev + 1, 13) to (start + 0, 18)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 10)
 Highest counter ID seen: (none)
 
diff --git a/tests/coverage/holes.coverage b/tests/coverage/holes.coverage
index a6a02f1b9d0..1ea60491800 100644
--- a/tests/coverage/holes.coverage
+++ b/tests/coverage/holes.coverage
@@ -58,8 +58,8 @@
    LL|       |    }
    LL|       |
    LL|      1|    black_box(());
-   LL|      1|
-   LL|      1|    #[rustfmt::skip]
+   LL|       |
+   LL|       |    #[rustfmt::skip]
    LL|      1|    let _const =
    LL|       |        const
    LL|       |        {
@@ -68,8 +68,8 @@
    LL|       |        ;
    LL|       |
    LL|      1|    black_box(());
-   LL|      1|
-   LL|      1|    #[rustfmt::skip]
+   LL|       |
+   LL|       |    #[rustfmt::skip]
    LL|      1|    let _async =
    LL|       |        async
    LL|      0|        {
@@ -78,11 +78,11 @@
    LL|       |        ;
    LL|       |
    LL|      1|    black_box(());
-   LL|      1|
-   LL|      1|    // This tests the edge case of a const block nested inside an "anon const",
-   LL|      1|    // such as the length of an array literal. Handling this case requires
-   LL|      1|    // `nested_filter::OnlyBodies` or equivalent.
-   LL|      1|    #[rustfmt::skip]
+   LL|       |
+   LL|       |    // This tests the edge case of a const block nested inside an "anon const",
+   LL|       |    // such as the length of an array literal. Handling this case requires
+   LL|       |    // `nested_filter::OnlyBodies` or equivalent.
+   LL|       |    #[rustfmt::skip]
    LL|      1|    let _const_block_inside_anon_const =
    LL|       |        [
    LL|       |            0
diff --git a/tests/coverage/if.cov-map b/tests/coverage/if.cov-map
index a77ba8194a4..044c0f2ba08 100644
--- a/tests/coverage/if.cov-map
+++ b/tests/coverage/if.cov-map
@@ -1,12 +1,17 @@
 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, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 04, 01, 00, 0a, 01, 05, 05, 00, 0c, 01, 02, 09, 02, 0a, 01, 05, 09, 01, 0e, 01, 03, 09, 00, 0a, 01, 03, 09, 00, 10, 05, 01, 05, 05, 06, 02, 05, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/if.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(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)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 5, 5) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 2, 10)
+- Code(Counter(0)) at (prev + 5, 9) to (start + 1, 14)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 1, 5) to (start + 5, 6)
 - 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)
diff --git a/tests/coverage/if.coverage b/tests/coverage/if.coverage
index 0762418347c..c3c8a1bf38a 100644
--- a/tests/coverage/if.coverage
+++ b/tests/coverage/if.coverage
@@ -2,23 +2,23 @@
    LL|       |
    LL|       |#[rustfmt::skip]
    LL|      1|fn main() {
-   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-   LL|      1|    // dependent conditions.
-   LL|      1|    let
+   LL|       |    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|       |    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|       |    // dependent conditions.
+   LL|       |    let
    LL|      1|    is_true
-   LL|      1|    =
+   LL|       |    =
    LL|      1|        std::env::args().len()
    LL|      1|    ==
    LL|      1|        1
-   LL|      1|    ;
-   LL|      1|    let
+   LL|       |    ;
+   LL|       |    let
    LL|      1|        mut
    LL|      1|    countdown
-   LL|      1|    =
+   LL|       |    =
    LL|      1|        0
-   LL|      1|    ;
-   LL|      1|    if
+   LL|       |    ;
+   LL|       |    if
    LL|      1|        is_true
    LL|      1|    {
    LL|      1|        countdown
diff --git a/tests/coverage/if_else.cov-map b/tests/coverage/if_else.cov-map
index 194ad6ca71f..1d8ca180953 100644
--- a/tests/coverage/if_else.cov-map
+++ b/tests/coverage/if_else.cov-map
@@ -1,13 +1,18 @@
 Function name: if_else::main
-Raw bytes (43): 0x[01, 01, 02, 01, 05, 01, 09, 07, 01, 04, 01, 08, 10, 05, 09, 05, 05, 06, 02, 08, 09, 02, 10, 01, 06, 09, 00, 10, 09, 01, 05, 05, 06, 06, 07, 05, 05, 06, 01, 06, 01, 00, 02]
+Raw bytes (68): 0x[01, 01, 02, 01, 05, 01, 09, 0c, 01, 04, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 02, 09, 00, 10, 05, 01, 05, 05, 06, 02, 08, 09, 02, 10, 01, 06, 09, 00, 10, 09, 01, 05, 05, 06, 06, 07, 05, 05, 06, 01, 06, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/if_else.rs
 Number of expressions: 2
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 7
-- Code(Counter(0)) at (prev + 4, 1) to (start + 8, 16)
-- Code(Counter(1)) at (prev + 9, 5) to (start + 5, 6)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 1, 5) to (start + 5, 6)
 - Code(Expression(0, Sub)) at (prev + 8, 9) to (start + 2, 16)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 6, 9) to (start + 0, 16)
diff --git a/tests/coverage/if_else.coverage b/tests/coverage/if_else.coverage
index 2bf93487cec..148e2b19517 100644
--- a/tests/coverage/if_else.coverage
+++ b/tests/coverage/if_else.coverage
@@ -2,13 +2,13 @@
    LL|       |
    LL|       |#[rustfmt::skip]
    LL|      1|fn main() {
-   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-   LL|      1|    // dependent conditions.
+   LL|       |    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|       |    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|       |    // dependent conditions.
    LL|      1|    let is_true = std::env::args().len() == 1;
-   LL|      1|
+   LL|       |
    LL|      1|    let mut countdown = 0;
-   LL|      1|    if
+   LL|       |    if
    LL|      1|        is_true
    LL|      1|    {
    LL|      1|        countdown
diff --git a/tests/coverage/if_not.cov-map b/tests/coverage/if_not.cov-map
index f47139ce5a4..1b1a1b30e93 100644
--- a/tests/coverage/if_not.cov-map
+++ b/tests/coverage/if_not.cov-map
@@ -1,14 +1,15 @@
 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, 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]
+Raw bytes (65): 0x[01, 01, 03, 01, 05, 01, 09, 01, 0d, 0b, 01, 05, 01, 00, 16, 01, 02, 09, 01, 0d, 02, 02, 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
+- file 0 => $DIR/if_not.rs
 Number of expressions: 3
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(3)
-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)
+Number of file 0 mappings: 11
+- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 1, 13)
+- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 2, 6)
     = (c0 - c1)
 - Code(Counter(1)) at (prev + 2, 5) to (start + 0, 6)
 - Code(Counter(0)) at (prev + 3, 9) to (start + 1, 13)
diff --git a/tests/coverage/if_not.coverage b/tests/coverage/if_not.coverage
index 678ccf9f2f8..8478e861a3a 100644
--- a/tests/coverage/if_not.coverage
+++ b/tests/coverage/if_not.coverage
@@ -3,7 +3,7 @@
    LL|       |
    LL|       |#[rustfmt::skip]
    LL|     12|fn if_not(cond: bool) {
-   LL|     12|    if
+   LL|       |    if
    LL|     12|        !
    LL|     12|        cond
    LL|      4|    {
diff --git a/tests/coverage/ignore_run.cov-map b/tests/coverage/ignore_run.cov-map
index c8ad3821e16..0d8245c54dc 100644
--- a/tests/coverage/ignore_run.cov-map
+++ b/tests/coverage/ignore_run.cov-map
@@ -1,9 +1,10 @@
 Function name: ignore_run::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 03, 01, 00, 0d]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 03, 01, 00, 0a, 01, 00, 0c, 00, 0d]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/ignore_run.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 13)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/inline-dead.cov-map b/tests/coverage/inline-dead.cov-map
index 65cefe76c29..95a5f6bf68b 100644
--- a/tests/coverage/inline-dead.cov-map
+++ b/tests/coverage/inline-dead.cov-map
@@ -1,44 +1,53 @@
 Function name: inline_dead::dead (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 17, 01, 02, 02]
+Raw bytes (19): 0x[01, 01, 00, 03, 00, 17, 01, 00, 11, 00, 01, 05, 00, 07, 00, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/inline-dead.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 23, 1) to (start + 2, 2)
+Number of file 0 mappings: 3
+- Code(Zero) at (prev + 23, 1) to (start + 0, 17)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 7)
+- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: (none)
 
 Function name: inline_dead::live::<false>
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0e, 01, 01, 09, 05, 02, 09, 00, 0d, 02, 02, 09, 00, 0a, 01, 02, 01, 00, 02]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 0e, 01, 00, 20, 01, 01, 08, 00, 09, 05, 01, 09, 00, 0d, 02, 02, 09, 00, 0a, 01, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/inline-dead.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 14, 1) to (start + 1, 9)
-- Code(Counter(1)) at (prev + 2, 9) to (start + 0, 13)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 13)
 - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: inline_dead::main
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 04, 01, 03, 0a, 01, 06, 05, 01, 02]
+Raw bytes (39): 0x[01, 01, 00, 07, 01, 04, 01, 00, 0a, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 12, 01, 00, 14, 00, 21, 01, 02, 09, 00, 0a, 01, 03, 05, 00, 0d, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/inline-dead.rs
 Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 4, 1) to (start + 3, 10)
-- Code(Counter(0)) at (prev + 6, 5) to (start + 1, 2)
+Number of file 0 mappings: 7
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: inline_dead::main::{closure#0}
-Raw bytes (19): 0x[01, 01, 00, 03, 01, 07, 17, 01, 16, 00, 01, 17, 00, 18, 01, 01, 05, 00, 06]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 07, 17, 00, 18, 01, 01, 09, 00, 16, 00, 00, 17, 00, 18, 01, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/inline-dead.rs
 Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 7, 23) to (start + 1, 22)
-- Code(Zero) at (prev + 1, 23) to (start + 0, 24)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 7, 23) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Zero) at (prev + 0, 23) to (start + 0, 24)
 - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/inline-dead.coverage b/tests/coverage/inline-dead.coverage
index c12668ce89a..d75aaf30062 100644
--- a/tests/coverage/inline-dead.coverage
+++ b/tests/coverage/inline-dead.coverage
@@ -3,7 +3,7 @@
    LL|       |
    LL|      1|fn main() {
    LL|      1|    println!("{}", live::<false>());
-   LL|      1|
+   LL|       |
    LL|      1|    let f = |x: bool| {
    LL|      1|        debug_assert!(x);
                                     ^0
diff --git a/tests/coverage/inline.cov-map b/tests/coverage/inline.cov-map
index 7264391baaf..4c67dd96ac2 100644
--- a/tests/coverage/inline.cov-map
+++ b/tests/coverage/inline.cov-map
@@ -1,86 +1,137 @@
 Function name: inline::display::<char>
-Raw bytes (31): 0x[01, 01, 01, 05, 01, 05, 01, 29, 01, 00, 22, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 10, 02, 00, 11, 02, 06, 01, 03, 05, 01, 02]
+Raw bytes (36): 0x[01, 01, 01, 05, 01, 06, 01, 29, 01, 00, 21, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 10, 02, 00, 11, 02, 06, 01, 03, 05, 00, 0d, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/inline.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(1), rhs = Counter(0)
-Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 41, 1) to (start + 0, 34)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 41, 1) to (start + 0, 33)
 - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10)
     = (c1 - c0)
 - Code(Counter(1)) at (prev + 0, 14) to (start + 0, 16)
 - Code(Expression(0, Sub)) at (prev + 0, 17) to (start + 2, 6)
     = (c1 - c0)
-- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: inline::error
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 31, 01, 01, 0b]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 31, 01, 00, 0b, 01, 01, 05, 00, 0b]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/inline.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 49, 1) to (start + 1, 11)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 49, 1) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 11)
 Highest counter ID seen: c0
 
 Function name: inline::length::<char>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1e, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 1e, 01, 00, 20, 01, 01, 05, 00, 07, 01, 00, 08, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/inline.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 30, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 30, 1) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 7)
+- Code(Counter(0)) at (prev + 0, 8) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: inline::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 05, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 05, 01, 00, 0a, 01, 01, 05, 00, 11, 01, 00, 12, 00, 22, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/inline.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 5, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: inline::permutate::<char>
-Raw bytes (54): 0x[01, 01, 05, 01, 05, 0d, 09, 0d, 09, 01, 13, 05, 09, 08, 01, 0f, 01, 02, 0e, 05, 02, 0f, 02, 06, 02, 02, 0f, 00, 14, 0a, 01, 0d, 00, 0e, 09, 00, 12, 00, 16, 0a, 00, 17, 04, 0a, 0e, 05, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (142): 0x[01, 01, 0e, 01, 05, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 01, 37, 05, 09, 16, 01, 0f, 01, 00, 38, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 13, 01, 00, 14, 00, 16, 01, 01, 08, 00, 0e, 05, 00, 0f, 02, 06, 02, 02, 0f, 00, 14, 2e, 01, 0d, 00, 0e, 09, 00, 12, 00, 13, 09, 00, 15, 00, 16, 2e, 00, 17, 04, 0a, 2e, 01, 0d, 00, 11, 2e, 00, 12, 00, 14, 2e, 00, 16, 00, 17, 2e, 00, 19, 00, 1a, 2e, 01, 0d, 00, 16, 2e, 00, 17, 00, 19, 2e, 00, 1b, 00, 20, 2e, 01, 0d, 00, 11, 2e, 00, 12, 00, 14, 32, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
-Number of expressions: 5
+- file 0 => $DIR/inline.rs
+Number of expressions: 14
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(3), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(3), rhs = Counter(2)
-- expression 3 operands: lhs = Counter(0), rhs = Expression(4, Add)
-- expression 4 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 15, 1) to (start + 2, 14)
-- Code(Counter(1)) at (prev + 2, 15) to (start + 2, 6)
+- expression 3 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 4 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 5 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 6 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 7 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 8 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 9 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 10 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 11 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 12 operands: lhs = Counter(0), rhs = Expression(13, Add)
+- expression 13 operands: lhs = Counter(1), rhs = Counter(2)
+Number of file 0 mappings: 22
+- Code(Counter(0)) at (prev + 15, 1) to (start + 0, 56)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 14)
+- Code(Counter(1)) at (prev + 0, 15) to (start + 2, 6)
 - Code(Expression(0, Sub)) at (prev + 2, 15) to (start + 0, 20)
     = (c0 - c1)
-- Code(Expression(2, Sub)) at (prev + 1, 13) to (start + 0, 14)
+- Code(Expression(11, Sub)) at (prev + 1, 13) to (start + 0, 14)
     = (c3 - c2)
-- Code(Counter(2)) at (prev + 0, 18) to (start + 0, 22)
-- Code(Expression(2, Sub)) at (prev + 0, 23) to (start + 4, 10)
+- Code(Counter(2)) at (prev + 0, 18) to (start + 0, 19)
+- Code(Counter(2)) at (prev + 0, 21) to (start + 0, 22)
+- Code(Expression(11, Sub)) at (prev + 0, 23) to (start + 4, 10)
     = (c3 - c2)
-- Code(Expression(3, Sub)) at (prev + 5, 12) to (start + 2, 6)
+- Code(Expression(11, Sub)) at (prev + 1, 13) to (start + 0, 17)
+    = (c3 - c2)
+- Code(Expression(11, Sub)) at (prev + 0, 18) to (start + 0, 20)
+    = (c3 - c2)
+- Code(Expression(11, Sub)) at (prev + 0, 22) to (start + 0, 23)
+    = (c3 - c2)
+- Code(Expression(11, Sub)) at (prev + 0, 25) to (start + 0, 26)
+    = (c3 - c2)
+- Code(Expression(11, Sub)) at (prev + 1, 13) to (start + 0, 22)
+    = (c3 - c2)
+- Code(Expression(11, Sub)) at (prev + 0, 23) to (start + 0, 25)
+    = (c3 - c2)
+- Code(Expression(11, Sub)) at (prev + 0, 27) to (start + 0, 32)
+    = (c3 - c2)
+- Code(Expression(11, Sub)) at (prev + 1, 13) to (start + 0, 17)
+    = (c3 - c2)
+- Code(Expression(11, Sub)) at (prev + 0, 18) to (start + 0, 20)
+    = (c3 - c2)
+- Code(Expression(12, Sub)) at (prev + 2, 12) to (start + 2, 6)
     = (c0 - (c1 + c2))
 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
 Highest counter ID seen: c2
 
 Function name: inline::permutations::<char>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 01, 03, 02]
+Raw bytes (39): 0x[01, 01, 00, 07, 01, 0a, 01, 00, 2d, 01, 01, 09, 00, 0f, 01, 00, 12, 00, 14, 01, 00, 15, 00, 1d, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 16, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/inline.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 10, 1) to (start + 3, 2)
+Number of file 0 mappings: 7
+- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 45)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 0, 21) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: inline::swap::<char>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 23, 01, 04, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 23, 01, 00, 33, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 12, 01, 01, 05, 00, 12, 01, 01, 05, 00, 0e, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/inline.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 35, 1) to (start + 4, 2)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 35, 1) to (start + 0, 51)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/inline.coverage b/tests/coverage/inline.coverage
index 3d322126a38..5fe069d5389 100644
--- a/tests/coverage/inline.coverage
+++ b/tests/coverage/inline.coverage
@@ -18,7 +18,7 @@
    LL|      6|        display(xs);
    LL|     10|    } else if k < n {
    LL|     15|        for i in k..n {
-                               ^10
+                               ^10^10
    LL|     15|            swap(xs, i, k);
    LL|     15|            permutate(xs, k + 1);
    LL|     15|            swap(xs, i, k);
diff --git a/tests/coverage/inner_items.cov-map b/tests/coverage/inner_items.cov-map
index a12cce25b64..ca6ddfda2dd 100644
--- a/tests/coverage/inner_items.cov-map
+++ b/tests/coverage/inner_items.cov-map
@@ -1,46 +1,70 @@
 Function name: <inner_items::main::InStruct as inner_items::main::InTrait>::default_trait_func
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 09, 03, 0a]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 21, 09, 00, 29, 01, 01, 0d, 00, 14, 01, 01, 0d, 00, 11, 01, 00, 12, 00, 1c, 01, 01, 09, 00, 0a]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/inner_items.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 33, 9) to (start + 3, 10)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 33, 9) to (start + 0, 41)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
 Highest counter ID seen: c0
 
 Function name: <inner_items::main::InStruct as inner_items::main::InTrait>::trait_func
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 28, 09, 03, 0a]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 28, 09, 00, 2c, 01, 01, 0d, 00, 29, 01, 01, 0d, 00, 14, 01, 00, 15, 00, 29, 01, 01, 09, 00, 0a]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/inner_items.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 40, 9) to (start + 3, 10)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 40, 9) to (start + 0, 44)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 41)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 0, 21) to (start + 0, 41)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
 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, 05, 00, 06, 01, 24, 08, 00, 0f, 09, 00, 10, 02, 06, 06, 02, 05, 00, 06, 01, 02, 09, 05, 02]
+Raw bytes (88): 0x[01, 01, 02, 01, 05, 01, 09, 10, 01, 03, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0f, 05, 00, 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, 00, 10, 01, 00, 13, 02, 06, 01, 04, 05, 00, 08, 01, 00, 09, 00, 1b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/inner_items.rs
 Number of expressions: 2
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(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)
+Number of file 0 mappings: 16
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 15)
+- Code(Counter(1)) at (prev + 0, 16) to (start + 2, 6)
 - 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, 5) to (start + 0, 6)
     = (c0 - c2)
-- Code(Counter(0)) at (prev + 2, 9) to (start + 5, 2)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 2, 6)
+- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 8)
+- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c2
 
 Function name: inner_items::main::in_func
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 12, 05, 04, 06]
+Raw bytes (44): 0x[01, 01, 00, 08, 01, 12, 05, 00, 17, 01, 01, 0d, 00, 0e, 01, 00, 11, 00, 12, 01, 01, 0d, 00, 0e, 01, 00, 11, 00, 16, 01, 01, 09, 00, 11, 01, 00, 12, 00, 1a, 01, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/inner_items.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 18, 5) to (start + 4, 6)
+Number of file 0 mappings: 8
+- Code(Counter(0)) at (prev + 18, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/inner_items.coverage b/tests/coverage/inner_items.coverage
index 8244d347b59..8503cc12f23 100644
--- a/tests/coverage/inner_items.coverage
+++ b/tests/coverage/inner_items.coverage
@@ -1,11 +1,11 @@
    LL|       |#![allow(unused_assignments, unused_variables, dead_code)]
    LL|       |
    LL|      1|fn main() {
-   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-   LL|      1|    // dependent conditions.
+   LL|       |    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|       |    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|       |    // dependent conditions.
    LL|      1|    let is_true = std::env::args().len() == 1;
-   LL|      1|
+   LL|       |
    LL|      1|    let mut countdown = 0;
    LL|      1|    if is_true {
    LL|      1|        countdown = 10;
@@ -54,7 +54,7 @@
    LL|      1|    let mut val = InStruct {
    LL|      1|        in_struct_field: 101, //
    LL|      1|    };
-   LL|      1|
+   LL|       |
    LL|      1|    val.default_trait_func();
    LL|      1|}
 
diff --git a/tests/coverage/issue-83601.cov-map b/tests/coverage/issue-83601.cov-map
index f1023109008..d1d751ff24b 100644
--- a/tests/coverage/issue-83601.cov-map
+++ b/tests/coverage/issue-83601.cov-map
@@ -1,13 +1,30 @@
 Function name: issue_83601::main
-Raw bytes (21): 0x[01, 01, 01, 05, 09, 03, 01, 06, 01, 02, 0f, 05, 03, 09, 01, 0f, 02, 02, 05, 03, 02]
+Raw bytes (76): 0x[01, 01, 01, 05, 09, 0e, 01, 06, 01, 00, 0a, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 05, 01, 09, 00, 0c, 05, 00, 0f, 00, 15, 05, 01, 05, 00, 0f, 02, 01, 05, 00, 0d, 02, 00, 0e, 00, 14, 02, 01, 05, 00, 0d, 02, 00, 0e, 00, 14, 02, 01, 05, 00, 0d, 02, 00, 0e, 00, 14, 02, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/issue-83601.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 6, 1) to (start + 2, 15)
-- Code(Counter(1)) at (prev + 3, 9) to (start + 1, 15)
-- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 3, 2)
+Number of file 0 mappings: 14
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 12)
+- Code(Counter(1)) at (prev + 0, 15) to (start + 0, 21)
+- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 13)
+    = (c1 - c2)
+- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 20)
+    = (c1 - c2)
+- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 13)
+    = (c1 - c2)
+- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 20)
+    = (c1 - c2)
+- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 13)
+    = (c1 - c2)
+- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 20)
+    = (c1 - c2)
+- Code(Expression(0, Sub)) at (prev + 1, 1) to (start + 0, 2)
     = (c1 - c2)
 Highest counter ID seen: c1
 
diff --git a/tests/coverage/issue-84561.cov-map b/tests/coverage/issue-84561.cov-map
index 47e2922a805..2b643ea599e 100644
--- a/tests/coverage/issue-84561.cov-map
+++ b/tests/coverage/issue-84561.cov-map
@@ -1,67 +1,81 @@
 Function name: <issue_84561::Foo as core::fmt::Debug>::fmt
-Raw bytes (27): 0x[01, 01, 01, 01, 05, 04, 01, 8a, 01, 05, 01, 24, 05, 01, 25, 00, 26, 02, 01, 09, 00, 0f, 01, 01, 05, 00, 06]
+Raw bytes (42): 0x[01, 01, 01, 01, 05, 07, 01, 8a, 01, 05, 00, 43, 01, 01, 09, 00, 0f, 01, 00, 10, 00, 11, 01, 00, 13, 00, 24, 05, 00, 25, 00, 26, 02, 01, 09, 00, 0f, 01, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/issue-84561.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 138, 5) to (start + 1, 36)
-- Code(Counter(1)) at (prev + 1, 37) to (start + 0, 38)
+Number of file 0 mappings: 7
+- Code(Counter(0)) at (prev + 138, 5) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 36)
+- Code(Counter(1)) at (prev + 0, 37) to (start + 0, 38)
 - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: c1
 
 Function name: issue_84561::main
-Raw bytes (10): 0x[01, 01, 00, 01, 01, b4, 01, 01, 04, 02]
+Raw bytes (30): 0x[01, 01, 00, 05, 01, b4, 01, 01, 00, 0a, 01, 01, 05, 00, 0a, 01, 01, 05, 00, 0a, 01, 01, 05, 00, 0a, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/issue-84561.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 180, 1) to (start + 4, 2)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 180, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: issue_84561::test1
-Raw bytes (50): 0x[01, 01, 00, 09, 01, 9a, 01, 01, 01, 0b, 05, 01, 0c, 00, 1e, 01, 01, 05, 00, 0b, 09, 00, 0c, 00, 1e, 01, 01, 0d, 01, 0b, 0d, 01, 0c, 00, 1e, 01, 01, 05, 03, 0b, 11, 03, 0c, 00, 1e, 01, 01, 01, 00, 02]
+Raw bytes (65): 0x[01, 01, 00, 0c, 01, 9a, 01, 01, 00, 0b, 01, 01, 05, 00, 0b, 05, 00, 0c, 00, 1e, 01, 01, 05, 00, 0b, 09, 00, 0c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 05, 00, 0b, 0d, 00, 0c, 00, 1e, 01, 01, 05, 02, 06, 01, 03, 05, 00, 0b, 11, 00, 0c, 00, 1e, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/issue-84561.rs
 Number of expressions: 0
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 154, 1) to (start + 1, 11)
-- Code(Counter(1)) at (prev + 1, 12) to (start + 0, 30)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 154, 1) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 11)
+- Code(Counter(1)) at (prev + 0, 12) to (start + 0, 30)
 - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 11)
 - Code(Counter(2)) at (prev + 0, 12) to (start + 0, 30)
-- Code(Counter(0)) at (prev + 1, 13) to (start + 1, 11)
-- Code(Counter(3)) at (prev + 1, 12) to (start + 0, 30)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 3, 11)
-- Code(Counter(4)) at (prev + 3, 12) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 11)
+- Code(Counter(3)) at (prev + 0, 12) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 2, 6)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 11)
+- Code(Counter(4)) at (prev + 0, 12) to (start + 0, 30)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c4
 
 Function name: issue_84561::test2
-Raw bytes (20): 0x[01, 01, 00, 03, 01, b0, 01, 01, 01, 10, 05, 01, 11, 00, 23, 01, 01, 01, 00, 02]
+Raw bytes (25): 0x[01, 01, 00, 04, 01, b0, 01, 01, 00, 0b, 01, 01, 05, 00, 10, 05, 00, 11, 00, 23, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/issue-84561.rs
 Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 176, 1) to (start + 1, 16)
-- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 35)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 176, 1) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 0, 17) to (start + 0, 35)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: issue_84561::test2::call_print
-Raw bytes (10): 0x[01, 01, 00, 01, 01, a7, 01, 09, 02, 0a]
+Raw bytes (25): 0x[01, 01, 00, 04, 01, a7, 01, 09, 00, 1f, 01, 01, 0d, 00, 13, 01, 00, 14, 00, 18, 01, 01, 09, 00, 0a]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/issue-84561.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 167, 9) to (start + 2, 10)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 167, 9) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
 Highest counter ID seen: c0
 
 Function name: issue_84561::test3
-Raw bytes (279): 0x[01, 01, 0a, 0d, 11, 0d, 15, 0d, 19, 1d, 21, 29, 2d, 25, 29, 25, 29, 25, 29, 27, 31, 29, 2d, 33, 01, 08, 01, 03, 0f, 05, 04, 09, 01, 0f, 09, 02, 05, 04, 0f, 09, 05, 05, 00, 0f, 09, 01, 05, 00, 0f, 09, 01, 09, 01, 0f, 0d, 02, 05, 00, 0f, 0d, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 0d, 01, 05, 03, 0f, 00, 03, 20, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 0d, 01, 05, 00, 0f, 00, 05, 09, 03, 10, 00, 05, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 0d, 04, 09, 02, 0f, 0d, 06, 05, 00, 0f, 0d, 04, 05, 00, 0f, 0d, 04, 09, 01, 0f, 0d, 05, 08, 00, 0f, 11, 01, 09, 00, 13, 02, 05, 09, 00, 13, 0d, 05, 08, 00, 0f, 15, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 06, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 0d, 03, 05, 00, 0f, 0d, 01, 0c, 00, 13, 19, 01, 0d, 00, 13, 0a, 02, 0d, 00, 13, 1d, 04, 05, 02, 13, 21, 03, 0d, 00, 13, 0e, 02, 0d, 00, 13, 27, 03, 05, 00, 0f, 25, 01, 0c, 00, 13, 29, 01, 0d, 00, 17, 29, 04, 0d, 00, 13, 1e, 02, 0d, 00, 17, 1e, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 1e, 02, 15, 00, 1b, 2d, 04, 0d, 00, 13, 22, 03, 09, 00, 19, 31, 02, 05, 00, 0f, 31, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02]
+Raw bytes (409): 0x[01, 01, 0a, 0d, 11, 0d, 15, 0d, 19, 1d, 21, 29, 2d, 25, 29, 25, 29, 25, 29, 27, 31, 29, 2d, 4d, 01, 08, 01, 00, 0b, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 05, 01, 09, 00, 0c, 05, 00, 0f, 00, 15, 05, 01, 05, 00, 0f, 09, 01, 05, 00, 0d, 09, 00, 0e, 00, 14, 09, 01, 05, 00, 0d, 09, 00, 0e, 00, 14, 09, 01, 05, 00, 0d, 09, 00, 0e, 00, 14, 09, 02, 05, 00, 0f, 09, 01, 05, 00, 0f, 09, 01, 05, 00, 0f, 09, 01, 09, 00, 0c, 09, 00, 0f, 00, 15, 09, 01, 05, 00, 0f, 0d, 01, 05, 00, 0f, 0d, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 0d, 01, 05, 00, 0d, 0d, 00, 0e, 00, 14, 0d, 01, 05, 00, 0d, 0d, 00, 0e, 00, 14, 0d, 02, 05, 00, 0f, 00, 00, 20, 00, 24, 00, 00, 29, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 0d, 01, 05, 00, 0f, 00, 05, 09, 00, 0d, 00, 03, 09, 00, 10, 00, 02, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 0d, 04, 09, 00, 10, 0d, 00, 13, 00, 2e, 0d, 02, 05, 00, 0f, 0d, 04, 05, 00, 0f, 0d, 04, 05, 00, 0f, 0d, 04, 09, 00, 0c, 0d, 00, 0f, 00, 15, 0d, 01, 05, 00, 0f, 0d, 04, 08, 00, 0f, 11, 01, 09, 00, 13, 02, 05, 09, 00, 13, 0d, 05, 08, 00, 0f, 15, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 06, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 0d, 03, 05, 00, 0f, 0d, 01, 0c, 00, 13, 19, 01, 0d, 00, 13, 0a, 02, 0d, 00, 13, 1d, 04, 05, 00, 0f, 1d, 02, 0c, 00, 13, 21, 01, 0d, 00, 13, 0e, 02, 0d, 00, 13, 27, 03, 05, 00, 0f, 25, 01, 0c, 00, 13, 29, 01, 0d, 00, 17, 29, 04, 0d, 00, 13, 1e, 02, 0d, 00, 17, 1e, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 1e, 02, 15, 00, 1b, 2d, 04, 0d, 00, 13, 22, 03, 09, 00, 19, 31, 02, 05, 00, 0f, 31, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/issue-84561.rs
 Number of expressions: 10
 - expression 0 operands: lhs = Counter(3), rhs = Counter(4)
 - expression 1 operands: lhs = Counter(3), rhs = Counter(5)
@@ -73,29 +87,54 @@ Number of expressions: 10
 - expression 7 operands: lhs = Counter(9), rhs = Counter(10)
 - expression 8 operands: lhs = Expression(9, Add), rhs = Counter(12)
 - expression 9 operands: lhs = Counter(10), rhs = Counter(11)
-Number of file 0 mappings: 51
-- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 15)
-- Code(Counter(1)) at (prev + 4, 9) to (start + 1, 15)
-- Code(Counter(2)) at (prev + 2, 5) to (start + 4, 15)
-- Code(Counter(2)) at (prev + 5, 5) to (start + 0, 15)
+Number of file 0 mappings: 77
+- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 12)
+- Code(Counter(1)) at (prev + 0, 15) to (start + 0, 21)
+- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(2)) at (prev + 0, 14) to (start + 0, 20)
+- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(2)) at (prev + 0, 14) to (start + 0, 20)
+- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(2)) at (prev + 0, 14) to (start + 0, 20)
+- Code(Counter(2)) at (prev + 2, 5) to (start + 0, 15)
 - Code(Counter(2)) at (prev + 1, 5) to (start + 0, 15)
-- Code(Counter(2)) at (prev + 1, 9) to (start + 1, 15)
-- Code(Counter(3)) at (prev + 2, 5) to (start + 0, 15)
+- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 12)
+- Code(Counter(2)) at (prev + 0, 15) to (start + 0, 21)
+- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15)
 - Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 48)
-- Code(Counter(3)) at (prev + 1, 5) to (start + 3, 15)
-- Code(Zero) at (prev + 3, 32) to (start + 0, 48)
+- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(3)) at (prev + 0, 14) to (start + 0, 20)
+- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(3)) at (prev + 0, 14) to (start + 0, 20)
+- Code(Counter(3)) at (prev + 2, 5) to (start + 0, 15)
+- Code(Zero) at (prev + 0, 32) to (start + 0, 36)
+- Code(Zero) at (prev + 0, 41) to (start + 0, 48)
 - Code(Zero) at (prev + 0, 51) to (start + 0, 65)
 - Code(Zero) at (prev + 0, 75) to (start + 0, 90)
 - Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15)
-- Code(Zero) at (prev + 5, 9) to (start + 3, 16)
-- Code(Zero) at (prev + 5, 13) to (start + 0, 27)
+- Code(Zero) at (prev + 5, 9) to (start + 0, 13)
+- Code(Zero) at (prev + 3, 9) to (start + 0, 16)
+- Code(Zero) at (prev + 2, 13) to (start + 0, 27)
 - Code(Zero) at (prev + 2, 13) to (start + 0, 28)
-- Code(Counter(3)) at (prev + 4, 9) to (start + 2, 15)
-- Code(Counter(3)) at (prev + 6, 5) to (start + 0, 15)
+- Code(Counter(3)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(3)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(3)) at (prev + 2, 5) to (start + 0, 15)
 - Code(Counter(3)) at (prev + 4, 5) to (start + 0, 15)
-- Code(Counter(3)) at (prev + 4, 9) to (start + 1, 15)
-- Code(Counter(3)) at (prev + 5, 8) to (start + 0, 15)
+- Code(Counter(3)) at (prev + 4, 5) to (start + 0, 15)
+- Code(Counter(3)) at (prev + 4, 9) to (start + 0, 12)
+- Code(Counter(3)) at (prev + 0, 15) to (start + 0, 21)
+- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(3)) at (prev + 4, 8) to (start + 0, 15)
 - Code(Counter(4)) at (prev + 1, 9) to (start + 0, 19)
 - Code(Expression(0, Sub)) at (prev + 5, 9) to (start + 0, 19)
     = (c3 - c4)
@@ -110,8 +149,9 @@ Number of file 0 mappings: 51
 - Code(Counter(6)) at (prev + 1, 13) to (start + 0, 19)
 - Code(Expression(2, Sub)) at (prev + 2, 13) to (start + 0, 19)
     = (c3 - c6)
-- Code(Counter(7)) at (prev + 4, 5) to (start + 2, 19)
-- Code(Counter(8)) at (prev + 3, 13) to (start + 0, 19)
+- Code(Counter(7)) at (prev + 4, 5) to (start + 0, 15)
+- Code(Counter(7)) at (prev + 2, 12) to (start + 0, 19)
+- Code(Counter(8)) at (prev + 1, 13) to (start + 0, 19)
 - Code(Expression(3, Sub)) at (prev + 2, 13) to (start + 0, 19)
     = (c7 - c8)
 - Code(Expression(9, Add)) at (prev + 3, 5) to (start + 0, 15)
diff --git a/tests/coverage/issue-84561.coverage b/tests/coverage/issue-84561.coverage
index a55f42a696e..781f1e97f5a 100644
--- a/tests/coverage/issue-84561.coverage
+++ b/tests/coverage/issue-84561.coverage
@@ -14,7 +14,7 @@
    LL|      1|    println!("{:?}", Foo(1));
    LL|      1|    println!("{:?}", bar);
    LL|      1|    println!("{:?}", baz);
-   LL|      1|
+   LL|       |
    LL|      1|    assert_eq!(Foo(1), Foo(1));
    LL|      1|    assert_ne!(Foo(0), Foo(1));
    LL|      1|    assert_eq!(Foo(2), Foo(2));
@@ -25,17 +25,17 @@
                                              ^0
    LL|      1|    println!("{:?}", bar);
    LL|      1|    println!("{:?}", Foo(1));
-   LL|      1|
+   LL|       |
    LL|      1|    assert_ne!(Foo(0), Foo(5), "{}", if is_true { "true message" } else { "false message" });
-                                             ^0                 ^0                      ^0
+                                             ^0       ^0        ^0                      ^0
    LL|      1|    assert_ne!(
    LL|       |        Foo(0)
    LL|       |        ,
    LL|       |        Foo(5)
    LL|       |        ,
    LL|      0|        "{}"
-   LL|      0|        ,
-   LL|      0|        if
+   LL|       |        ,
+   LL|       |        if
    LL|      0|        is_true
    LL|       |        {
    LL|      0|            "true message"
@@ -45,7 +45,7 @@
    LL|       |    );
    LL|       |
    LL|      1|    let is_true = std::env::args().len() == 1;
-   LL|      1|
+   LL|       |
    LL|      1|    assert_eq!(
    LL|       |        Foo(1),
    LL|       |        Foo(1)
@@ -96,7 +96,7 @@
    LL|       |        Foo(5)
    LL|       |    );
    LL|      1|    assert_ne!(
-   LL|      1|        Foo(5),
+   LL|       |        Foo(5),
    LL|      1|        if is_true {
    LL|      1|            Foo(0)
    LL|       |        } else {
diff --git a/tests/coverage/issue-85461.cov-map b/tests/coverage/issue-85461.cov-map
index 349bc2cab80..b08d7033693 100644
--- a/tests/coverage/issue-85461.cov-map
+++ b/tests/coverage/issue-85461.cov-map
@@ -1,9 +1,12 @@
 Function name: issue_85461::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 08, 01, 03, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 08, 01, 00, 0a, 01, 01, 05, 00, 11, 01, 01, 05, 00, 11, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/issue-85461.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/issue-93054.cov-map b/tests/coverage/issue-93054.cov-map
index 38cb70a3f97..17f3dafce1d 100644
--- a/tests/coverage/issue-93054.cov-map
+++ b/tests/coverage/issue-93054.cov-map
@@ -1,27 +1,30 @@
 Function name: issue_93054::foo2 (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 00, 1d]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 00, 1c]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/issue-93054.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 21, 1) to (start + 0, 29)
+- Code(Zero) at (prev + 21, 1) to (start + 0, 28)
 Highest counter ID seen: (none)
 
 Function name: issue_93054::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1d, 01, 00, 0d]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 1d, 01, 00, 0a, 01, 00, 0c, 00, 0d]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/issue-93054.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 29, 1) to (start + 0, 13)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 29, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13)
 Highest counter ID seen: c0
 
 Function name: issue_93054::make (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 01, 02, 02]
+Raw bytes (19): 0x[01, 01, 00, 03, 00, 19, 01, 00, 1b, 00, 01, 05, 00, 09, 00, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/issue-93054.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 25, 1) to (start + 2, 2)
+Number of file 0 mappings: 3
+- Code(Zero) at (prev + 25, 1) to (start + 0, 27)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 9)
+- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: (none)
 
diff --git a/tests/coverage/lazy_boolean.cov-map b/tests/coverage/lazy_boolean.cov-map
index 3f7788da1eb..cbbe6a89fb0 100644
--- a/tests/coverage/lazy_boolean.cov-map
+++ b/tests/coverage/lazy_boolean.cov-map
@@ -1,7 +1,7 @@
 Function name: lazy_boolean::main
-Raw bytes (158): 0x[01, 01, 07, 01, 05, 01, 25, 01, 21, 01, 11, 01, 15, 01, 19, 01, 1d, 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, 09, 00, 1d, 00, 22, 01, 01, 09, 00, 11, 01, 00, 14, 00, 19, 0d, 00, 1d, 00, 22, 01, 03, 09, 01, 10, 0e, 02, 05, 03, 06, 11, 03, 05, 00, 06, 01, 03, 09, 00, 10, 15, 01, 05, 03, 06, 12, 05, 05, 03, 06, 01, 05, 08, 00, 10, 16, 00, 11, 02, 06, 19, 02, 05, 00, 06, 01, 02, 08, 00, 0f, 1d, 00, 10, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (198): 0x[01, 01, 07, 01, 05, 01, 25, 01, 21, 01, 11, 01, 15, 01, 19, 01, 1d, 24, 01, 04, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 0a, 00, 0f, 01, 00, 11, 00, 16, 01, 00, 18, 00, 1d, 01, 00, 21, 00, 2a, 01, 01, 08, 00, 0f, 05, 00, 10, 04, 06, 05, 01, 09, 00, 0e, 02, 03, 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, 09, 00, 1d, 00, 22, 01, 01, 09, 00, 11, 01, 00, 14, 00, 19, 0d, 00, 1d, 00, 22, 01, 03, 09, 01, 10, 0e, 02, 05, 03, 06, 11, 03, 05, 00, 06, 01, 03, 09, 00, 10, 15, 01, 05, 03, 06, 12, 05, 05, 03, 06, 01, 05, 08, 00, 10, 16, 00, 11, 02, 06, 19, 02, 05, 00, 06, 01, 02, 08, 00, 0f, 1d, 00, 10, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/lazy_boolean.rs
 Number of expressions: 7
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(9)
@@ -10,10 +10,18 @@ Number of expressions: 7
 - expression 4 operands: lhs = Counter(0), rhs = Counter(5)
 - expression 5 operands: lhs = Counter(0), rhs = Counter(6)
 - expression 6 operands: lhs = Counter(0), rhs = Counter(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, 5) to (start + 0, 6)
+Number of file 0 mappings: 36
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 2, 10) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 0, 33) to (start + 0, 42)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 15)
+- Code(Counter(1)) at (prev + 0, 16) to (start + 4, 6)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 14)
+- Code(Expression(0, Sub)) at (prev + 3, 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)
diff --git a/tests/coverage/lazy_boolean.coverage b/tests/coverage/lazy_boolean.coverage
index 828ba2a5811..0a30038e02f 100644
--- a/tests/coverage/lazy_boolean.coverage
+++ b/tests/coverage/lazy_boolean.coverage
@@ -2,11 +2,11 @@
    LL|       |
    LL|       |#[rustfmt::skip]
    LL|      1|fn main() {
-   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-   LL|      1|    // dependent conditions.
+   LL|       |    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|       |    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|       |    // dependent conditions.
    LL|      1|    let is_true = std::env::args().len() == 1;
-   LL|      1|
+   LL|       |
    LL|      1|    let (mut a, mut b, mut c) = (0, 0, 0);
    LL|      1|    if is_true {
    LL|      1|        a = 1;
diff --git a/tests/coverage/let_else_loop.cov-map b/tests/coverage/let_else_loop.cov-map
index 7789114c239..169d4a5c096 100644
--- a/tests/coverage/let_else_loop.cov-map
+++ b/tests/coverage/let_else_loop.cov-map
@@ -1,33 +1,36 @@
 Function name: let_else_loop::_if (unused)
-Raw bytes (19): 0x[01, 01, 00, 03, 00, 16, 01, 01, 0c, 00, 01, 0f, 00, 16, 00, 00, 20, 00, 27]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 16, 01, 00, 13, 00, 01, 08, 00, 0c, 00, 00, 0f, 00, 16, 00, 00, 20, 00, 27]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/let_else_loop.rs
 Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Zero) at (prev + 22, 1) to (start + 1, 12)
-- Code(Zero) at (prev + 1, 15) to (start + 0, 22)
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 22, 1) to (start + 0, 19)
+- Code(Zero) at (prev + 1, 8) to (start + 0, 12)
+- Code(Zero) at (prev + 0, 15) to (start + 0, 22)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 39)
 Highest counter ID seen: (none)
 
 Function name: let_else_loop::_loop_either_way (unused)
-Raw bytes (19): 0x[01, 01, 00, 03, 00, 0f, 01, 01, 14, 00, 01, 1c, 00, 23, 00, 01, 05, 00, 0c]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 0f, 01, 00, 20, 00, 01, 10, 00, 14, 00, 00, 1c, 00, 23, 00, 01, 05, 00, 0c]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/let_else_loop.rs
 Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Zero) at (prev + 15, 1) to (start + 1, 20)
-- Code(Zero) at (prev + 1, 28) to (start + 0, 35)
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 15, 1) to (start + 0, 32)
+- Code(Zero) at (prev + 1, 16) to (start + 0, 20)
+- Code(Zero) at (prev + 0, 28) to (start + 0, 35)
 - Code(Zero) at (prev + 1, 5) to (start + 0, 12)
 Highest counter ID seen: (none)
 
 Function name: let_else_loop::loopy
-Raw bytes (19): 0x[01, 01, 00, 03, 01, 09, 01, 01, 14, 09, 01, 1c, 00, 23, 05, 01, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 09, 01, 00, 15, 01, 01, 10, 00, 14, 09, 00, 1c, 00, 23, 05, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/let_else_loop.rs
 Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 9, 1) to (start + 1, 20)
-- Code(Counter(2)) at (prev + 1, 28) to (start + 0, 35)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 9, 1) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 20)
+- Code(Counter(2)) at (prev + 0, 28) to (start + 0, 35)
 - Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c2
 
diff --git a/tests/coverage/long_and_wide.cov-map b/tests/coverage/long_and_wide.cov-map
index 032b7fe102e..93466a98eaf 100644
--- a/tests/coverage/long_and_wide.cov-map
+++ b/tests/coverage/long_and_wide.cov-map
@@ -1,36 +1,44 @@
 Function name: long_and_wide::far_function
-Raw bytes (10): 0x[01, 01, 00, 01, 01, 96, 01, 01, 00, 15]
+Raw bytes (15): 0x[01, 01, 00, 02, 01, 96, 01, 01, 00, 12, 01, 00, 14, 00, 15]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/long_and_wide.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 150, 1) to (start + 0, 21)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 150, 1) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 21)
 Highest counter ID seen: c0
 
 Function name: long_and_wide::long_function
-Raw bytes (10): 0x[01, 01, 00, 01, 01, 10, 01, 84, 01, 02]
+Raw bytes (15): 0x[01, 01, 00, 02, 01, 10, 01, 00, 13, 01, 84, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/long_and_wide.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 16, 1) to (start + 132, 2)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 132, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: long_and_wide::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 01, 04, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 07, 01, 00, 0a, 01, 01, 05, 00, 12, 01, 01, 05, 00, 12, 01, 01, 05, 00, 11, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/long_and_wide.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 7, 1) to (start + 4, 2)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: long_and_wide::wide_function
-Raw bytes (10): 0x[01, 01, 00, 01, 01, 0e, 01, 00, 8b, 01]
+Raw bytes (23): 0x[01, 01, 00, 03, 01, 0e, 01, 00, 13, 01, 00, 86, 01, 00, 88, 01, 01, 00, 8a, 01, 00, 8b, 01]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/long_and_wide.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 139)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 0, 134) to (start + 0, 136)
+- Code(Counter(0)) at (prev + 0, 138) to (start + 0, 139)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/long_and_wide.coverage b/tests/coverage/long_and_wide.coverage
index f0898d9f466..d9bacdf9eed 100644
--- a/tests/coverage/long_and_wide.coverage
+++ b/tests/coverage/long_and_wide.coverage
@@ -14,137 +14,137 @@
    LL|      1|fn wide_function() { /*                                                                                                           */ (); }
    LL|       |
    LL|      1|fn long_function() {
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
-   LL|      1|    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
+   LL|       |    //
    LL|      1|}
    LL|       |
    LL|      1|fn far_function() {}
diff --git a/tests/coverage/loop-break.cov-map b/tests/coverage/loop-break.cov-map
index fccc4d64395..3981623550d 100644
--- a/tests/coverage/loop-break.cov-map
+++ b/tests/coverage/loop-break.cov-map
@@ -1,11 +1,11 @@
 Function name: loop_break::main
-Raw bytes (31): 0x[01, 01, 01, 05, 01, 05, 01, 03, 01, 00, 0b, 05, 02, 0c, 00, 21, 01, 01, 0d, 00, 12, 02, 01, 09, 00, 0a, 01, 02, 01, 00, 02]
+Raw bytes (31): 0x[01, 01, 01, 05, 01, 05, 01, 03, 01, 00, 0a, 05, 02, 0c, 00, 21, 01, 01, 0d, 00, 12, 02, 01, 09, 00, 0a, 01, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/loop-break.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10)
 - Code(Counter(1)) at (prev + 2, 12) to (start + 0, 33)
 - Code(Counter(0)) at (prev + 1, 13) to (start + 0, 18)
 - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10)
diff --git a/tests/coverage/loop_break_value.cov-map b/tests/coverage/loop_break_value.cov-map
index e48d078f672..cf355eceb2c 100644
--- a/tests/coverage/loop_break_value.cov-map
+++ b/tests/coverage/loop_break_value.cov-map
@@ -1,9 +1,12 @@
 Function name: loop_break_value::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 04, 01, 0a, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 04, 01, 00, 0a, 01, 01, 09, 00, 0f, 01, 02, 0d, 05, 0a, 01, 07, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/loop_break_value.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 4, 1) to (start + 10, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 5, 10)
+- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/loop_break_value.coverage b/tests/coverage/loop_break_value.coverage
index 7d453398759..5e80168b958 100644
--- a/tests/coverage/loop_break_value.coverage
+++ b/tests/coverage/loop_break_value.coverage
@@ -3,13 +3,13 @@
    LL|       |#[rustfmt::skip]
    LL|      1|fn main() {
    LL|      1|    let result
-   LL|      1|        =
+   LL|       |        =
    LL|      1|            loop
    LL|      1|        {
    LL|      1|            break
    LL|      1|            10
    LL|      1|            ;
    LL|      1|        }
-   LL|      1|    ;
+   LL|       |    ;
    LL|      1|}
 
diff --git a/tests/coverage/loops_branches.cov-map b/tests/coverage/loops_branches.cov-map
index 2157cd6ee3f..78fdaa53f46 100644
--- a/tests/coverage/loops_branches.cov-map
+++ b/tests/coverage/loops_branches.cov-map
@@ -1,19 +1,22 @@
 Function name: <loops_branches::DebugTest as core::fmt::Debug>::fmt
-Raw bytes (112): 0x[01, 01, 04, 07, 0b, 01, 0d, 05, 09, 09, 0d, 14, 01, 09, 05, 01, 10, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 1d, 05, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 0d, 03, 0d, 00, 0e, 09, 00, 12, 00, 17, 0d, 01, 10, 00, 14, 0d, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 0d, 01, 11, 00, 12, 0d, 01, 11, 00, 21, 02, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06]
+Raw bytes (137): 0x[01, 01, 04, 07, 0b, 01, 0d, 05, 09, 09, 0d, 19, 01, 09, 05, 00, 43, 01, 01, 0c, 00, 10, 01, 01, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 13, 01, 00, 14, 00, 15, 01, 00, 17, 00, 1d, 05, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 0d, 03, 0d, 00, 0e, 09, 00, 12, 00, 17, 0d, 01, 10, 00, 14, 0d, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 0d, 01, 11, 00, 12, 0d, 01, 11, 00, 17, 0d, 00, 18, 00, 19, 0d, 00, 1b, 00, 21, 02, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/loops_branches.rs
 Number of expressions: 4
 - expression 0 operands: lhs = Expression(1, Add), rhs = Expression(2, Add)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(3)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 3 operands: lhs = Counter(2), rhs = Counter(3)
-Number of file 0 mappings: 20
-- Code(Counter(0)) at (prev + 9, 5) to (start + 1, 16)
-- Code(Counter(0)) at (prev + 2, 16) to (start + 0, 21)
+Number of file 0 mappings: 25
+- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 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(Counter(0)) at (prev + 1, 13) to (start + 0, 14)
-- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 23) to (start + 0, 29)
 - Code(Counter(1)) at (prev + 0, 30) to (start + 0, 31)
 - Code(Zero) at (prev + 1, 16) to (start + 1, 10)
 - Code(Counter(3)) at (prev + 3, 13) to (start + 0, 14)
@@ -23,7 +26,9 @@ Number of file 0 mappings: 20
 - Code(Zero) at (prev + 1, 27) to (start + 0, 31)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
 - Code(Counter(3)) at (prev + 1, 17) to (start + 0, 18)
-- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 33)
+- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 23)
+- Code(Counter(3)) at (prev + 0, 24) to (start + 0, 25)
+- Code(Counter(3)) at (prev + 0, 27) to (start + 0, 33)
 - Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 35)
     = ((c0 + c3) - (c1 + c2))
 - Code(Zero) at (prev + 1, 20) to (start + 1, 14)
@@ -33,22 +38,25 @@ Number of file 0 mappings: 20
 Highest counter ID seen: c3
 
 Function name: <loops_branches::DisplayTest as core::fmt::Display>::fmt
-Raw bytes (112): 0x[01, 01, 04, 07, 0b, 01, 09, 05, 0d, 05, 09, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 1d, 0d, 00, 1e, 00, 1f, 09, 02, 0d, 00, 0e, 05, 00, 12, 00, 17, 09, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 09, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 09, 01, 11, 00, 12, 09, 01, 11, 00, 21, 02, 00, 22, 00, 23, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06]
+Raw bytes (137): 0x[01, 01, 04, 07, 0b, 01, 09, 05, 0d, 05, 09, 19, 01, 22, 05, 00, 43, 01, 01, 0c, 00, 11, 00, 00, 12, 01, 0a, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 13, 01, 00, 14, 00, 15, 01, 00, 17, 00, 1d, 0d, 00, 1e, 00, 1f, 09, 02, 0d, 00, 0e, 05, 00, 12, 00, 17, 09, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 09, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 09, 01, 11, 00, 12, 09, 01, 11, 00, 17, 09, 00, 18, 00, 19, 09, 00, 1b, 00, 21, 02, 00, 22, 00, 23, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/loops_branches.rs
 Number of expressions: 4
 - expression 0 operands: lhs = Expression(1, Add), rhs = Expression(2, Add)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(3)
 - expression 3 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 20
-- Code(Counter(0)) at (prev + 34, 5) to (start + 1, 17)
-- Code(Zero) at (prev + 1, 18) to (start + 1, 10)
+Number of file 0 mappings: 25
+- Code(Counter(0)) at (prev + 34, 5) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 17)
+- Code(Zero) at (prev + 0, 18) to (start + 1, 10)
 - Code(Counter(0)) 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(Counter(0)) at (prev + 1, 13) to (start + 0, 14)
-- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 23) to (start + 0, 29)
 - Code(Counter(3)) at (prev + 0, 30) to (start + 0, 31)
 - Code(Counter(2)) at (prev + 2, 13) to (start + 0, 14)
 - Code(Counter(1)) at (prev + 0, 18) to (start + 0, 23)
@@ -58,7 +66,9 @@ Number of file 0 mappings: 20
 - Code(Zero) at (prev + 1, 27) to (start + 0, 31)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
 - Code(Counter(2)) at (prev + 1, 17) to (start + 0, 18)
-- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 33)
+- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 23)
+- Code(Counter(2)) at (prev + 0, 24) to (start + 0, 25)
+- Code(Counter(2)) at (prev + 0, 27) to (start + 0, 33)
 - Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 35)
     = ((c0 + c2) - (c1 + c3))
 - Code(Expression(3, Sub)) at (prev + 3, 9) to (start + 0, 15)
@@ -67,11 +77,20 @@ Number of file 0 mappings: 20
 Highest counter ID seen: c3
 
 Function name: loops_branches::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 37, 01, 05, 02]
+Raw bytes (54): 0x[01, 01, 00, 0a, 01, 37, 01, 00, 0a, 01, 01, 09, 00, 13, 01, 00, 16, 00, 1f, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 01, 09, 00, 15, 01, 00, 18, 00, 23, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 12, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/loops_branches.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 55, 1) to (start + 5, 2)
+Number of file 0 mappings: 10
+- Code(Counter(0)) at (prev + 55, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 35)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/macro_in_closure.cov-map b/tests/coverage/macro_in_closure.cov-map
index 9614154a366..4544aa50143 100644
--- a/tests/coverage/macro_in_closure.cov-map
+++ b/tests/coverage/macro_in_closure.cov-map
@@ -1,18 +1,21 @@
 Function name: macro_in_closure::NO_BLOCK::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 1c, 00, 2d]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 25, 00, 2c]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/macro_in_closure.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 7, 28) to (start + 0, 45)
+- Code(Counter(0)) at (prev + 7, 37) to (start + 0, 44)
 Highest counter ID seen: c0
 
 Function name: macro_in_closure::WITH_BLOCK::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 09, 1e, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 09, 1e, 00, 1f, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 15, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/macro_in_closure.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 9, 30) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 9, 30) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/macro_name_span.cov-map b/tests/coverage/macro_name_span.cov-map
index bd033faa551..c96cb75846b 100644
--- a/tests/coverage/macro_name_span.cov-map
+++ b/tests/coverage/macro_name_span.cov-map
@@ -1,18 +1,21 @@
 Function name: macro_name_span::affected_function
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 1c, 01, 3e]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 16, 1c, 00, 1d, 01, 01, 09, 00, 3e]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/macro_name_span.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 22, 28) to (start + 1, 62)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 22, 28) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 62)
 Highest counter ID seen: c0
 
 Function name: macro_name_span::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 02, 02]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 0b, 01, 00, 0a, 01, 01, 05, 00, 16, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/macro_name_span.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 11, 1) to (start + 2, 2)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/match_or_pattern.cov-map b/tests/coverage/match_or_pattern.cov-map
index ae77eedfe72..0bb126bc09b 100644
--- a/tests/coverage/match_or_pattern.cov-map
+++ b/tests/coverage/match_or_pattern.cov-map
@@ -1,7 +1,7 @@
 Function name: match_or_pattern::main
-Raw bytes (145): 0x[01, 01, 08, 01, 05, 01, 09, 01, 0d, 01, 11, 01, 15, 01, 19, 01, 1d, 01, 21, 19, 01, 01, 01, 08, 0f, 05, 08, 10, 03, 06, 02, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 06, 03, 1b, 00, 1d, 09, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 0d, 00, 10, 03, 06, 0a, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 0e, 01, 1b, 00, 1d, 11, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 15, 00, 10, 03, 06, 12, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 16, 01, 1b, 00, 1d, 19, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 1d, 00, 10, 03, 06, 1a, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 1e, 01, 1b, 00, 1d, 21, 01, 0e, 00, 10, 01, 02, 01, 00, 02]
+Raw bytes (190): 0x[01, 01, 08, 01, 05, 01, 09, 01, 0d, 01, 11, 01, 15, 01, 19, 01, 1d, 01, 21, 22, 01, 01, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 0e, 01, 00, 10, 00, 12, 01, 00, 15, 00, 16, 01, 01, 09, 00, 0e, 01, 00, 10, 00, 12, 01, 00, 15, 00, 16, 01, 01, 08, 00, 0f, 05, 00, 10, 03, 06, 02, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 06, 03, 1b, 00, 1d, 09, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 0d, 00, 10, 03, 06, 0a, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 0e, 01, 1b, 00, 1d, 11, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 15, 00, 10, 03, 06, 12, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 16, 01, 1b, 00, 1d, 19, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 1d, 00, 10, 03, 06, 1a, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 1e, 01, 1b, 00, 1d, 21, 01, 0e, 00, 10, 01, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/match_or_pattern.rs
 Number of expressions: 8
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(2)
@@ -11,9 +11,18 @@ Number of expressions: 8
 - expression 5 operands: lhs = Counter(0), rhs = Counter(6)
 - expression 6 operands: lhs = Counter(0), rhs = Counter(7)
 - expression 7 operands: lhs = Counter(0), rhs = Counter(8)
-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)
+Number of file 0 mappings: 34
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 0, 21) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 0, 21) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 15)
+- Code(Counter(1)) at (prev + 0, 16) to (start + 3, 6)
 - 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)
diff --git a/tests/coverage/match_or_pattern.coverage b/tests/coverage/match_or_pattern.coverage
index a65c226e567..50540bc5614 100644
--- a/tests/coverage/match_or_pattern.coverage
+++ b/tests/coverage/match_or_pattern.coverage
@@ -1,9 +1,9 @@
    LL|      1|fn main() {
-   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-   LL|      1|    // dependent conditions.
+   LL|       |    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|       |    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|       |    // dependent conditions.
    LL|      1|    let is_true = std::env::args().len() == 1;
-   LL|      1|
+   LL|       |
    LL|      1|    let mut a: u8 = 0;
    LL|      1|    let mut b: u8 = 0;
    LL|      1|    if is_true {
diff --git a/tests/coverage/mcdc/condition-limit.cov-map b/tests/coverage/mcdc/condition-limit.cov-map
index befe8866a59..ffee97cfbc5 100644
--- a/tests/coverage/mcdc/condition-limit.cov-map
+++ b/tests/coverage/mcdc/condition-limit.cov-map
@@ -1,7 +1,7 @@
 Function name: condition_limit::accept_7_conditions
-Raw bytes (147): 0x[01, 01, 08, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 15, 19, 19, 1d, 01, 1d, 12, 01, 06, 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, 09, 06, 07, 06, 00, 00, 0d, 00, 0e, 09, 00, 12, 00, 13, 30, 0d, 0a, 06, 05, 00, 00, 12, 00, 13, 0d, 00, 17, 00, 18, 30, 11, 0e, 05, 04, 00, 00, 17, 00, 18, 11, 00, 1c, 00, 1d, 30, 15, 12, 04, 03, 00, 00, 1c, 00, 1d, 15, 00, 21, 00, 22, 30, 19, 16, 03, 02, 00, 00, 21, 00, 22, 19, 00, 26, 00, 27, 30, 1d, 1a, 02, 00, 00, 00, 26, 00, 27, 1d, 00, 28, 02, 06, 1e, 02, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (192): 0x[01, 01, 08, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 15, 19, 19, 1d, 01, 1d, 1b, 01, 06, 01, 00, 2c, 01, 01, 0a, 00, 0b, 01, 00, 0d, 00, 0e, 01, 00, 10, 00, 11, 01, 00, 13, 00, 14, 01, 00, 16, 00, 17, 01, 00, 19, 00, 1a, 01, 00, 1c, 00, 1d, 01, 00, 21, 00, 29, 01, 01, 08, 00, 09, 28, 08, 07, 00, 08, 00, 27, 30, 05, 02, 01, 07, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 07, 06, 00, 00, 0d, 00, 0e, 09, 00, 12, 00, 13, 30, 0d, 0a, 06, 05, 00, 00, 12, 00, 13, 0d, 00, 17, 00, 18, 30, 11, 0e, 05, 04, 00, 00, 17, 00, 18, 11, 00, 1c, 00, 1d, 30, 15, 12, 04, 03, 00, 00, 1c, 00, 1d, 15, 00, 21, 00, 22, 30, 19, 16, 03, 02, 00, 00, 21, 00, 22, 19, 00, 26, 00, 27, 30, 1d, 1a, 02, 00, 00, 00, 26, 00, 27, 1d, 00, 28, 02, 06, 1e, 02, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/condition-limit.rs
 Number of expressions: 8
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
@@ -11,9 +11,18 @@ Number of expressions: 8
 - expression 5 operands: lhs = Counter(5), rhs = Counter(6)
 - expression 6 operands: lhs = Counter(6), rhs = Counter(7)
 - expression 7 operands: lhs = Counter(0), rhs = Counter(7)
-Number of file 0 mappings: 18
-- Code(Counter(0)) at (prev + 6, 1) to (start + 2, 9)
-- MCDCDecision { bitmap_idx: 8, conditions_num: 7 } at (prev + 2, 8) to (start + 0, 39)
+Number of file 0 mappings: 27
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 44)
+- Code(Counter(0)) at (prev + 1, 10) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 0, 28) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 0, 33) to (start + 0, 41)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 8, conditions_num: 7 } at (prev + 0, 8) to (start + 0, 39)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 7, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
diff --git a/tests/coverage/mcdc/if.cov-map b/tests/coverage/mcdc/if.cov-map
index 1b038f48429..dac1eb4c94b 100644
--- a/tests/coverage/mcdc/if.cov-map
+++ b/tests/coverage/mcdc/if.cov-map
@@ -1,14 +1,15 @@
 Function name: if::mcdc_check_a
-Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 0e, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (67): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 09, 01, 0e, 01, 00, 22, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/if.rs
 Number of expressions: 3
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 14, 1) to (start + 1, 9)
-- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
@@ -23,16 +24,17 @@ Number of file 0 mappings: 8
 Highest counter ID seen: c2
 
 Function name: if::mcdc_check_b
-Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 16, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (67): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 09, 01, 16, 01, 00, 22, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/if.rs
 Number of expressions: 3
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 22, 1) to (start + 1, 9)
-- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
@@ -47,16 +49,17 @@ Number of file 0 mappings: 8
 Highest counter ID seen: c2
 
 Function name: if::mcdc_check_both
-Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 1e, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (67): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 09, 01, 1e, 01, 00, 25, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/if.rs
 Number of expressions: 3
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 9)
-- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 30, 1) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
@@ -71,16 +74,17 @@ Number of file 0 mappings: 8
 Highest counter ID seen: c2
 
 Function name: if::mcdc_check_neither
-Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 06, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (67): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 09, 01, 06, 01, 00, 28, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/if.rs
 Number of expressions: 3
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 9)
-- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 40)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
@@ -95,9 +99,9 @@ Number of file 0 mappings: 8
 Highest counter ID seen: c2
 
 Function name: if::mcdc_check_not_tree_decision
-Raw bytes (85): 0x[01, 01, 07, 01, 05, 01, 17, 05, 09, 05, 09, 17, 0d, 05, 09, 01, 0d, 0a, 01, 30, 01, 03, 0a, 28, 05, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 03, 00, 09, 00, 0a, 02, 00, 0e, 00, 0f, 30, 09, 06, 03, 02, 00, 00, 0e, 00, 0f, 17, 00, 14, 00, 15, 30, 0d, 12, 02, 00, 00, 00, 14, 00, 15, 0d, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (90): 0x[01, 01, 07, 01, 05, 01, 17, 05, 09, 05, 09, 17, 0d, 05, 09, 01, 0d, 0b, 01, 30, 01, 00, 3b, 28, 05, 03, 03, 08, 00, 15, 01, 00, 09, 00, 0a, 30, 05, 02, 01, 02, 03, 00, 09, 00, 0a, 02, 00, 0e, 00, 0f, 30, 09, 06, 03, 02, 00, 00, 0e, 00, 0f, 17, 00, 14, 00, 15, 30, 0d, 12, 02, 00, 00, 00, 14, 00, 15, 0d, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/if.rs
 Number of expressions: 7
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Expression(5, Add)
@@ -106,9 +110,10 @@ Number of expressions: 7
 - expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3)
 - expression 5 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 6 operands: lhs = Counter(0), rhs = Counter(3)
-Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 48, 1) to (start + 3, 10)
+Number of file 0 mappings: 11
+- Code(Counter(0)) at (prev + 48, 1) to (start + 0, 59)
 - MCDCDecision { bitmap_idx: 5, conditions_num: 3 } at (prev + 3, 8) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 10)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 3 } at (prev + 0, 9) to (start + 0, 10)
     true  = c1
     false = (c0 - c1)
@@ -129,9 +134,9 @@ Number of file 0 mappings: 10
 Highest counter ID seen: c3
 
 Function name: if::mcdc_check_tree_decision
-Raw bytes (87): 0x[01, 01, 08, 01, 05, 05, 09, 05, 09, 05, 1f, 09, 0d, 09, 0d, 01, 1f, 09, 0d, 0a, 01, 26, 01, 03, 09, 28, 04, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0e, 00, 0f, 30, 09, 0a, 02, 00, 03, 00, 0e, 00, 0f, 0a, 00, 13, 00, 14, 30, 0d, 0e, 03, 00, 00, 00, 13, 00, 14, 1f, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (92): 0x[01, 01, 08, 01, 05, 05, 09, 05, 09, 05, 1f, 09, 0d, 09, 0d, 01, 1f, 09, 0d, 0b, 01, 26, 01, 00, 37, 01, 03, 08, 00, 09, 28, 04, 03, 00, 08, 00, 15, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0e, 00, 0f, 30, 09, 0a, 02, 00, 03, 00, 0e, 00, 0f, 0a, 00, 13, 00, 14, 30, 0d, 0e, 03, 00, 00, 00, 13, 00, 14, 1f, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/if.rs
 Number of expressions: 8
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
@@ -141,9 +146,10 @@ Number of expressions: 8
 - expression 5 operands: lhs = Counter(2), rhs = Counter(3)
 - expression 6 operands: lhs = Counter(0), rhs = Expression(7, Add)
 - expression 7 operands: lhs = Counter(2), rhs = Counter(3)
-Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 38, 1) to (start + 3, 9)
-- MCDCDecision { bitmap_idx: 4, conditions_num: 3 } at (prev + 3, 8) to (start + 0, 21)
+Number of file 0 mappings: 11
+- Code(Counter(0)) at (prev + 38, 1) to (start + 0, 55)
+- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 4, conditions_num: 3 } at (prev + 0, 8) to (start + 0, 21)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
@@ -164,46 +170,53 @@ Number of file 0 mappings: 10
 Highest counter ID seen: c3
 
 Function name: if::mcdc_nested_if
-Raw bytes (120): 0x[01, 01, 0b, 01, 05, 01, 2b, 05, 09, 05, 09, 2b, 0d, 05, 09, 0d, 11, 2b, 11, 05, 09, 01, 2b, 05, 09, 0e, 01, 3a, 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, 26, 02, 00, 00, 00, 0d, 00, 0e, 2b, 01, 09, 01, 0d, 28, 06, 02, 01, 0c, 00, 12, 30, 0d, 12, 01, 02, 00, 00, 0c, 00, 0d, 0d, 00, 11, 00, 12, 30, 11, 1a, 02, 00, 00, 00, 11, 00, 12, 11, 00, 13, 02, 0a, 1e, 02, 09, 00, 0a, 26, 01, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (139): 0x[01, 01, 0d, 01, 05, 01, 33, 05, 09, 05, 09, 05, 09, 05, 09, 33, 0d, 05, 09, 0d, 11, 33, 11, 05, 09, 01, 33, 05, 09, 11, 01, 3a, 01, 00, 2d, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 00, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 30, 09, 2e, 02, 00, 00, 00, 0d, 00, 0e, 33, 01, 09, 00, 0c, 33, 00, 0d, 00, 15, 33, 01, 0c, 00, 0d, 28, 06, 02, 00, 0c, 00, 12, 30, 0d, 1a, 01, 02, 00, 00, 0c, 00, 0d, 0d, 00, 11, 00, 12, 30, 11, 22, 02, 00, 00, 00, 11, 00, 12, 11, 00, 13, 02, 0a, 26, 02, 09, 00, 0a, 2e, 01, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
-Number of expressions: 11
+- file 0 => $DIR/if.rs
+Number of expressions: 13
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 1 operands: lhs = Counter(0), rhs = Expression(10, Add)
+- expression 1 operands: lhs = Counter(0), rhs = Expression(12, Add)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 3 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 4 operands: lhs = Expression(10, Add), rhs = Counter(3)
+- expression 4 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 5 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 6 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 7 operands: lhs = Expression(10, Add), rhs = Counter(4)
-- expression 8 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 9 operands: lhs = Counter(0), rhs = Expression(10, Add)
+- expression 6 operands: lhs = Expression(12, Add), rhs = Counter(3)
+- expression 7 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 8 operands: lhs = Counter(3), rhs = Counter(4)
+- expression 9 operands: lhs = Expression(12, Add), rhs = Counter(4)
 - expression 10 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 14
-- Code(Counter(0)) at (prev + 58, 1) to (start + 1, 9)
-- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
+- expression 11 operands: lhs = Counter(0), rhs = Expression(12, Add)
+- expression 12 operands: lhs = Counter(1), rhs = Counter(2)
+Number of file 0 mappings: 17
+- Code(Counter(0)) at (prev + 58, 1) to (start + 0, 45)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
 - Code(Expression(0, Sub)) at (prev + 0, 13) to (start + 0, 14)
     = (c0 - c1)
-- MCDCBranch { true: Counter(2), false: Expression(9, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14)
+- MCDCBranch { true: Counter(2), false: Expression(11, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14)
     true  = c2
     false = (c0 - (c1 + c2))
-- Code(Expression(10, Add)) at (prev + 1, 9) to (start + 1, 13)
+- Code(Expression(12, Add)) at (prev + 1, 9) to (start + 0, 12)
     = (c1 + c2)
-- MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 1, 12) to (start + 0, 18)
-- MCDCBranch { true: Counter(3), false: Expression(4, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 12) to (start + 0, 13)
+- Code(Expression(12, Add)) at (prev + 0, 13) to (start + 0, 21)
+    = (c1 + c2)
+- Code(Expression(12, Add)) at (prev + 1, 12) to (start + 0, 13)
+    = (c1 + c2)
+- MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 0, 12) to (start + 0, 18)
+- MCDCBranch { true: Counter(3), false: Expression(6, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 12) to (start + 0, 13)
     true  = c3
     false = ((c1 + c2) - c3)
 - Code(Counter(3)) at (prev + 0, 17) to (start + 0, 18)
-- MCDCBranch { true: Counter(4), false: Expression(6, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 17) to (start + 0, 18)
+- MCDCBranch { true: Counter(4), false: Expression(8, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 17) to (start + 0, 18)
     true  = c4
     false = (c3 - c4)
 - Code(Counter(4)) at (prev + 0, 19) to (start + 2, 10)
-- Code(Expression(7, Sub)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Expression(9, Sub)) at (prev + 2, 9) to (start + 0, 10)
     = ((c1 + c2) - c4)
-- Code(Expression(9, Sub)) at (prev + 1, 12) to (start + 2, 6)
+- Code(Expression(11, Sub)) at (prev + 1, 12) to (start + 2, 6)
     = (c0 - (c1 + c2))
 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
 Highest counter ID seen: c4
diff --git a/tests/coverage/mcdc/if.coverage b/tests/coverage/mcdc/if.coverage
index 51917d06045..fda5525c472 100644
--- a/tests/coverage/mcdc/if.coverage
+++ b/tests/coverage/mcdc/if.coverage
@@ -123,8 +123,8 @@
    LL|      3|}
    LL|       |
    LL|      4|fn mcdc_check_tree_decision(a: bool, b: bool, c: bool) {
-   LL|      4|    // This expression is intentionally written in a way
-   LL|      4|    // where 100% branch coverage indicates 100% mcdc coverage.
+   LL|       |    // This expression is intentionally written in a way
+   LL|       |    // where 100% branch coverage indicates 100% mcdc coverage.
    LL|      4|    if a && (b || c) {
                            ^3   ^2
   ------------------
@@ -160,8 +160,8 @@
    LL|      4|}
    LL|       |
    LL|      4|fn mcdc_check_not_tree_decision(a: bool, b: bool, c: bool) {
-   LL|      4|    // Contradict to `mcdc_check_tree_decision`,
-   LL|      4|    // 100% branch coverage of this expression does not indicate 100% mcdc coverage.
+   LL|       |    // Contradict to `mcdc_check_tree_decision`,
+   LL|       |    // 100% branch coverage of this expression does not indicate 100% mcdc coverage.
    LL|      4|    if (a || b) && c {
                            ^1
   ------------------
diff --git a/tests/coverage/mcdc/inlined_expressions.cov-map b/tests/coverage/mcdc/inlined_expressions.cov-map
index 7d78e572a3b..d05ef368ba4 100644
--- a/tests/coverage/mcdc/inlined_expressions.cov-map
+++ b/tests/coverage/mcdc/inlined_expressions.cov-map
@@ -1,13 +1,14 @@
 Function name: inlined_expressions::inlined_instance
-Raw bytes (50): 0x[01, 01, 02, 01, 05, 05, 09, 06, 01, 07, 01, 01, 06, 28, 03, 02, 01, 05, 00, 0b, 30, 05, 02, 01, 02, 00, 00, 05, 00, 06, 05, 00, 0a, 00, 0b, 30, 09, 06, 02, 00, 00, 00, 0a, 00, 0b, 01, 01, 01, 00, 02]
+Raw bytes (55): 0x[01, 01, 02, 01, 05, 05, 09, 07, 01, 07, 01, 00, 2e, 01, 01, 05, 00, 06, 28, 03, 02, 00, 05, 00, 0b, 30, 05, 02, 01, 02, 00, 00, 05, 00, 06, 05, 00, 0a, 00, 0b, 30, 09, 06, 02, 00, 00, 00, 0a, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/inlined_expressions.rs
 Number of expressions: 2
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 6)
-- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 5) to (start + 0, 11)
+Number of file 0 mappings: 7
+- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
+- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 5) to (start + 0, 11)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 5) to (start + 0, 6)
     true  = c1
     false = (c0 - c1)
diff --git a/tests/coverage/mcdc/nested_if.cov-map b/tests/coverage/mcdc/nested_if.cov-map
index 83d0739aaf5..853cdf2c576 100644
--- a/tests/coverage/mcdc/nested_if.cov-map
+++ b/tests/coverage/mcdc/nested_if.cov-map
@@ -1,7 +1,7 @@
 Function name: nested_if::doubly_nested_if_in_condition
-Raw bytes (170): 0x[01, 01, 0f, 01, 05, 05, 11, 05, 09, 05, 37, 09, 0d, 05, 09, 05, 1f, 09, 15, 15, 19, 05, 2b, 09, 19, 09, 0d, 05, 37, 09, 0d, 01, 11, 14, 01, 0e, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 06, 02, 00, 10, 00, 36, 30, 09, 16, 01, 00, 02, 00, 10, 00, 11, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 36, 16, 00, 18, 00, 19, 28, 03, 02, 00, 18, 00, 1e, 30, 15, 1a, 01, 02, 00, 00, 18, 00, 19, 15, 00, 1d, 00, 1e, 30, 19, 22, 02, 00, 00, 00, 1d, 00, 1e, 19, 00, 21, 00, 25, 26, 00, 2f, 00, 34, 37, 00, 39, 00, 3e, 32, 00, 48, 00, 4c, 11, 00, 4f, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (175): 0x[01, 01, 0f, 01, 05, 05, 11, 05, 09, 05, 37, 09, 0d, 05, 09, 05, 1f, 09, 15, 15, 19, 05, 2b, 09, 19, 09, 0d, 05, 37, 09, 0d, 01, 11, 15, 01, 0e, 01, 00, 45, 01, 01, 08, 00, 09, 28, 09, 02, 00, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 06, 02, 00, 10, 00, 36, 30, 09, 16, 01, 00, 02, 00, 10, 00, 11, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 36, 16, 00, 18, 00, 19, 28, 03, 02, 00, 18, 00, 1e, 30, 15, 1a, 01, 02, 00, 00, 18, 00, 19, 15, 00, 1d, 00, 1e, 30, 19, 22, 02, 00, 00, 00, 1d, 00, 1e, 19, 00, 21, 00, 25, 26, 00, 2f, 00, 34, 37, 00, 39, 00, 3e, 32, 00, 48, 00, 4c, 11, 00, 4f, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/nested_if.rs
 Number of expressions: 15
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(4)
@@ -18,9 +18,10 @@ Number of expressions: 15
 - expression 12 operands: lhs = Counter(1), rhs = Expression(13, Add)
 - expression 13 operands: lhs = Counter(2), rhs = Counter(3)
 - expression 14 operands: lhs = Counter(0), rhs = Counter(4)
-Number of file 0 mappings: 20
-- Code(Counter(0)) at (prev + 14, 1) to (start + 1, 9)
-- MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 78)
+Number of file 0 mappings: 21
+- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 69)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 78)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
@@ -59,9 +60,9 @@ Number of file 0 mappings: 20
 Highest counter ID seen: c6
 
 Function name: nested_if::nested_if_in_condition
-Raw bytes (118): 0x[01, 01, 0a, 01, 05, 05, 11, 05, 09, 05, 09, 05, 23, 09, 0d, 09, 0d, 05, 23, 09, 0d, 01, 11, 0e, 01, 06, 01, 01, 09, 28, 06, 02, 01, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 1e, 02, 00, 00, 00, 15, 00, 16, 23, 00, 19, 00, 1d, 1e, 00, 27, 00, 2c, 11, 00, 2f, 02, 06, 26, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (123): 0x[01, 01, 0a, 01, 05, 05, 11, 05, 09, 05, 09, 05, 23, 09, 0d, 09, 0d, 05, 23, 09, 0d, 01, 11, 0f, 01, 06, 01, 00, 35, 01, 01, 08, 00, 09, 28, 06, 02, 00, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 1e, 02, 00, 00, 00, 15, 00, 16, 23, 00, 19, 00, 1d, 1e, 00, 27, 00, 2c, 11, 00, 2f, 02, 06, 26, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/nested_if.rs
 Number of expressions: 10
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(4)
@@ -73,9 +74,10 @@ Number of expressions: 10
 - expression 7 operands: lhs = Counter(1), rhs = Expression(8, Add)
 - expression 8 operands: lhs = Counter(2), rhs = Counter(3)
 - expression 9 operands: lhs = Counter(0), rhs = Counter(4)
-Number of file 0 mappings: 14
-- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 9)
-- MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 46)
+Number of file 0 mappings: 15
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 53)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 46)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
@@ -103,9 +105,9 @@ Number of file 0 mappings: 14
 Highest counter ID seen: c4
 
 Function name: nested_if::nested_in_then_block_in_condition
-Raw bytes (170): 0x[01, 01, 0f, 01, 05, 05, 19, 05, 09, 05, 09, 05, 37, 09, 0d, 09, 0d, 37, 11, 09, 0d, 11, 15, 37, 15, 09, 0d, 05, 37, 09, 0d, 01, 19, 14, 01, 21, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 19, 06, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 16, 37, 00, 1c, 00, 1d, 28, 06, 02, 00, 1c, 00, 22, 30, 11, 1e, 01, 02, 00, 00, 1c, 00, 1d, 11, 00, 21, 00, 22, 30, 15, 26, 02, 00, 00, 00, 21, 00, 22, 15, 00, 25, 00, 29, 2a, 00, 33, 00, 38, 32, 00, 44, 00, 49, 19, 00, 4c, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (175): 0x[01, 01, 0f, 01, 05, 05, 19, 05, 09, 05, 09, 05, 37, 09, 0d, 09, 0d, 37, 11, 09, 0d, 11, 15, 37, 15, 09, 0d, 05, 37, 09, 0d, 01, 19, 15, 01, 21, 01, 00, 52, 01, 01, 08, 00, 09, 28, 09, 02, 00, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 19, 06, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 16, 37, 00, 1c, 00, 1d, 28, 06, 02, 00, 1c, 00, 22, 30, 11, 1e, 01, 02, 00, 00, 1c, 00, 1d, 11, 00, 21, 00, 22, 30, 15, 26, 02, 00, 00, 00, 21, 00, 22, 15, 00, 25, 00, 29, 2a, 00, 33, 00, 38, 32, 00, 44, 00, 49, 19, 00, 4c, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/nested_if.rs
 Number of expressions: 15
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(6)
@@ -122,9 +124,10 @@ Number of expressions: 15
 - expression 12 operands: lhs = Counter(1), rhs = Expression(13, Add)
 - expression 13 operands: lhs = Counter(2), rhs = Counter(3)
 - expression 14 operands: lhs = Counter(0), rhs = Counter(6)
-Number of file 0 mappings: 20
-- Code(Counter(0)) at (prev + 33, 1) to (start + 1, 9)
-- MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 75)
+Number of file 0 mappings: 21
+- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 82)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 75)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
@@ -163,18 +166,19 @@ Number of file 0 mappings: 20
 Highest counter ID seen: c6
 
 Function name: nested_if::nested_single_condition_decision
-Raw bytes (83): 0x[01, 01, 05, 01, 05, 05, 0d, 05, 09, 05, 09, 01, 0d, 0b, 01, 16, 01, 04, 09, 28, 03, 02, 04, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 06, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 09, 0e, 00, 10, 00, 11, 09, 00, 14, 00, 19, 0e, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (88): 0x[01, 01, 05, 01, 05, 05, 0d, 05, 09, 05, 09, 01, 0d, 0c, 01, 16, 01, 00, 36, 01, 04, 08, 00, 09, 28, 03, 02, 00, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 06, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 09, 0e, 00, 10, 00, 11, 09, 00, 14, 00, 19, 0e, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/nested_if.rs
 Number of expressions: 5
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(3)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 3 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 4 operands: lhs = Counter(0), rhs = Counter(3)
-Number of file 0 mappings: 11
-- Code(Counter(0)) at (prev + 22, 1) to (start + 4, 9)
-- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 4, 8) to (start + 0, 41)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 54)
+- Code(Counter(0)) at (prev + 4, 8) to (start + 0, 9)
+- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 41)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
diff --git a/tests/coverage/mcdc/nested_if.coverage b/tests/coverage/mcdc/nested_if.coverage
index c3ac30d22bf..8b5179b34fe 100644
--- a/tests/coverage/mcdc/nested_if.coverage
+++ b/tests/coverage/mcdc/nested_if.coverage
@@ -122,9 +122,9 @@
    LL|      4|}
    LL|       |
    LL|      3|fn nested_single_condition_decision(a: bool, b: bool) {
-   LL|      3|    // Decision with only 1 decision should not be instrumented by MCDC because
-   LL|      3|    // branch-coverage is equivalent to MCDC coverage in this case, and we don't
-   LL|      3|    // want to waste bitmap space for this.
+   LL|       |    // Decision with only 1 decision should not be instrumented by MCDC because
+   LL|       |    // branch-coverage is equivalent to MCDC coverage in this case, and we don't
+   LL|       |    // want to waste bitmap space for this.
    LL|      3|    if a && if b { false } else { true } {
                              ^2  ^1             ^1
   ------------------
diff --git a/tests/coverage/mcdc/non_control_flow.cov-map b/tests/coverage/mcdc/non_control_flow.cov-map
index 48a103b2c7d..f06bc2ed816 100644
--- a/tests/coverage/mcdc/non_control_flow.cov-map
+++ b/tests/coverage/mcdc/non_control_flow.cov-map
@@ -1,14 +1,14 @@
 Function name: non_control_flow::assign_3
-Raw bytes (79): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 0a, 01, 15, 01, 00, 28, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 04, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 03, 00, 00, 12, 00, 13, 09, 00, 17, 00, 18, 30, 0d, 0e, 03, 00, 00, 00, 17, 00, 18, 01, 01, 05, 01, 02]
+Raw bytes (89): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 0c, 01, 15, 01, 00, 27, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 04, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 03, 00, 00, 12, 00, 13, 09, 00, 17, 00, 18, 30, 0d, 0e, 03, 00, 00, 00, 17, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/non_control_flow.rs
 Number of expressions: 4
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 3 operands: lhs = Counter(2), rhs = Counter(3)
-Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 40)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 39)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
 - MCDCDecision { bitmap_idx: 4, conditions_num: 3 } at (prev + 0, 13) to (start + 0, 24)
@@ -24,21 +24,23 @@ Number of file 0 mappings: 10
 - MCDCBranch { true: Counter(3), false: Expression(3, Sub), condition_id: 3, true_next_id: 0, false_next_id: 0 } at (prev + 0, 23) to (start + 0, 24)
     true  = c3
     false = (c2 - c3)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c3
 
 Function name: non_control_flow::assign_3_bis
-Raw bytes (81): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 0a, 01, 1a, 01, 00, 2c, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 05, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 03, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 03, 00, 02, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 30, 0d, 0e, 02, 00, 00, 00, 17, 00, 18, 01, 01, 05, 01, 02]
+Raw bytes (91): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 0c, 01, 1a, 01, 00, 2b, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 05, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 03, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 03, 00, 02, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 30, 0d, 0e, 02, 00, 00, 00, 17, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/non_control_flow.rs
 Number of expressions: 5
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(2)
 - expression 3 operands: lhs = Counter(0), rhs = Expression(4, Add)
 - expression 4 operands: lhs = Counter(2), rhs = Counter(3)
-Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 26, 1) to (start + 0, 44)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 26, 1) to (start + 0, 43)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
 - MCDCDecision { bitmap_idx: 5, conditions_num: 3 } at (prev + 0, 13) to (start + 0, 24)
@@ -54,18 +56,20 @@ Number of file 0 mappings: 10
 - MCDCBranch { true: Counter(3), false: Expression(3, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 23) to (start + 0, 24)
     true  = c3
     false = (c0 - (c2 + c3))
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c3
 
 Function name: non_control_flow::assign_and
-Raw bytes (60): 0x[01, 01, 02, 01, 05, 05, 09, 08, 01, 0b, 01, 00, 21, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 01, 02]
+Raw bytes (70): 0x[01, 01, 02, 01, 05, 05, 09, 0a, 01, 0b, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/non_control_flow.rs
 Number of expressions: 2
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 33)
+Number of file 0 mappings: 10
+- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 32)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
 - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 13) to (start + 0, 19)
@@ -76,19 +80,21 @@ Number of file 0 mappings: 8
 - MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19)
     true  = c2
     false = (c1 - c2)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c2
 
 Function name: non_control_flow::assign_or
-Raw bytes (62): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 08, 01, 10, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 01, 02]
+Raw bytes (72): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 0a, 01, 10, 01, 00, 1f, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/non_control_flow.rs
 Number of expressions: 3
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 32)
+Number of file 0 mappings: 10
+- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 31)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
 - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 13) to (start + 0, 19)
@@ -100,27 +106,32 @@ Number of file 0 mappings: 8
 - MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19)
     true  = c2
     false = (c0 - (c1 + c2))
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c2
 
 Function name: non_control_flow::foo
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 24, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 24, 01, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/non_control_flow.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 36, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 36, 1) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: non_control_flow::func_call
-Raw bytes (60): 0x[01, 01, 02, 01, 05, 05, 09, 08, 01, 28, 01, 00, 20, 01, 01, 05, 00, 08, 01, 00, 09, 00, 0a, 28, 03, 02, 00, 09, 00, 0f, 30, 05, 02, 01, 02, 00, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 30, 09, 06, 02, 00, 00, 00, 0e, 00, 0f, 01, 01, 01, 00, 02]
+Raw bytes (60): 0x[01, 01, 02, 01, 05, 05, 09, 08, 01, 28, 01, 00, 1f, 01, 01, 05, 00, 08, 01, 00, 09, 00, 0a, 28, 03, 02, 00, 09, 00, 0f, 30, 05, 02, 01, 02, 00, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 30, 09, 06, 02, 00, 00, 00, 0e, 00, 0f, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/non_control_flow.rs
 Number of expressions: 2
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 40, 1) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 40, 1) to (start + 0, 31)
 - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 8)
 - Code(Counter(0)) at (prev + 0, 9) to (start + 0, 10)
 - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 9) to (start + 0, 15)
@@ -135,17 +146,17 @@ Number of file 0 mappings: 8
 Highest counter ID seen: c2
 
 Function name: non_control_flow::right_comb_tree
-Raw bytes (111): 0x[01, 01, 05, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 0e, 01, 1f, 01, 00, 41, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 06, 05, 00, 0d, 00, 2a, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 13, 00, 14, 30, 09, 06, 02, 03, 00, 00, 13, 00, 14, 09, 00, 19, 00, 1a, 30, 0d, 0a, 03, 04, 00, 00, 19, 00, 1a, 0d, 00, 1f, 00, 20, 30, 11, 0e, 04, 05, 00, 00, 1f, 00, 20, 11, 00, 24, 00, 27, 30, 15, 12, 05, 00, 00, 00, 24, 00, 27, 01, 01, 05, 01, 02]
+Raw bytes (121): 0x[01, 01, 05, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 10, 01, 1f, 01, 00, 40, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 06, 05, 00, 0d, 00, 2a, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 13, 00, 14, 30, 09, 06, 02, 03, 00, 00, 13, 00, 14, 09, 00, 19, 00, 1a, 30, 0d, 0a, 03, 04, 00, 00, 19, 00, 1a, 0d, 00, 1f, 00, 20, 30, 11, 0e, 04, 05, 00, 00, 1f, 00, 20, 11, 00, 24, 00, 27, 30, 15, 12, 05, 00, 00, 00, 24, 00, 27, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/non_control_flow.rs
 Number of expressions: 5
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(2), rhs = Counter(3)
 - expression 3 operands: lhs = Counter(3), rhs = Counter(4)
 - expression 4 operands: lhs = Counter(4), rhs = Counter(5)
-Number of file 0 mappings: 14
-- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 65)
+Number of file 0 mappings: 16
+- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 64)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
 - MCDCDecision { bitmap_idx: 6, conditions_num: 5 } at (prev + 0, 13) to (start + 0, 42)
@@ -168,6 +179,8 @@ Number of file 0 mappings: 14
 - MCDCBranch { true: Counter(5), false: Expression(4, Sub), condition_id: 5, true_next_id: 0, false_next_id: 0 } at (prev + 0, 36) to (start + 0, 39)
     true  = c5
     false = (c4 - c5)
-- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c5
 
diff --git a/tests/coverage/nested_loops.cov-map b/tests/coverage/nested_loops.cov-map
index e9e41bd53e7..649c65d8590 100644
--- a/tests/coverage/nested_loops.cov-map
+++ b/tests/coverage/nested_loops.cov-map
@@ -1,40 +1,60 @@
 Function name: nested_loops::main
-Raw bytes (97): 0x[01, 01, 0e, 07, 2f, 05, 11, 01, 0d, 2f, 05, 01, 0d, 27, 05, 01, 09, 33, 27, 05, 15, 01, 09, 2f, 33, 01, 0d, 05, 15, 05, 01, 0d, 01, 01, 01, 02, 1b, 05, 04, 13, 00, 20, 09, 01, 0d, 01, 18, 0d, 02, 12, 00, 17, 11, 01, 10, 00, 16, 02, 01, 11, 00, 16, 0e, 01, 0e, 03, 16, 15, 04, 11, 01, 1b, 16, 02, 15, 00, 21, 1e, 01, 18, 02, 12, 2a, 03, 0d, 00, 0e, 36, 02, 09, 00, 17, 01, 02, 01, 00, 02]
+Raw bytes (164): 0x[01, 01, 14, 07, 47, 05, 11, 01, 0d, 47, 05, 01, 0d, 47, 05, 01, 0d, 47, 05, 01, 0d, 47, 05, 01, 0d, 3f, 05, 01, 09, 4b, 3f, 05, 15, 01, 09, 47, 4b, 01, 0d, 05, 15, 05, 01, 18, 01, 01, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 02, 13, 00, 20, 09, 01, 0d, 00, 12, 09, 00, 15, 00, 18, 09, 01, 0d, 00, 12, 09, 00, 15, 00, 18, 0d, 01, 12, 00, 17, 11, 01, 10, 00, 16, 02, 01, 11, 00, 16, 26, 01, 0d, 00, 0e, 26, 01, 0d, 00, 13, 26, 01, 0d, 00, 13, 26, 01, 10, 00, 16, 15, 01, 11, 00, 18, 15, 01, 14, 00, 1b, 2e, 01, 15, 00, 21, 36, 01, 18, 02, 12, 42, 03, 0d, 00, 0e, 4e, 02, 09, 00, 17, 01, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
-Number of expressions: 14
-- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(11, Add)
+- file 0 => $DIR/nested_loops.rs
+Number of expressions: 20
+- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(17, Add)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(4)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(3)
-- expression 3 operands: lhs = Expression(11, Add), rhs = Counter(1)
+- expression 3 operands: lhs = Expression(17, Add), rhs = Counter(1)
 - expression 4 operands: lhs = Counter(0), rhs = Counter(3)
-- expression 5 operands: lhs = Expression(9, Add), rhs = Counter(1)
-- expression 6 operands: lhs = Counter(0), rhs = Counter(2)
-- expression 7 operands: lhs = Expression(12, Add), rhs = Expression(9, Add)
-- expression 8 operands: lhs = Counter(1), rhs = Counter(5)
-- expression 9 operands: lhs = Counter(0), rhs = Counter(2)
-- expression 10 operands: lhs = Expression(11, Add), rhs = Expression(12, Add)
-- expression 11 operands: lhs = Counter(0), rhs = Counter(3)
-- expression 12 operands: lhs = Counter(1), rhs = Counter(5)
-- expression 13 operands: lhs = Counter(1), rhs = Counter(0)
-Number of file 0 mappings: 13
-- Code(Counter(0)) at (prev + 1, 1) to (start + 2, 27)
-- Code(Counter(1)) at (prev + 4, 19) to (start + 0, 32)
-- Code(Counter(2)) at (prev + 1, 13) to (start + 1, 24)
-- Code(Counter(3)) at (prev + 2, 18) to (start + 0, 23)
+- expression 5 operands: lhs = Expression(17, Add), rhs = Counter(1)
+- expression 6 operands: lhs = Counter(0), rhs = Counter(3)
+- expression 7 operands: lhs = Expression(17, Add), rhs = Counter(1)
+- expression 8 operands: lhs = Counter(0), rhs = Counter(3)
+- expression 9 operands: lhs = Expression(17, Add), rhs = Counter(1)
+- expression 10 operands: lhs = Counter(0), rhs = Counter(3)
+- expression 11 operands: lhs = Expression(15, Add), rhs = Counter(1)
+- expression 12 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 13 operands: lhs = Expression(18, Add), rhs = Expression(15, Add)
+- expression 14 operands: lhs = Counter(1), rhs = Counter(5)
+- expression 15 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 16 operands: lhs = Expression(17, Add), rhs = Expression(18, Add)
+- expression 17 operands: lhs = Counter(0), rhs = Counter(3)
+- expression 18 operands: lhs = Counter(1), rhs = Counter(5)
+- expression 19 operands: lhs = Counter(1), rhs = Counter(0)
+Number of file 0 mappings: 24
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 2, 19) to (start + 0, 32)
+- Code(Counter(2)) at (prev + 1, 13) to (start + 0, 18)
+- Code(Counter(2)) at (prev + 0, 21) to (start + 0, 24)
+- Code(Counter(2)) at (prev + 1, 13) to (start + 0, 18)
+- Code(Counter(2)) at (prev + 0, 21) to (start + 0, 24)
+- Code(Counter(3)) at (prev + 1, 18) to (start + 0, 23)
 - Code(Counter(4)) at (prev + 1, 16) to (start + 0, 22)
 - Code(Expression(0, Sub)) at (prev + 1, 17) to (start + 0, 22)
     = ((c1 + c4) - (c0 + c3))
-- Code(Expression(3, Sub)) at (prev + 1, 14) to (start + 3, 22)
+- Code(Expression(9, Sub)) at (prev + 1, 13) to (start + 0, 14)
     = ((c0 + c3) - c1)
-- Code(Counter(5)) at (prev + 4, 17) to (start + 1, 27)
-- Code(Expression(5, Sub)) at (prev + 2, 21) to (start + 0, 33)
+- Code(Expression(9, Sub)) at (prev + 1, 13) to (start + 0, 19)
+    = ((c0 + c3) - c1)
+- Code(Expression(9, Sub)) at (prev + 1, 13) to (start + 0, 19)
+    = ((c0 + c3) - c1)
+- Code(Expression(9, Sub)) at (prev + 1, 16) to (start + 0, 22)
+    = ((c0 + c3) - c1)
+- Code(Counter(5)) at (prev + 1, 17) to (start + 0, 24)
+- Code(Counter(5)) at (prev + 1, 20) to (start + 0, 27)
+- Code(Expression(11, Sub)) at (prev + 1, 21) to (start + 0, 33)
     = ((c0 + c2) - c1)
-- Code(Expression(7, Sub)) at (prev + 1, 24) to (start + 2, 18)
+- Code(Expression(13, Sub)) at (prev + 1, 24) to (start + 2, 18)
     = ((c1 + c5) - (c0 + c2))
-- Code(Expression(10, Sub)) at (prev + 3, 13) to (start + 0, 14)
+- Code(Expression(16, Sub)) at (prev + 3, 13) to (start + 0, 14)
     = ((c0 + c3) - (c1 + c5))
-- Code(Expression(13, Sub)) at (prev + 2, 9) to (start + 0, 23)
+- Code(Expression(19, Sub)) at (prev + 2, 9) to (start + 0, 23)
     = (c1 - c0)
 - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
 Highest counter ID seen: c5
diff --git a/tests/coverage/no-core.cov-map b/tests/coverage/no-core.cov-map
index 3a1ca4745c7..f2867008127 100644
--- a/tests/coverage/no-core.cov-map
+++ b/tests/coverage/no-core.cov-map
@@ -1,9 +1,10 @@
 Function name: no_core::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 01, 00, 0d]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 0c, 01, 00, 0a, 01, 00, 0c, 00, 0d]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/no-core.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 13)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/no_cov_crate.cov-map b/tests/coverage/no_cov_crate.cov-map
index 244b0099544..ca3c95fe84c 100644
--- a/tests/coverage/no_cov_crate.cov-map
+++ b/tests/coverage/no_cov_crate.cov-map
@@ -1,68 +1,99 @@
 Function name: no_cov_crate::add_coverage_1
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 16, 01, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 22, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/no_cov_crate.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 22, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: no_cov_crate::add_coverage_2
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1a, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 1a, 01, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 22, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/no_cov_crate.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 26, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 26, 1) to (start + 0, 20)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: no_cov_crate::add_coverage_not_called (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 1f, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 1f, 01, 00, 1d, 00, 01, 05, 00, 0d, 00, 00, 0e, 00, 26, 00, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/no_cov_crate.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 31, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 31, 1) to (start + 0, 29)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 13)
+- Code(Zero) at (prev + 0, 14) to (start + 0, 38)
+- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: (none)
 
 Function name: no_cov_crate::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 4f, 01, 0b, 02]
+Raw bytes (74): 0x[01, 01, 00, 0e, 01, 4f, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 05, 00, 1a, 01, 01, 05, 00, 1a, 01, 01, 05, 00, 13, 01, 01, 05, 00, 13, 01, 02, 05, 00, 22, 01, 00, 23, 00, 2a, 01, 01, 05, 00, 16, 01, 00, 17, 00, 1e, 01, 01, 05, 00, 23, 01, 00, 24, 00, 2b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/no_cov_crate.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 79, 1) to (start + 11, 2)
+Number of file 0 mappings: 14
+- Code(Counter(0)) at (prev + 79, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 0, 35) to (start + 0, 42)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 23) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 35)
+- Code(Counter(0)) at (prev + 0, 36) to (start + 0, 43)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: no_cov_crate::nested_fns::outer
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 33, 05, 02, 22, 01, 0c, 05, 00, 06]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 33, 05, 00, 20, 01, 01, 09, 00, 11, 01, 00, 12, 00, 26, 01, 01, 09, 00, 1a, 01, 00, 1b, 00, 22, 01, 0a, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/no_cov_crate.rs
 Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 51, 5) to (start + 2, 34)
-- Code(Counter(0)) at (prev + 12, 5) to (start + 0, 6)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 51, 5) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 38)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 0, 27) to (start + 0, 34)
+- Code(Counter(0)) at (prev + 10, 5) to (start + 0, 6)
 Highest counter ID seen: c0
 
 Function name: no_cov_crate::nested_fns::outer_both_covered
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 41, 05, 02, 16, 01, 0b, 05, 00, 06]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 41, 05, 00, 2d, 01, 01, 09, 00, 11, 01, 00, 12, 00, 26, 01, 01, 09, 00, 0e, 01, 00, 0f, 00, 16, 01, 09, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/no_cov_crate.rs
 Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 65, 5) to (start + 2, 22)
-- Code(Counter(0)) at (prev + 11, 5) to (start + 0, 6)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 65, 5) to (start + 0, 45)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 38)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 6)
 Highest counter ID seen: c0
 
 Function name: no_cov_crate::nested_fns::outer_both_covered::inner
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 45, 09, 01, 17, 05, 01, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 45, 09, 00, 20, 01, 01, 10, 00, 17, 05, 00, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/no_cov_crate.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 69, 9) to (start + 1, 23)
-- Code(Counter(1)) at (prev + 1, 24) to (start + 2, 14)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 69, 9) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 1, 16) to (start + 0, 23)
+- Code(Counter(1)) at (prev + 0, 24) to (start + 2, 14)
 - Code(Expression(0, Sub)) at (prev + 2, 20) to (start + 2, 14)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
diff --git a/tests/coverage/no_cov_crate.coverage b/tests/coverage/no_cov_crate.coverage
index 2a8961e6c93..c6453e60a1a 100644
--- a/tests/coverage/no_cov_crate.coverage
+++ b/tests/coverage/no_cov_crate.coverage
@@ -78,12 +78,12 @@
    LL|       |
    LL|      1|fn main() {
    LL|      1|    let is_true = std::env::args().len() == 1;
-   LL|      1|
+   LL|       |
    LL|      1|    do_not_add_coverage_1();
    LL|      1|    do_not_add_coverage_2();
    LL|      1|    add_coverage_1();
    LL|      1|    add_coverage_2();
-   LL|      1|
+   LL|       |
    LL|      1|    nested_fns::outer_not_covered(is_true);
    LL|      1|    nested_fns::outer(is_true);
    LL|      1|    nested_fns::outer_both_covered(is_true);
diff --git a/tests/coverage/no_spans.cov-map b/tests/coverage/no_spans.cov-map
index 7f43b68fa90..821976b0fab 100644
--- a/tests/coverage/no_spans.cov-map
+++ b/tests/coverage/no_spans.cov-map
@@ -1,18 +1,20 @@
 Function name: no_spans::affected_function
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1a, 1c, 00, 1d]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 15, 1c, 00, 1d]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/no_spans.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 26, 28) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 21, 28) to (start + 0, 29)
 Highest counter ID seen: c0
 
-Function name: no_spans::affected_function::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 0c, 00, 0e]
+Function name: no_spans::main
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 0a, 01, 00, 0a, 01, 01, 05, 00, 1a, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/no_spans.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 27, 12) to (start + 0, 14)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/no_spans.coverage b/tests/coverage/no_spans.coverage
index 19e8c2fe5b6..cf0e47677e9 100644
--- a/tests/coverage/no_spans.coverage
+++ b/tests/coverage/no_spans.coverage
@@ -1,20 +1,15 @@
    LL|       |#![feature(coverage_attribute)]
    LL|       |//@ edition: 2021
    LL|       |
-   LL|       |// If the span extractor can't find any relevant spans for a function, the
-   LL|       |// refinement loop will terminate with nothing in its `prev` slot. If the
-   LL|       |// subsequent code tries to unwrap `prev`, it will panic.
+   LL|       |// Test that coverage instrumentation can gracefully handle functions that end
+   LL|       |// up having no relevant spans, without crashing the compiler or causing
+   LL|       |// `llvm-cov` to fail.
    LL|       |//
-   LL|       |// This scenario became more likely after #118525 started discarding spans that
-   LL|       |// can't be un-expanded back to within the function body.
-   LL|       |//
-   LL|       |// Regression test for "invalid attempt to unwrap a None some_prev", as seen
-   LL|       |// in issues such as #118643 and #118662.
+   LL|       |// This was originally a regression test for issues such as #118643 and #118662.
    LL|       |
-   LL|       |#[coverage(off)]
-   LL|       |fn main() {
-   LL|       |    affected_function()();
-   LL|       |}
+   LL|      1|fn main() {
+   LL|      1|    affected_function()();
+   LL|      1|}
    LL|       |
    LL|       |macro_rules! macro_that_defines_a_function {
    LL|       |    (fn $name:ident () $body:tt) => {
@@ -24,7 +19,7 @@
    LL|       |
    LL|       |macro_that_defines_a_function! {
    LL|      1|    fn affected_function() {
-   LL|      1|        || ()
+   LL|       |        || ()
    LL|       |    }
    LL|       |}
 
diff --git a/tests/coverage/no_spans.rs b/tests/coverage/no_spans.rs
index e5312406f8a..979b4071927 100644
--- a/tests/coverage/no_spans.rs
+++ b/tests/coverage/no_spans.rs
@@ -1,17 +1,12 @@
 #![feature(coverage_attribute)]
 //@ edition: 2021
 
-// If the span extractor can't find any relevant spans for a function, the
-// refinement loop will terminate with nothing in its `prev` slot. If the
-// subsequent code tries to unwrap `prev`, it will panic.
+// Test that coverage instrumentation can gracefully handle functions that end
+// up having no relevant spans, without crashing the compiler or causing
+// `llvm-cov` to fail.
 //
-// This scenario became more likely after #118525 started discarding spans that
-// can't be un-expanded back to within the function body.
-//
-// Regression test for "invalid attempt to unwrap a None some_prev", as seen
-// in issues such as #118643 and #118662.
+// This was originally a regression test for issues such as #118643 and #118662.
 
-#[coverage(off)]
 fn main() {
     affected_function()();
 }
diff --git a/tests/coverage/no_spans_if_not.cov-map b/tests/coverage/no_spans_if_not.cov-map
index 6c389a24317..c8aa5c7527d 100644
--- a/tests/coverage/no_spans_if_not.cov-map
+++ b/tests/coverage/no_spans_if_not.cov-map
@@ -1,20 +1,23 @@
 Function name: no_spans_if_not::affected_function
-Raw bytes (19): 0x[01, 01, 00, 03, 01, 16, 1c, 01, 12, 01, 02, 0d, 00, 0f, 00, 02, 0d, 00, 0f]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 16, 1c, 00, 1d, 01, 01, 0c, 00, 12, 01, 01, 0d, 00, 0f, 00, 02, 0d, 00, 0f]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/no_spans_if_not.rs
 Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 22, 28) to (start + 1, 18)
-- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 15)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 22, 28) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 15)
 - Code(Zero) at (prev + 2, 13) to (start + 0, 15)
 Highest counter ID seen: c0
 
 Function name: no_spans_if_not::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 02, 02]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 0b, 01, 00, 0a, 01, 01, 05, 00, 16, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/no_spans_if_not.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 11, 1) to (start + 2, 2)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/overflow.cov-map b/tests/coverage/overflow.cov-map
index 1178d65de10..18b0503b9e7 100644
--- a/tests/coverage/overflow.cov-map
+++ b/tests/coverage/overflow.cov-map
@@ -1,7 +1,7 @@
 Function name: overflow::main
-Raw bytes (61): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 09, 01, 10, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 03, 0a, 06, 03, 13, 00, 20, 0d, 00, 21, 03, 0a, 0e, 03, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02]
+Raw bytes (96): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 10, 01, 10, 01, 00, 1c, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 01, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 03, 0a, 09, 01, 11, 00, 17, 09, 00, 1a, 00, 28, 06, 02, 13, 00, 20, 0d, 00, 21, 03, 0a, 0d, 01, 11, 00, 17, 0d, 00, 1a, 00, 28, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/overflow.rs
 Number of expressions: 6
 - expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 - expression 1 operands: lhs = Counter(1), rhs = Expression(5, Add)
@@ -9,33 +9,50 @@ Number of expressions: 6
 - expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add)
 - expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3)
 - expression 5 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 16, 1) to (start + 1, 27)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 24)
+Number of file 0 mappings: 16
+- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 24)
 - Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 0, 26)
     = (c1 - c0)
 - Code(Counter(2)) at (prev + 0, 27) to (start + 3, 10)
-- Code(Expression(1, Sub)) at (prev + 3, 19) to (start + 0, 32)
+- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 23)
+- Code(Counter(2)) at (prev + 0, 26) to (start + 0, 40)
+- Code(Expression(1, Sub)) at (prev + 2, 19) to (start + 0, 32)
     = (c1 - (c0 + c2))
 - Code(Counter(3)) at (prev + 0, 33) to (start + 3, 10)
-- Code(Expression(3, Sub)) at (prev + 3, 9) to (start + 0, 10)
+- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 23)
+- Code(Counter(3)) at (prev + 0, 26) to (start + 0, 40)
+- Code(Expression(3, Sub)) at (prev + 2, 9) to (start + 0, 10)
     = (c1 - ((c0 + c2) + c3))
 - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 23)
     = (c1 - c0)
-- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c3
 
 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, 05, 00, 06, 01, 01, 09, 05, 02]
+Raw bytes (76): 0x[01, 01, 01, 01, 05, 0e, 01, 05, 01, 00, 26, 01, 01, 08, 00, 12, 05, 00, 13, 02, 06, 02, 02, 05, 00, 06, 01, 01, 09, 00, 0f, 01, 00, 12, 00, 1e, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 26, 01, 01, 09, 00, 0f, 01, 00, 12, 00, 21, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 2f, 01, 01, 05, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/overflow.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(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)
+Number of file 0 mappings: 14
+- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 38)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 18)
+- Code(Counter(1)) at (prev + 0, 19) to (start + 2, 6)
 - 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)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 38)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 47)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
diff --git a/tests/coverage/panic_unwind.cov-map b/tests/coverage/panic_unwind.cov-map
index 18b13919fe5..ff656d3d8d5 100644
--- a/tests/coverage/panic_unwind.cov-map
+++ b/tests/coverage/panic_unwind.cov-map
@@ -1,7 +1,7 @@
 Function name: panic_unwind::main
-Raw bytes (61): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 09, 01, 0d, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 02, 0a, 06, 02, 13, 00, 20, 0d, 00, 21, 02, 0a, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02]
+Raw bytes (76): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 0c, 01, 0d, 01, 00, 1c, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 01, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 02, 0a, 06, 02, 13, 00, 20, 0d, 00, 21, 02, 0a, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/panic_unwind.rs
 Number of expressions: 6
 - expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 - expression 1 operands: lhs = Counter(1), rhs = Expression(5, Add)
@@ -9,9 +9,11 @@ Number of expressions: 6
 - expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add)
 - expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3)
 - expression 5 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 13, 1) to (start + 1, 27)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 24)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 24)
 - Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 0, 26)
     = (c1 - c0)
 - Code(Counter(2)) at (prev + 0, 27) to (start + 2, 10)
@@ -22,19 +24,25 @@ Number of file 0 mappings: 9
     = (c1 - ((c0 + c2) + c3))
 - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 23)
     = (c1 - c0)
-- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c3
 
 Function name: panic_unwind::might_panic
-Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 04, 01, 01, 14, 05, 02, 09, 01, 0f, 02, 02, 0c, 03, 02]
+Raw bytes (41): 0x[01, 01, 01, 01, 05, 07, 01, 04, 01, 00, 23, 01, 01, 08, 00, 14, 05, 01, 09, 00, 11, 05, 00, 12, 00, 20, 05, 01, 09, 00, 0f, 02, 01, 0c, 02, 06, 02, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/panic_unwind.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 4, 1) to (start + 1, 20)
-- Code(Counter(1)) at (prev + 2, 9) to (start + 1, 15)
-- Code(Expression(0, Sub)) at (prev + 2, 12) to (start + 3, 2)
+Number of file 0 mappings: 7
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 35)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 20)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(1)) at (prev + 0, 18) to (start + 0, 32)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 2, 6)
+    = (c0 - c1)
+- Code(Expression(0, Sub)) at (prev + 3, 1) to (start + 0, 2)
     = (c0 - c1)
 Highest counter ID seen: c1
 
diff --git a/tests/coverage/partial_eq.cov-map b/tests/coverage/partial_eq.cov-map
index 21c8714ac99..0a81be74912 100644
--- a/tests/coverage/partial_eq.cov-map
+++ b/tests/coverage/partial_eq.cov-map
@@ -1,18 +1,29 @@
 Function name: <partial_eq::Version>::new
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 05, 02, 06]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 0c, 05, 00, 41, 01, 01, 09, 00, 25, 01, 00, 10, 00, 15, 01, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/partial_eq.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 12, 5) to (start + 2, 6)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 12, 5) to (start + 0, 65)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: c0
 
 Function name: partial_eq::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 01, 0a, 02]
+Raw bytes (49): 0x[01, 01, 00, 09, 01, 11, 01, 00, 0a, 01, 01, 09, 00, 16, 01, 00, 19, 00, 25, 01, 01, 09, 00, 16, 01, 00, 19, 00, 25, 01, 02, 05, 00, 0d, 01, 01, 09, 00, 1b, 01, 03, 09, 00, 26, 01, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/partial_eq.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 17, 1) to (start + 10, 2)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 38)
+- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/partial_eq.coverage b/tests/coverage/partial_eq.coverage
index dc5b82b3c5f..0662ce2c300 100644
--- a/tests/coverage/partial_eq.coverage
+++ b/tests/coverage/partial_eq.coverage
@@ -17,13 +17,13 @@
    LL|      1|fn main() {
    LL|      1|    let version_3_2_1 = Version::new(3, 2, 1);
    LL|      1|    let version_3_3_0 = Version::new(3, 3, 0);
-   LL|      1|
+   LL|       |
    LL|      1|    println!(
    LL|      1|        "{:?} < {:?} = {}",
-   LL|      1|        version_3_2_1,
-   LL|      1|        version_3_3_0,
+   LL|       |        version_3_2_1,
+   LL|       |        version_3_3_0,
    LL|      1|        version_3_2_1 < version_3_3_0, //
-   LL|      1|    );
+   LL|       |    );
    LL|      1|}
    LL|       |
    LL|       |/*
diff --git a/tests/coverage/simple_loop.cov-map b/tests/coverage/simple_loop.cov-map
index 8e428b267d5..5447ffdb6e7 100644
--- a/tests/coverage/simple_loop.cov-map
+++ b/tests/coverage/simple_loop.cov-map
@@ -1,19 +1,27 @@
 Function name: simple_loop::main
-Raw bytes (43): 0x[01, 01, 02, 01, 05, 09, 01, 07, 01, 04, 01, 09, 10, 05, 0a, 05, 05, 06, 02, 05, 05, 00, 06, 09, 05, 0d, 02, 0e, 01, 04, 0d, 00, 12, 06, 02, 0a, 03, 0a, 01, 06, 01, 00, 02]
+Raw bytes (75): 0x[01, 01, 03, 01, 05, 09, 01, 09, 01, 0d, 01, 04, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 03, 09, 00, 10, 05, 01, 05, 05, 06, 02, 05, 05, 00, 06, 09, 05, 0d, 02, 0e, 01, 04, 0d, 00, 12, 0a, 02, 09, 00, 0a, 0a, 01, 09, 02, 0a, 01, 05, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
-Number of expressions: 2
+- file 0 => $DIR/simple_loop.rs
+Number of expressions: 3
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(2), rhs = Counter(0)
-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)
+- expression 2 operands: lhs = Counter(2), rhs = Counter(0)
+Number of file 0 mappings: 13
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 1, 5) to (start + 5, 6)
 - Code(Expression(0, Sub)) at (prev + 5, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Counter(2)) at (prev + 5, 13) to (start + 2, 14)
 - Code(Counter(0)) at (prev + 4, 13) to (start + 0, 18)
-- Code(Expression(1, Sub)) at (prev + 2, 10) to (start + 3, 10)
+- Code(Expression(2, Sub)) at (prev + 2, 9) to (start + 0, 10)
     = (c2 - c0)
-- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 2)
+- Code(Expression(2, Sub)) at (prev + 1, 9) to (start + 2, 10)
+    = (c2 - c0)
+- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 2)
 Highest counter ID seen: c2
 
diff --git a/tests/coverage/simple_loop.coverage b/tests/coverage/simple_loop.coverage
index 237e509f42e..a75263f633e 100644
--- a/tests/coverage/simple_loop.coverage
+++ b/tests/coverage/simple_loop.coverage
@@ -2,14 +2,14 @@
    LL|       |
    LL|       |#[rustfmt::skip]
    LL|      1|fn main() {
-   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-   LL|      1|    // dependent conditions.
+   LL|       |    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|       |    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|       |    // dependent conditions.
    LL|      1|    let is_true = std::env::args().len() == 1;
-   LL|      1|
+   LL|       |
    LL|      1|    let mut countdown = 0;
-   LL|      1|
-   LL|      1|    if
+   LL|       |
+   LL|       |    if
    LL|      1|        is_true
    LL|      1|    {
    LL|      1|        countdown
diff --git a/tests/coverage/simple_match.cov-map b/tests/coverage/simple_match.cov-map
index 15f114daa7f..cbd6c7ca52f 100644
--- a/tests/coverage/simple_match.cov-map
+++ b/tests/coverage/simple_match.cov-map
@@ -1,16 +1,21 @@
 Function name: simple_match::main
-Raw bytes (64): 0x[01, 01, 05, 01, 05, 09, 01, 09, 01, 09, 13, 01, 0d, 0a, 01, 04, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 05, 00, 06, 09, 05, 09, 00, 0d, 0a, 05, 0d, 00, 16, 0d, 02, 0d, 00, 0e, 0a, 02, 11, 02, 12, 0d, 04, 0d, 07, 0e, 0e, 0a, 0d, 00, 0f, 01, 03, 01, 00, 02]
+Raw bytes (99): 0x[01, 01, 05, 01, 05, 09, 01, 09, 01, 09, 13, 01, 0d, 11, 01, 04, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0f, 05, 00, 10, 02, 06, 02, 02, 05, 00, 06, 09, 05, 09, 00, 0d, 0a, 05, 0d, 00, 16, 0d, 02, 0d, 00, 0e, 0a, 02, 11, 02, 12, 0d, 04, 0d, 07, 0e, 0d, 01, 11, 00, 1e, 0d, 02, 15, 00, 16, 0e, 07, 0d, 00, 0f, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/simple_match.rs
 Number of expressions: 5
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(2), rhs = Counter(0)
 - expression 2 operands: lhs = Counter(2), rhs = Counter(0)
 - expression 3 operands: lhs = Counter(2), rhs = Expression(4, Add)
 - expression 4 operands: lhs = Counter(0), rhs = Counter(3)
-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)
+Number of file 0 mappings: 17
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 15)
+- Code(Counter(1)) at (prev + 0, 16) to (start + 2, 6)
 - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Counter(2)) at (prev + 5, 9) to (start + 0, 13)
@@ -20,7 +25,9 @@ Number of file 0 mappings: 10
 - Code(Expression(2, Sub)) at (prev + 2, 17) to (start + 2, 18)
     = (c2 - c0)
 - Code(Counter(3)) at (prev + 4, 13) to (start + 7, 14)
-- Code(Expression(3, Sub)) at (prev + 10, 13) to (start + 0, 15)
+- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 30)
+- Code(Counter(3)) at (prev + 2, 21) to (start + 0, 22)
+- Code(Expression(3, Sub)) at (prev + 7, 13) to (start + 0, 15)
     = (c2 - (c0 + c3))
 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
 Highest counter ID seen: c3
diff --git a/tests/coverage/simple_match.coverage b/tests/coverage/simple_match.coverage
index e1d5e48a2bf..0ed7e8dc788 100644
--- a/tests/coverage/simple_match.coverage
+++ b/tests/coverage/simple_match.coverage
@@ -2,11 +2,11 @@
    LL|       |
    LL|       |#[rustfmt::skip]
    LL|      1|fn main() {
-   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-   LL|      1|    // dependent conditions.
+   LL|       |    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|       |    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|       |    // dependent conditions.
    LL|      1|    let is_true = std::env::args().len() == 1;
-   LL|      1|
+   LL|       |
    LL|      1|    let mut countdown = 1;
    LL|      1|    if is_true {
    LL|      1|        countdown = 0;
diff --git a/tests/coverage/sort_groups.cov-map b/tests/coverage/sort_groups.cov-map
index 898d68171c5..70cf7cff4b6 100644
--- a/tests/coverage/sort_groups.cov-map
+++ b/tests/coverage/sort_groups.cov-map
@@ -1,79 +1,98 @@
 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, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 11, 01, 00, 1d, 01, 01, 08, 00, 0c, 05, 00, 0d, 02, 06, 05, 01, 09, 00, 11, 02, 01, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/sort_groups.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(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, 5) to (start + 0, 6)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 12)
+- Code(Counter(1)) at (prev + 0, 13) to (start + 2, 6)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Expression(0, Sub)) at (prev + 1, 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, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 11, 01, 00, 1d, 01, 01, 08, 00, 0c, 05, 00, 0d, 02, 06, 05, 01, 09, 00, 11, 02, 01, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/sort_groups.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(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, 5) to (start + 0, 6)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 12)
+- Code(Counter(1)) at (prev + 0, 13) to (start + 2, 6)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Expression(0, Sub)) at (prev + 1, 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, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 11, 01, 00, 1d, 01, 01, 08, 00, 0c, 05, 00, 0d, 02, 06, 05, 01, 09, 00, 11, 02, 01, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/sort_groups.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(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, 5) to (start + 0, 6)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 12)
+- Code(Counter(1)) at (prev + 0, 13) to (start + 2, 6)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Expression(0, Sub)) at (prev + 1, 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, 05, 00, 06, 01, 01, 01, 00, 02]
+Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 11, 01, 00, 1d, 01, 01, 08, 00, 0c, 05, 00, 0d, 02, 06, 05, 01, 09, 00, 11, 02, 01, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/sort_groups.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(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, 5) to (start + 0, 6)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 12)
+- Code(Counter(1)) at (prev + 0, 13) to (start + 2, 6)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Expression(0, Sub)) at (prev + 1, 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, 1c, 05, 04, 24, 02, 06, 02, 02, 05, 00, 06, 01, 01, 05, 02, 02]
+Raw bytes (76): 0x[01, 01, 01, 01, 05, 0e, 01, 06, 01, 00, 0a, 01, 01, 09, 00, 0d, 01, 00, 10, 00, 2a, 01, 01, 05, 00, 15, 01, 00, 16, 00, 1a, 01, 01, 05, 00, 1f, 01, 00, 20, 00, 25, 01, 01, 08, 00, 1c, 05, 00, 24, 02, 06, 02, 02, 05, 00, 06, 01, 01, 05, 00, 16, 01, 00, 17, 00, 1b, 01, 01, 05, 00, 0d, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/sort_groups.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 6, 1) to (start + 4, 28)
-- Code(Counter(1)) at (prev + 4, 36) to (start + 2, 6)
+Number of file 0 mappings: 14
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 42)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 21)
+- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 0, 32) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 28)
+- Code(Counter(1)) at (prev + 0, 36) to (start + 2, 6)
 - 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)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 23) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: sort_groups::other_fn
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 11]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 17, 01, 00, 0e, 01, 00, 10, 00, 11]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/sort_groups.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 17)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 17)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/test_harness.cov-map b/tests/coverage/test_harness.cov-map
index b513b3d0549..691332a1c42 100644
--- a/tests/coverage/test_harness.cov-map
+++ b/tests/coverage/test_harness.cov-map
@@ -1,18 +1,20 @@
 Function name: test_harness::my_test
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 01, 00, 10]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 0a, 01, 00, 0d, 01, 00, 0f, 00, 10]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/test_harness.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 16)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
 Highest counter ID seen: c0
 
 Function name: test_harness::unused (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 07, 01, 00, 0f]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 07, 01, 00, 0c, 00, 00, 0e, 00, 0f]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/test_harness.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 7, 1) to (start + 0, 15)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 7, 1) to (start + 0, 12)
+- Code(Zero) at (prev + 0, 14) to (start + 0, 15)
 Highest counter ID seen: (none)
 
diff --git a/tests/coverage/tight_inf_loop.cov-map b/tests/coverage/tight_inf_loop.cov-map
index 77a8ffb8358..c6bee3bd7ad 100644
--- a/tests/coverage/tight_inf_loop.cov-map
+++ b/tests/coverage/tight_inf_loop.cov-map
@@ -1,11 +1,13 @@
 Function name: tight_inf_loop::main
-Raw bytes (19): 0x[01, 01, 00, 03, 01, 01, 01, 01, 0d, 00, 02, 09, 00, 10, 01, 01, 06, 01, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 01, 01, 00, 0a, 01, 01, 08, 00, 0d, 00, 01, 09, 00, 10, 01, 01, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/tight_inf_loop.rs
 Number of expressions: 0
-Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 1, 1) to (start + 1, 13)
-- Code(Zero) at (prev + 2, 9) to (start + 0, 16)
-- Code(Counter(0)) at (prev + 1, 6) to (start + 1, 2)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 13)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/trivial.cov-map b/tests/coverage/trivial.cov-map
index 05f64896d9e..fff10df9aee 100644
--- a/tests/coverage/trivial.cov-map
+++ b/tests/coverage/trivial.cov-map
@@ -1,9 +1,10 @@
 Function name: trivial::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 03, 01, 00, 0d]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 03, 01, 00, 0a, 01, 00, 0c, 00, 0d]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/trivial.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 13)
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/try_error_result.cov-map b/tests/coverage/try_error_result.cov-map
index e45f3de1081..e08f4296153 100644
--- a/tests/coverage/try_error_result.cov-map
+++ b/tests/coverage/try_error_result.cov-map
@@ -1,73 +1,83 @@
 Function name: <try_error_result::Thing1>::get_thing_2
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 29, 05, 01, 18, 05, 02, 0d, 00, 14, 02, 02, 0d, 00, 1a, 01, 02, 05, 00, 06]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 29, 05, 00, 44, 01, 01, 0c, 00, 18, 05, 01, 0d, 00, 14, 02, 02, 0d, 00, 1a, 01, 02, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/try_error_result.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 41, 5) to (start + 1, 24)
-- Code(Counter(1)) at (prev + 2, 13) to (start + 0, 20)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 41, 5) to (start + 0, 68)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 24)
+- Code(Counter(1)) at (prev + 1, 13) to (start + 0, 20)
 - Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 26)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 2, 5) to (start + 0, 6)
 Highest counter ID seen: c1
 
 Function name: <try_error_result::Thing2>::call
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 34, 05, 01, 18, 05, 02, 0d, 00, 14, 02, 02, 0d, 00, 13, 01, 02, 05, 00, 06]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 34, 05, 00, 3a, 01, 01, 0c, 00, 18, 05, 01, 0d, 00, 14, 02, 02, 0d, 00, 13, 01, 02, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/try_error_result.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 52, 5) to (start + 1, 24)
-- Code(Counter(1)) at (prev + 2, 13) to (start + 0, 20)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 52, 5) to (start + 0, 58)
+- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 24)
+- Code(Counter(1)) at (prev + 1, 13) to (start + 0, 20)
 - Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 19)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 2, 5) to (start + 0, 6)
 Highest counter ID seen: c1
 
 Function name: try_error_result::call
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 05, 01, 01, 14, 05, 02, 09, 00, 10, 02, 02, 09, 00, 0f, 01, 02, 01, 00, 02]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 05, 01, 00, 2e, 01, 01, 08, 00, 14, 05, 01, 09, 00, 10, 02, 02, 09, 00, 0f, 01, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/try_error_result.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 5, 1) to (start + 1, 20)
-- Code(Counter(1)) at (prev + 2, 9) to (start + 0, 16)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 20)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 16)
 - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: try_error_result::main
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 71, 01, 02, 0a, 05, 03, 05, 00, 06, 02, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
+Raw bytes (46): 0x[01, 01, 01, 01, 05, 08, 01, 71, 01, 00, 1c, 01, 01, 05, 00, 0a, 01, 00, 0d, 00, 17, 01, 00, 18, 00, 2b, 01, 01, 05, 00, 0a, 05, 01, 05, 00, 06, 02, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/try_error_result.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 113, 1) to (start + 2, 10)
-- Code(Counter(1)) at (prev + 3, 5) to (start + 0, 6)
+Number of file 0 mappings: 8
+- Code(Counter(0)) at (prev + 113, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 43)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 10)
+- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 6)
 - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 11)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: try_error_result::test1
-Raw bytes (67): 0x[01, 01, 04, 07, 05, 01, 09, 05, 01, 05, 09, 0b, 01, 0d, 01, 02, 17, 05, 07, 09, 00, 0e, 09, 02, 09, 04, 1a, 02, 06, 0d, 00, 11, 02, 00, 29, 00, 2a, 00, 01, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0a, 04, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0e, 03, 05, 00, 0b, 01, 01, 01, 00, 02]
+Raw bytes (82): 0x[01, 01, 04, 07, 05, 01, 09, 05, 01, 05, 09, 0e, 01, 0d, 01, 00, 1d, 01, 01, 09, 01, 12, 01, 01, 15, 00, 17, 05, 05, 09, 00, 0e, 09, 02, 09, 01, 11, 09, 04, 0d, 00, 1a, 02, 02, 0d, 00, 11, 02, 00, 29, 00, 2a, 00, 01, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0a, 04, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0e, 03, 05, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/try_error_result.rs
 Number of expressions: 4
 - expression 0 operands: lhs = Expression(1, Add), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(0)
 - expression 3 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 11
-- Code(Counter(0)) at (prev + 13, 1) to (start + 2, 23)
-- Code(Counter(1)) at (prev + 7, 9) to (start + 0, 14)
-- Code(Counter(2)) at (prev + 2, 9) to (start + 4, 26)
-- Code(Expression(0, Sub)) at (prev + 6, 13) to (start + 0, 17)
+Number of file 0 mappings: 14
+- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 1, 18)
+- Code(Counter(0)) at (prev + 1, 21) to (start + 0, 23)
+- Code(Counter(1)) at (prev + 5, 9) to (start + 0, 14)
+- Code(Counter(2)) at (prev + 2, 9) to (start + 1, 17)
+- Code(Counter(2)) at (prev + 4, 13) to (start + 0, 26)
+- Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 17)
     = ((c0 + c2) - c1)
 - Code(Expression(0, Sub)) at (prev + 0, 41) to (start + 0, 42)
     = ((c0 + c2) - c1)
@@ -82,125 +92,157 @@ Number of file 0 mappings: 11
 Highest counter ID seen: c2
 
 Function name: try_error_result::test2
-Raw bytes (336): 0x[01, 01, 36, 0d, 11, 0d, 3f, 11, 15, 0d, 37, 3b, 1d, 3f, 19, 11, 15, 0d, 3f, 11, 15, 0d, 3b, 3f, 19, 11, 15, 0d, 37, 3b, 1d, 3f, 19, 11, 15, 41, 53, 21, 25, 41, 21, 41, 53, 21, 25, 09, 73, 77, 2d, 0d, 29, 09, 0d, 09, 77, 0d, 29, 09, 73, 77, 2d, 0d, 29, 45, 8b, 01, 31, 35, 45, 31, 45, 8b, 01, 31, 35, 49, 9f, 01, 39, 3d, 49, 39, 49, 9f, 01, 39, 3d, 05, 09, ab, 01, 09, af, 01, 3d, b3, 01, 39, b7, 01, 35, bb, 01, 31, bf, 01, 2d, c3, 01, 29, c7, 01, 25, cb, 01, 21, cf, 01, 1d, d3, 01, 19, d7, 01, 15, 05, 11, 28, 01, 3d, 01, 03, 17, 05, 08, 09, 00, 0e, 09, 02, 09, 04, 1a, 0d, 06, 0d, 00, 1f, 11, 00, 2f, 00, 30, 02, 00, 31, 03, 1c, 15, 04, 11, 00, 12, 1e, 02, 11, 03, 27, 32, 05, 11, 00, 14, 1e, 00, 17, 00, 29, 19, 00, 41, 00, 42, 26, 00, 43, 00, 47, 1d, 00, 5f, 00, 60, 32, 01, 0d, 00, 17, 4e, 01, 11, 00, 14, 41, 00, 17, 00, 29, 21, 00, 41, 00, 42, 4a, 00, 43, 00, 47, 25, 00, 60, 00, 61, 4e, 01, 0d, 00, 17, 6e, 04, 11, 00, 14, 62, 00, 17, 00, 29, 29, 00, 42, 00, 43, 66, 00, 44, 00, 48, 2d, 00, 61, 00, 62, 6e, 01, 0d, 00, 17, 86, 01, 01, 11, 00, 14, 45, 00, 17, 01, 1d, 31, 01, 36, 00, 37, 82, 01, 01, 12, 00, 16, 35, 00, 2f, 00, 30, 86, 01, 01, 0d, 00, 17, 9a, 01, 01, 11, 00, 14, 49, 00, 17, 01, 1d, 39, 02, 11, 00, 12, 96, 01, 01, 12, 00, 16, 3d, 01, 11, 00, 12, 9a, 01, 02, 0d, 00, 17, a2, 01, 03, 05, 00, 0b, a6, 01, 01, 01, 00, 02]
+Raw bytes (443): 0x[01, 01, 3d, 0d, 11, 0d, 57, 11, 15, 0d, 57, 11, 15, 0d, 57, 11, 15, 0d, 4f, 53, 1d, 57, 19, 11, 15, 0d, 57, 11, 15, 0d, 57, 11, 15, 0d, 53, 57, 19, 11, 15, 0d, 4f, 53, 1d, 57, 19, 11, 15, 41, 6b, 21, 25, 41, 21, 41, 6b, 21, 25, 09, 8f, 01, 93, 01, 2d, 0d, 29, 09, 0d, 09, 0d, 09, 93, 01, 0d, 29, 09, 8f, 01, 93, 01, 2d, 0d, 29, 45, a7, 01, 31, 35, 45, 31, 45, a7, 01, 31, 35, 49, bb, 01, 39, 3d, 49, 39, 49, bb, 01, 39, 3d, 05, 09, c7, 01, 09, cb, 01, 3d, cf, 01, 39, d3, 01, 35, d7, 01, 31, db, 01, 2d, df, 01, 29, e3, 01, 25, e7, 01, 21, eb, 01, 1d, ef, 01, 19, f3, 01, 15, 05, 11, 39, 01, 3d, 01, 00, 1d, 01, 01, 09, 00, 0f, 01, 00, 12, 00, 1a, 01, 01, 09, 01, 12, 01, 01, 15, 00, 17, 05, 05, 09, 00, 0e, 09, 02, 09, 01, 11, 09, 04, 0d, 00, 1a, 0d, 02, 0d, 00, 13, 0d, 00, 14, 00, 1f, 11, 00, 2f, 00, 30, 02, 00, 31, 00, 35, 02, 00, 45, 00, 4f, 02, 00, 50, 00, 62, 02, 01, 0d, 00, 13, 02, 02, 11, 00, 1c, 15, 01, 11, 00, 12, 36, 02, 11, 00, 15, 36, 02, 11, 00, 1b, 36, 01, 15, 00, 27, 4a, 02, 11, 00, 14, 36, 00, 17, 00, 1d, 36, 00, 1e, 00, 29, 19, 00, 41, 00, 42, 3e, 00, 43, 00, 47, 1d, 00, 5f, 00, 60, 4a, 01, 0d, 00, 17, 66, 01, 11, 00, 14, 41, 00, 17, 00, 1d, 41, 00, 1e, 00, 29, 21, 00, 41, 00, 42, 62, 00, 43, 00, 47, 25, 00, 60, 00, 61, 66, 01, 0d, 00, 17, 8a, 01, 04, 11, 00, 14, 7e, 00, 17, 00, 1d, 7e, 00, 1e, 00, 29, 29, 00, 42, 00, 43, 82, 01, 00, 44, 00, 48, 2d, 00, 61, 00, 62, 8a, 01, 01, 0d, 00, 17, a2, 01, 01, 11, 00, 14, 45, 00, 17, 00, 1d, 45, 01, 12, 00, 1d, 31, 00, 36, 00, 37, 9e, 01, 01, 12, 00, 16, 35, 00, 2f, 00, 30, a2, 01, 01, 0d, 00, 17, b6, 01, 01, 11, 00, 14, 49, 00, 17, 00, 1d, 49, 01, 12, 00, 1d, 39, 01, 11, 00, 12, b2, 01, 01, 12, 00, 16, 3d, 01, 11, 00, 12, b6, 01, 02, 0d, 00, 17, be, 01, 03, 05, 00, 0b, c2, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
-Number of expressions: 54
+- file 0 => $DIR/try_error_result.rs
+Number of expressions: 61
 - expression 0 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 1 operands: lhs = Counter(3), rhs = Expression(15, Add)
+- expression 1 operands: lhs = Counter(3), rhs = Expression(21, Add)
 - expression 2 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 3 operands: lhs = Counter(3), rhs = Expression(13, Add)
-- expression 4 operands: lhs = Expression(14, Add), rhs = Counter(7)
-- expression 5 operands: lhs = Expression(15, Add), rhs = Counter(6)
+- expression 3 operands: lhs = Counter(3), rhs = Expression(21, Add)
+- expression 4 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 5 operands: lhs = Counter(3), rhs = Expression(21, Add)
 - expression 6 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 7 operands: lhs = Counter(3), rhs = Expression(15, Add)
-- expression 8 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 9 operands: lhs = Counter(3), rhs = Expression(14, Add)
-- expression 10 operands: lhs = Expression(15, Add), rhs = Counter(6)
-- expression 11 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 12 operands: lhs = Counter(3), rhs = Expression(13, Add)
-- expression 13 operands: lhs = Expression(14, Add), rhs = Counter(7)
-- expression 14 operands: lhs = Expression(15, Add), rhs = Counter(6)
-- expression 15 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 16 operands: lhs = Counter(16), rhs = Expression(20, Add)
-- expression 17 operands: lhs = Counter(8), rhs = Counter(9)
-- expression 18 operands: lhs = Counter(16), rhs = Counter(8)
-- expression 19 operands: lhs = Counter(16), rhs = Expression(20, Add)
-- expression 20 operands: lhs = Counter(8), rhs = Counter(9)
-- expression 21 operands: lhs = Counter(2), rhs = Expression(28, Add)
-- expression 22 operands: lhs = Expression(29, Add), rhs = Counter(11)
-- expression 23 operands: lhs = Counter(3), rhs = Counter(10)
-- expression 24 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 25 operands: lhs = Counter(2), rhs = Expression(29, Add)
-- expression 26 operands: lhs = Counter(3), rhs = Counter(10)
-- expression 27 operands: lhs = Counter(2), rhs = Expression(28, Add)
-- expression 28 operands: lhs = Expression(29, Add), rhs = Counter(11)
+- expression 7 operands: lhs = Counter(3), rhs = Expression(19, Add)
+- expression 8 operands: lhs = Expression(20, Add), rhs = Counter(7)
+- expression 9 operands: lhs = Expression(21, Add), rhs = Counter(6)
+- expression 10 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 11 operands: lhs = Counter(3), rhs = Expression(21, Add)
+- expression 12 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 13 operands: lhs = Counter(3), rhs = Expression(21, Add)
+- expression 14 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 15 operands: lhs = Counter(3), rhs = Expression(20, Add)
+- expression 16 operands: lhs = Expression(21, Add), rhs = Counter(6)
+- expression 17 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 18 operands: lhs = Counter(3), rhs = Expression(19, Add)
+- expression 19 operands: lhs = Expression(20, Add), rhs = Counter(7)
+- expression 20 operands: lhs = Expression(21, Add), rhs = Counter(6)
+- expression 21 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 22 operands: lhs = Counter(16), rhs = Expression(26, Add)
+- expression 23 operands: lhs = Counter(8), rhs = Counter(9)
+- expression 24 operands: lhs = Counter(16), rhs = Counter(8)
+- expression 25 operands: lhs = Counter(16), rhs = Expression(26, Add)
+- expression 26 operands: lhs = Counter(8), rhs = Counter(9)
+- expression 27 operands: lhs = Counter(2), rhs = Expression(35, Add)
+- expression 28 operands: lhs = Expression(36, Add), rhs = Counter(11)
 - expression 29 operands: lhs = Counter(3), rhs = Counter(10)
-- expression 30 operands: lhs = Counter(17), rhs = Expression(34, Add)
-- expression 31 operands: lhs = Counter(12), rhs = Counter(13)
-- expression 32 operands: lhs = Counter(17), rhs = Counter(12)
-- expression 33 operands: lhs = Counter(17), rhs = Expression(34, Add)
-- expression 34 operands: lhs = Counter(12), rhs = Counter(13)
-- expression 35 operands: lhs = Counter(18), rhs = Expression(39, Add)
-- expression 36 operands: lhs = Counter(14), rhs = Counter(15)
-- expression 37 operands: lhs = Counter(18), rhs = Counter(14)
-- expression 38 operands: lhs = Counter(18), rhs = Expression(39, Add)
-- expression 39 operands: lhs = Counter(14), rhs = Counter(15)
-- expression 40 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 41 operands: lhs = Expression(42, Add), rhs = Counter(2)
-- expression 42 operands: lhs = Expression(43, Add), rhs = Counter(15)
-- expression 43 operands: lhs = Expression(44, Add), rhs = Counter(14)
-- expression 44 operands: lhs = Expression(45, Add), rhs = Counter(13)
-- expression 45 operands: lhs = Expression(46, Add), rhs = Counter(12)
-- expression 46 operands: lhs = Expression(47, Add), rhs = Counter(11)
-- expression 47 operands: lhs = Expression(48, Add), rhs = Counter(10)
-- expression 48 operands: lhs = Expression(49, Add), rhs = Counter(9)
-- expression 49 operands: lhs = Expression(50, Add), rhs = Counter(8)
-- expression 50 operands: lhs = Expression(51, Add), rhs = Counter(7)
-- expression 51 operands: lhs = Expression(52, Add), rhs = Counter(6)
-- expression 52 operands: lhs = Expression(53, Add), rhs = Counter(5)
-- expression 53 operands: lhs = Counter(1), rhs = Counter(4)
-Number of file 0 mappings: 40
-- Code(Counter(0)) at (prev + 61, 1) to (start + 3, 23)
-- Code(Counter(1)) at (prev + 8, 9) to (start + 0, 14)
-- Code(Counter(2)) at (prev + 2, 9) to (start + 4, 26)
-- Code(Counter(3)) at (prev + 6, 13) to (start + 0, 31)
+- expression 30 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 31 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 32 operands: lhs = Counter(2), rhs = Expression(36, Add)
+- expression 33 operands: lhs = Counter(3), rhs = Counter(10)
+- expression 34 operands: lhs = Counter(2), rhs = Expression(35, Add)
+- expression 35 operands: lhs = Expression(36, Add), rhs = Counter(11)
+- expression 36 operands: lhs = Counter(3), rhs = Counter(10)
+- expression 37 operands: lhs = Counter(17), rhs = Expression(41, Add)
+- expression 38 operands: lhs = Counter(12), rhs = Counter(13)
+- expression 39 operands: lhs = Counter(17), rhs = Counter(12)
+- expression 40 operands: lhs = Counter(17), rhs = Expression(41, Add)
+- expression 41 operands: lhs = Counter(12), rhs = Counter(13)
+- expression 42 operands: lhs = Counter(18), rhs = Expression(46, Add)
+- expression 43 operands: lhs = Counter(14), rhs = Counter(15)
+- expression 44 operands: lhs = Counter(18), rhs = Counter(14)
+- expression 45 operands: lhs = Counter(18), rhs = Expression(46, Add)
+- expression 46 operands: lhs = Counter(14), rhs = Counter(15)
+- expression 47 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 48 operands: lhs = Expression(49, Add), rhs = Counter(2)
+- expression 49 operands: lhs = Expression(50, Add), rhs = Counter(15)
+- expression 50 operands: lhs = Expression(51, Add), rhs = Counter(14)
+- expression 51 operands: lhs = Expression(52, Add), rhs = Counter(13)
+- expression 52 operands: lhs = Expression(53, Add), rhs = Counter(12)
+- expression 53 operands: lhs = Expression(54, Add), rhs = Counter(11)
+- expression 54 operands: lhs = Expression(55, Add), rhs = Counter(10)
+- expression 55 operands: lhs = Expression(56, Add), rhs = Counter(9)
+- expression 56 operands: lhs = Expression(57, Add), rhs = Counter(8)
+- expression 57 operands: lhs = Expression(58, Add), rhs = Counter(7)
+- expression 58 operands: lhs = Expression(59, Add), rhs = Counter(6)
+- expression 59 operands: lhs = Expression(60, Add), rhs = Counter(5)
+- expression 60 operands: lhs = Counter(1), rhs = Counter(4)
+Number of file 0 mappings: 57
+- Code(Counter(0)) at (prev + 61, 1) to (start + 0, 29)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 1, 18)
+- Code(Counter(0)) at (prev + 1, 21) to (start + 0, 23)
+- Code(Counter(1)) at (prev + 5, 9) to (start + 0, 14)
+- Code(Counter(2)) at (prev + 2, 9) to (start + 1, 17)
+- Code(Counter(2)) at (prev + 4, 13) to (start + 0, 26)
+- Code(Counter(3)) at (prev + 2, 13) to (start + 0, 19)
+- Code(Counter(3)) at (prev + 0, 20) to (start + 0, 31)
 - Code(Counter(4)) at (prev + 0, 47) to (start + 0, 48)
-- Code(Expression(0, Sub)) at (prev + 0, 49) to (start + 3, 28)
+- Code(Expression(0, Sub)) at (prev + 0, 49) to (start + 0, 53)
     = (c3 - c4)
-- Code(Counter(5)) at (prev + 4, 17) to (start + 0, 18)
-- Code(Expression(7, Sub)) at (prev + 2, 17) to (start + 3, 39)
+- Code(Expression(0, Sub)) at (prev + 0, 69) to (start + 0, 79)
+    = (c3 - c4)
+- Code(Expression(0, Sub)) at (prev + 0, 80) to (start + 0, 98)
+    = (c3 - c4)
+- Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 19)
+    = (c3 - c4)
+- Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 28)
+    = (c3 - c4)
+- Code(Counter(5)) at (prev + 1, 17) to (start + 0, 18)
+- Code(Expression(13, Sub)) at (prev + 2, 17) to (start + 0, 21)
     = (c3 - (c4 + c5))
-- Code(Expression(12, Sub)) at (prev + 5, 17) to (start + 0, 20)
+- Code(Expression(13, Sub)) at (prev + 2, 17) to (start + 0, 27)
+    = (c3 - (c4 + c5))
+- Code(Expression(13, Sub)) at (prev + 1, 21) to (start + 0, 39)
+    = (c3 - (c4 + c5))
+- Code(Expression(18, Sub)) at (prev + 2, 17) to (start + 0, 20)
     = (c3 - (((c4 + c5) + c6) + c7))
-- Code(Expression(7, Sub)) at (prev + 0, 23) to (start + 0, 41)
+- Code(Expression(13, Sub)) at (prev + 0, 23) to (start + 0, 29)
+    = (c3 - (c4 + c5))
+- Code(Expression(13, Sub)) at (prev + 0, 30) to (start + 0, 41)
     = (c3 - (c4 + c5))
 - Code(Counter(6)) at (prev + 0, 65) to (start + 0, 66)
-- Code(Expression(9, Sub)) at (prev + 0, 67) to (start + 0, 71)
+- Code(Expression(15, Sub)) at (prev + 0, 67) to (start + 0, 71)
     = (c3 - ((c4 + c5) + c6))
 - Code(Counter(7)) at (prev + 0, 95) to (start + 0, 96)
-- Code(Expression(12, Sub)) at (prev + 1, 13) to (start + 0, 23)
+- Code(Expression(18, Sub)) at (prev + 1, 13) to (start + 0, 23)
     = (c3 - (((c4 + c5) + c6) + c7))
-- Code(Expression(19, Sub)) at (prev + 1, 17) to (start + 0, 20)
+- Code(Expression(25, Sub)) at (prev + 1, 17) to (start + 0, 20)
     = (c16 - (c8 + c9))
-- Code(Counter(16)) at (prev + 0, 23) to (start + 0, 41)
+- Code(Counter(16)) at (prev + 0, 23) to (start + 0, 29)
+- Code(Counter(16)) at (prev + 0, 30) to (start + 0, 41)
 - Code(Counter(8)) at (prev + 0, 65) to (start + 0, 66)
-- Code(Expression(18, Sub)) at (prev + 0, 67) to (start + 0, 71)
+- Code(Expression(24, Sub)) at (prev + 0, 67) to (start + 0, 71)
     = (c16 - c8)
 - Code(Counter(9)) at (prev + 0, 96) to (start + 0, 97)
-- Code(Expression(19, Sub)) at (prev + 1, 13) to (start + 0, 23)
+- Code(Expression(25, Sub)) at (prev + 1, 13) to (start + 0, 23)
     = (c16 - (c8 + c9))
-- Code(Expression(27, Sub)) at (prev + 4, 17) to (start + 0, 20)
+- Code(Expression(34, Sub)) at (prev + 4, 17) to (start + 0, 20)
     = (c2 - ((c3 + c10) + c11))
-- Code(Expression(24, Sub)) at (prev + 0, 23) to (start + 0, 41)
+- Code(Expression(31, Sub)) at (prev + 0, 23) to (start + 0, 29)
+    = (c2 - c3)
+- Code(Expression(31, Sub)) at (prev + 0, 30) to (start + 0, 41)
     = (c2 - c3)
 - Code(Counter(10)) at (prev + 0, 66) to (start + 0, 67)
-- Code(Expression(25, Sub)) at (prev + 0, 68) to (start + 0, 72)
+- Code(Expression(32, Sub)) at (prev + 0, 68) to (start + 0, 72)
     = (c2 - (c3 + c10))
 - Code(Counter(11)) at (prev + 0, 97) to (start + 0, 98)
-- Code(Expression(27, Sub)) at (prev + 1, 13) to (start + 0, 23)
+- Code(Expression(34, Sub)) at (prev + 1, 13) to (start + 0, 23)
     = (c2 - ((c3 + c10) + c11))
-- Code(Expression(33, Sub)) at (prev + 1, 17) to (start + 0, 20)
+- Code(Expression(40, Sub)) at (prev + 1, 17) to (start + 0, 20)
     = (c17 - (c12 + c13))
-- Code(Counter(17)) at (prev + 0, 23) to (start + 1, 29)
-- Code(Counter(12)) at (prev + 1, 54) to (start + 0, 55)
-- Code(Expression(32, Sub)) at (prev + 1, 18) to (start + 0, 22)
+- Code(Counter(17)) at (prev + 0, 23) to (start + 0, 29)
+- Code(Counter(17)) at (prev + 1, 18) to (start + 0, 29)
+- Code(Counter(12)) at (prev + 0, 54) to (start + 0, 55)
+- Code(Expression(39, Sub)) at (prev + 1, 18) to (start + 0, 22)
     = (c17 - c12)
 - Code(Counter(13)) at (prev + 0, 47) to (start + 0, 48)
-- Code(Expression(33, Sub)) at (prev + 1, 13) to (start + 0, 23)
+- Code(Expression(40, Sub)) at (prev + 1, 13) to (start + 0, 23)
     = (c17 - (c12 + c13))
-- Code(Expression(38, Sub)) at (prev + 1, 17) to (start + 0, 20)
+- Code(Expression(45, Sub)) at (prev + 1, 17) to (start + 0, 20)
     = (c18 - (c14 + c15))
-- Code(Counter(18)) at (prev + 0, 23) to (start + 1, 29)
-- Code(Counter(14)) at (prev + 2, 17) to (start + 0, 18)
-- Code(Expression(37, Sub)) at (prev + 1, 18) to (start + 0, 22)
+- Code(Counter(18)) at (prev + 0, 23) to (start + 0, 29)
+- Code(Counter(18)) at (prev + 1, 18) to (start + 0, 29)
+- Code(Counter(14)) at (prev + 1, 17) to (start + 0, 18)
+- Code(Expression(44, Sub)) at (prev + 1, 18) to (start + 0, 22)
     = (c18 - c14)
 - Code(Counter(15)) at (prev + 1, 17) to (start + 0, 18)
-- Code(Expression(38, Sub)) at (prev + 2, 13) to (start + 0, 23)
+- Code(Expression(45, Sub)) at (prev + 2, 13) to (start + 0, 23)
     = (c18 - (c14 + c15))
-- Code(Expression(40, Sub)) at (prev + 3, 5) to (start + 0, 11)
+- Code(Expression(47, Sub)) at (prev + 3, 5) to (start + 0, 11)
     = (c1 - c2)
-- Code(Expression(41, Sub)) at (prev + 1, 1) to (start + 0, 2)
+- Code(Expression(48, Sub)) at (prev + 1, 1) to (start + 0, 2)
     = (((((((((((((c1 + c4) + c5) + c6) + c7) + c8) + c9) + c10) + c11) + c12) + c13) + c14) + c15) - c2)
 Highest counter ID seen: c18
 
diff --git a/tests/coverage/try_error_result.coverage b/tests/coverage/try_error_result.coverage
index 7a89c0452ac..f2ec82f20fa 100644
--- a/tests/coverage/try_error_result.coverage
+++ b/tests/coverage/try_error_result.coverage
@@ -21,8 +21,8 @@
    LL|       |    {
    LL|      6|        countdown
    LL|      6|            -= 1
-   LL|      6|        ;
-   LL|      6|        if
+   LL|       |        ;
+   LL|       |        if
    LL|      6|            countdown < 5
    LL|       |        {
    LL|      1|            call(/*return_error=*/ true)?;
@@ -71,19 +71,19 @@
    LL|       |    {
    LL|      6|        countdown
    LL|      6|            -= 1
-   LL|      6|        ;
-   LL|      6|        if
+   LL|       |        ;
+   LL|       |        if
    LL|      6|            countdown < 5
    LL|       |        {
    LL|      1|            thing1.get_thing_2(/*err=*/ false)?.call(/*err=*/ true).expect_err("call should fail");
                                                             ^0
    LL|      1|            thing1
-   LL|      1|                .
+   LL|       |                .
    LL|      1|                get_thing_2(/*return_error=*/ false)
    LL|      0|                ?
    LL|       |                .
    LL|      1|                call(/*return_error=*/ true)
-   LL|      1|                .
+   LL|       |                .
    LL|      1|                expect_err(
    LL|      1|                    "call should fail"
    LL|       |                );
diff --git a/tests/coverage/unicode.cov-map b/tests/coverage/unicode.cov-map
index 29d40a05513..bbfa8b940c6 100644
--- a/tests/coverage/unicode.cov-map
+++ b/tests/coverage/unicode.cov-map
@@ -1,12 +1,12 @@
 Function name: unicode::main
-Raw bytes (53): 0x[01, 01, 02, 05, 01, 01, 0d, 09, 01, 0e, 01, 00, 0b, 02, 01, 09, 00, 0c, 05, 00, 10, 00, 1b, 02, 00, 1c, 00, 28, 01, 02, 08, 00, 23, 09, 00, 29, 00, 44, 0d, 00, 47, 02, 06, 06, 02, 05, 00, 06, 01, 02, 05, 01, 02]
+Raw bytes (58): 0x[01, 01, 02, 05, 01, 01, 0d, 0a, 01, 0e, 01, 00, 0a, 02, 01, 09, 00, 0c, 05, 00, 10, 00, 1b, 02, 00, 1c, 00, 28, 01, 02, 08, 00, 23, 09, 00, 29, 00, 44, 0d, 00, 47, 02, 06, 06, 02, 05, 00, 06, 01, 02, 05, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/unicode.rs
 Number of expressions: 2
 - expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(3)
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 11)
+Number of file 0 mappings: 10
+- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 10)
 - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 12)
     = (c1 - c0)
 - Code(Counter(1)) at (prev + 0, 16) to (start + 0, 27)
@@ -17,24 +17,28 @@ Number of file 0 mappings: 9
 - Code(Counter(3)) at (prev + 0, 71) to (start + 2, 6)
 - Code(Expression(1, Sub)) at (prev + 2, 5) to (start + 0, 6)
     = (c0 - c3)
-- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c3
 
 Function name: unicode::他 (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 1e, 19, 00, 25]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 1e, 19, 00, 22, 00, 00, 24, 00, 25]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/unicode.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 30, 25) to (start + 0, 37)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 30, 25) to (start + 0, 34)
+- Code(Zero) at (prev + 0, 36) to (start + 0, 37)
 Highest counter ID seen: (none)
 
 Function name: unicode::申し訳ございません
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 18, 01, 02, 02]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 18, 01, 00, 29, 01, 01, 05, 00, 19, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/unicode.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 24, 1) to (start + 2, 2)
+Number of file 0 mappings: 3
+- Code(Counter(0)) at (prev + 24, 1) to (start + 0, 41)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 25)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/unicode.coverage b/tests/coverage/unicode.coverage
index 44349954550..4646cc92e8e 100644
--- a/tests/coverage/unicode.coverage
+++ b/tests/coverage/unicode.coverage
@@ -29,7 +29,7 @@
    LL|       |
    LL|       |macro_rules! macro_that_defines_a_function {
    LL|       |    (fn $名:ident () $体:tt) => {
-   LL|      0|        fn $名 () $体 fn 他 () {}
+   LL|      0|        fn $名 () $体 fn 他 () {}
    LL|       |    }
    LL|       |}
    LL|       |
diff --git a/tests/coverage/unreachable.cov-map b/tests/coverage/unreachable.cov-map
index 0bc18bfcbd3..c38786ee664 100644
--- a/tests/coverage/unreachable.cov-map
+++ b/tests/coverage/unreachable.cov-map
@@ -1,27 +1,29 @@
 Function name: unreachable::UNREACHABLE_CLOSURE::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 0e, 27, 00, 45]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 0e, 30, 00, 45]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/unreachable.rs
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Zero) at (prev + 14, 39) to (start + 0, 69)
+- Code(Zero) at (prev + 14, 48) to (start + 0, 69)
 Highest counter ID seen: (none)
 
 Function name: unreachable::unreachable_function (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 10, 01, 01, 23]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 10, 01, 00, 1a, 00, 01, 0e, 00, 23]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/unreachable.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 16, 1) to (start + 1, 35)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 16, 1) to (start + 0, 26)
+- Code(Zero) at (prev + 1, 14) to (start + 0, 35)
 Highest counter ID seen: (none)
 
 Function name: unreachable::unreachable_intrinsic (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 01, 2a]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 15, 01, 00, 1b, 00, 01, 0e, 00, 2a]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/unreachable.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 21, 1) to (start + 1, 42)
+Number of file 0 mappings: 2
+- Code(Zero) at (prev + 21, 1) to (start + 0, 27)
+- Code(Zero) at (prev + 1, 14) to (start + 0, 42)
 Highest counter ID seen: (none)
 
diff --git a/tests/coverage/unused.cov-map b/tests/coverage/unused.cov-map
index c18d331ec2e..3380997b921 100644
--- a/tests/coverage/unused.cov-map
+++ b/tests/coverage/unused.cov-map
@@ -1,14 +1,16 @@
 Function name: unused::foo::<f32>
-Raw bytes (40): 0x[01, 01, 03, 05, 01, 05, 0b, 01, 09, 06, 01, 03, 01, 01, 12, 05, 02, 0b, 00, 11, 02, 01, 09, 00, 0f, 06, 00, 13, 00, 19, 02, 01, 09, 00, 0f, 01, 02, 01, 00, 02]
+Raw bytes (50): 0x[01, 01, 03, 05, 01, 05, 0b, 01, 09, 08, 01, 03, 01, 00, 10, 01, 01, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0b, 00, 11, 02, 01, 09, 00, 0f, 06, 00, 13, 00, 19, 02, 01, 09, 00, 0f, 01, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/unused.rs
 Number of expressions: 3
 - expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 - expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 3, 1) to (start + 1, 18)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 17)
+Number of file 0 mappings: 8
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
+- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 17)
 - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15)
     = (c1 - c0)
 - Code(Expression(1, Sub)) at (prev + 0, 19) to (start + 0, 25)
@@ -19,16 +21,18 @@ Number of file 0 mappings: 6
 Highest counter ID seen: c1
 
 Function name: unused::foo::<u32>
-Raw bytes (40): 0x[01, 01, 03, 05, 01, 05, 0b, 01, 09, 06, 01, 03, 01, 01, 12, 05, 02, 0b, 00, 11, 02, 01, 09, 00, 0f, 06, 00, 13, 00, 19, 02, 01, 09, 00, 0f, 01, 02, 01, 00, 02]
+Raw bytes (50): 0x[01, 01, 03, 05, 01, 05, 0b, 01, 09, 08, 01, 03, 01, 00, 10, 01, 01, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0b, 00, 11, 02, 01, 09, 00, 0f, 06, 00, 13, 00, 19, 02, 01, 09, 00, 0f, 01, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/unused.rs
 Number of expressions: 3
 - expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 - expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(2)
-Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 3, 1) to (start + 1, 18)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 17)
+Number of file 0 mappings: 8
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14)
+- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18)
+- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 17)
 - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15)
     = (c1 - c0)
 - Code(Expression(1, Sub)) at (prev + 0, 19) to (start + 0, 25)
@@ -39,58 +43,67 @@ Number of file 0 mappings: 6
 Highest counter ID seen: c1
 
 Function name: unused::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 25, 01, 04, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 01, 25, 01, 00, 1c, 01, 01, 05, 00, 0f, 01, 01, 05, 00, 0f, 01, 01, 05, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/unused.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 37, 1) to (start + 4, 2)
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 11)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 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, 05, 00, 06, 00, 01, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 00, 13, 01, 00, 1b, 00, 01, 08, 00, 0e, 00, 00, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/unused.rs
 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)
+Number of file 0 mappings: 5
+- Code(Zero) at (prev + 19, 1) to (start + 0, 27)
+- Code(Zero) at (prev + 1, 8) to (start + 0, 14)
+- Code(Zero) at (prev + 0, 15) to (start + 2, 6)
 - 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, 05, 00, 06, 00, 01, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 00, 19, 01, 00, 1c, 00, 01, 08, 00, 0e, 00, 00, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/unused.rs
 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)
+Number of file 0 mappings: 5
+- Code(Zero) at (prev + 25, 1) to (start + 0, 28)
+- Code(Zero) at (prev + 1, 8) to (start + 0, 14)
+- Code(Zero) at (prev + 0, 15) to (start + 2, 6)
 - 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, 05, 00, 06, 00, 01, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 00, 1f, 01, 00, 1c, 00, 01, 08, 00, 0e, 00, 00, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/unused.rs
 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)
+Number of file 0 mappings: 5
+- Code(Zero) at (prev + 31, 1) to (start + 0, 28)
+- Code(Zero) at (prev + 1, 8) to (start + 0, 14)
+- Code(Zero) at (prev + 0, 15) to (start + 2, 6)
 - 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_template_func::<_> (unused)
-Raw bytes (34): 0x[01, 01, 00, 06, 00, 0b, 01, 01, 12, 00, 02, 0b, 00, 11, 00, 01, 09, 00, 0f, 00, 00, 13, 00, 19, 00, 01, 09, 00, 0f, 00, 02, 01, 00, 02]
+Raw bytes (44): 0x[01, 01, 00, 08, 00, 0b, 01, 00, 21, 00, 01, 09, 00, 0e, 00, 00, 11, 00, 12, 00, 01, 0b, 00, 11, 00, 01, 09, 00, 0f, 00, 00, 13, 00, 19, 00, 01, 09, 00, 0f, 00, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/unused.rs
 Number of expressions: 0
-Number of file 0 mappings: 6
-- Code(Zero) at (prev + 11, 1) to (start + 1, 18)
-- Code(Zero) at (prev + 2, 11) to (start + 0, 17)
+Number of file 0 mappings: 8
+- Code(Zero) at (prev + 11, 1) to (start + 0, 33)
+- Code(Zero) at (prev + 1, 9) to (start + 0, 14)
+- Code(Zero) at (prev + 0, 17) to (start + 0, 18)
+- Code(Zero) at (prev + 1, 11) to (start + 0, 17)
 - Code(Zero) at (prev + 1, 9) to (start + 0, 15)
 - Code(Zero) at (prev + 0, 19) to (start + 0, 25)
 - Code(Zero) at (prev + 1, 9) to (start + 0, 15)
diff --git a/tests/coverage/unused_mod.cov-map b/tests/coverage/unused_mod.cov-map
index 5e8b69fcdba..ea419edbdaf 100644
--- a/tests/coverage/unused_mod.cov-map
+++ b/tests/coverage/unused_mod.cov-map
@@ -1,18 +1,24 @@
 Function name: unused_mod::main
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 04, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 04, 01, 00, 0a, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 1c, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/unused_mod.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 4, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: unused_mod::unused_module::never_called_function (unused)
-Raw bytes (9): 0x[01, 02, 00, 01, 00, 02, 01, 02, 02]
+Raw bytes (24): 0x[01, 02, 00, 04, 00, 02, 01, 00, 1f, 00, 01, 05, 00, 0d, 00, 00, 0e, 00, 21, 00, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 2
+- file 0 => $DIR/auxiliary/unused_mod_helper.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 2, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Zero) at (prev + 2, 1) to (start + 0, 31)
+- Code(Zero) at (prev + 1, 5) to (start + 0, 13)
+- Code(Zero) at (prev + 0, 14) to (start + 0, 33)
+- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: (none)
 
diff --git a/tests/coverage/uses_crate.cov-map b/tests/coverage/uses_crate.cov-map
index 5c23f882697..8f3c63aba5c 100644
--- a/tests/coverage/uses_crate.cov-map
+++ b/tests/coverage/uses_crate.cov-map
@@ -1,45 +1,67 @@
 Function name: used_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 1b, 01, 00, 4c, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 4f, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/auxiliary/used_crate.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 27, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 76)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 79)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 13, 01, 00, 43, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 46, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/auxiliary/used_crate.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 19, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 70)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: used_crate::used_only_from_bin_crate_generic_function::<&str>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 13, 01, 00, 43, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 46, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/auxiliary/used_crate.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 19, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 70)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1f, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 1f, 01, 00, 5b, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 5e, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/auxiliary/used_crate.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 31, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 91)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 94)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: uses_crate::main
-Raw bytes (9): 0x[01, 02, 00, 01, 01, 0c, 01, 07, 02]
+Raw bytes (59): 0x[01, 02, 00, 0b, 01, 0c, 01, 00, 0a, 01, 01, 05, 00, 1e, 01, 01, 09, 00, 11, 01, 00, 14, 00, 18, 01, 01, 05, 00, 3a, 01, 00, 3b, 00, 44, 01, 01, 05, 00, 3a, 01, 01, 05, 00, 43, 01, 00, 44, 00, 4c, 01, 01, 05, 00, 52, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 2
+- file 0 => $DIR/uses_crate.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 12, 1) to (start + 7, 2)
+Number of file 0 mappings: 11
+- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 58)
+- Code(Counter(0)) at (prev + 0, 59) to (start + 0, 68)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 58)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 0, 68) to (start + 0, 76)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 82)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/uses_crate.coverage b/tests/coverage/uses_crate.coverage
index d1b0dadda76..145c0649ac7 100644
--- a/tests/coverage/uses_crate.coverage
+++ b/tests/coverage/uses_crate.coverage
@@ -6,9 +6,9 @@ $DIR/auxiliary/used_crate.rs:
    LL|       |use std::fmt::Debug;
    LL|       |
    LL|      1|pub fn used_function() {
-   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-   LL|      1|    // dependent conditions.
+   LL|       |    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|       |    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|       |    // dependent conditions.
    LL|      1|    let is_true = std::env::args().len() == 1;
    LL|      1|    let mut countdown = 0;
    LL|      1|    if is_true {
@@ -104,8 +104,8 @@ $DIR/auxiliary/used_crate.rs:
    LL|      1|fn use_this_lib_crate() {
    LL|      1|    used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
    LL|      1|    used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
-   LL|      1|        "used from library used_crate.rs",
-   LL|      1|    );
+   LL|       |        "used from library used_crate.rs",
+   LL|       |    );
    LL|      1|    let some_vec = vec![5, 6, 7, 8];
    LL|      1|    used_only_from_this_lib_crate_generic_function(some_vec);
    LL|      1|    used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
diff --git a/tests/coverage/uses_inline_crate.cov-map b/tests/coverage/uses_inline_crate.cov-map
index a482d20e3b4..52f3f94ce64 100644
--- a/tests/coverage/uses_inline_crate.cov-map
+++ b/tests/coverage/uses_inline_crate.cov-map
@@ -1,59 +1,88 @@
 Function name: used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 2c, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 2c, 01, 00, 4c, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 4f, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/auxiliary/used_inline_crate.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 44, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 44, 1) to (start + 0, 76)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 79)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 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, 05, 00, 06, 01, 01, 05, 01, 02]
+Raw bytes (56): 0x[01, 01, 01, 01, 05, 0a, 01, 14, 01, 00, 1e, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0f, 05, 00, 10, 02, 06, 02, 02, 05, 00, 06, 01, 01, 05, 00, 17, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/auxiliary/used_inline_crate.rs
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(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)
+Number of file 0 mappings: 10
+- Code(Counter(0)) at (prev + 20, 1) to (start + 0, 30)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 15)
+- Code(Counter(1)) at (prev + 0, 16) to (start + 2, 6)
 - 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)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 23)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: used_inline_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 21, 01, 00, 43, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 46, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/auxiliary/used_inline_crate.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 70)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: used_inline_crate::used_only_from_bin_crate_generic_function::<&str>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 21, 01, 00, 43, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 46, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/auxiliary/used_inline_crate.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 67)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 70)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 31, 01, 02, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 31, 01, 00, 5b, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 5e, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/auxiliary/used_inline_crate.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 49, 1) to (start + 2, 2)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 49, 1) to (start + 0, 91)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 94)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
 Function name: uses_inline_crate::main
-Raw bytes (9): 0x[01, 02, 00, 01, 01, 0c, 01, 0a, 02]
+Raw bytes (64): 0x[01, 02, 00, 0c, 01, 0c, 01, 00, 0a, 01, 01, 05, 00, 25, 01, 01, 05, 00, 2c, 01, 01, 09, 00, 11, 01, 00, 14, 00, 18, 01, 01, 05, 00, 41, 01, 00, 42, 00, 4b, 01, 01, 05, 00, 41, 01, 01, 05, 00, 4a, 01, 00, 4b, 00, 53, 01, 01, 05, 00, 59, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 2
+- file 0 => $DIR/uses_inline_crate.rs
 Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 12, 1) to (start + 10, 2)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 37)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 44)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 24)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 65)
+- Code(Counter(0)) at (prev + 0, 66) to (start + 0, 75)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 65)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 74)
+- Code(Counter(0)) at (prev + 0, 75) to (start + 0, 83)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 89)
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/uses_inline_crate.coverage b/tests/coverage/uses_inline_crate.coverage
index 4671c95aefa..15084bcf7ea 100644
--- a/tests/coverage/uses_inline_crate.coverage
+++ b/tests/coverage/uses_inline_crate.coverage
@@ -6,9 +6,9 @@ $DIR/auxiliary/used_inline_crate.rs:
    LL|       |use std::fmt::Debug;
    LL|       |
    LL|      1|pub fn used_function() {
-   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-   LL|      1|    // dependent conditions.
+   LL|       |    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|       |    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|       |    // dependent conditions.
    LL|      1|    let is_true = std::env::args().len() == 1;
    LL|      1|    let mut countdown = 0;
    LL|      1|    if is_true {
@@ -20,9 +20,9 @@ $DIR/auxiliary/used_inline_crate.rs:
    LL|       |
    LL|       |#[inline(always)]
    LL|      1|pub fn used_inline_function() {
-   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-   LL|      1|    // dependent conditions.
+   LL|       |    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|       |    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|       |    // dependent conditions.
    LL|      1|    let is_true = std::env::args().len() == 1;
    LL|      1|    let mut countdown = 0;
    LL|      1|    if is_true {
@@ -126,8 +126,8 @@ $DIR/auxiliary/used_inline_crate.rs:
    LL|      2|fn use_this_lib_crate() {
    LL|      2|    used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
    LL|      2|    used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
-   LL|      2|        "used from library used_crate.rs",
-   LL|      2|    );
+   LL|       |        "used from library used_crate.rs",
+   LL|       |    );
    LL|      2|    let some_vec = vec![5, 6, 7, 8];
    LL|      2|    used_only_from_this_lib_crate_generic_function(some_vec);
    LL|      2|    used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
@@ -153,7 +153,7 @@ $DIR/uses_inline_crate.rs:
    LL|      1|    used_inline_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
    LL|      1|    used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
    LL|      1|    used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
-   LL|      1|        "interesting?",
-   LL|      1|    );
+   LL|       |        "interesting?",
+   LL|       |    );
    LL|      1|}
 
diff --git a/tests/coverage/while.cov-map b/tests/coverage/while.cov-map
index 5a6698128cb..c4183e18e02 100644
--- a/tests/coverage/while.cov-map
+++ b/tests/coverage/while.cov-map
@@ -1,11 +1,13 @@
 Function name: while::main
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 01, 01, 01, 10, 01, 02, 0b, 00, 14, 00, 00, 15, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 01, 01, 00, 0a, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 10, 01, 01, 0b, 00, 14, 00, 00, 15, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/while.rs
 Number of expressions: 0
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 1, 1) to (start + 1, 16)
-- Code(Counter(0)) at (prev + 2, 11) to (start + 0, 20)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 12)
+- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 1, 11) to (start + 0, 20)
 - Code(Zero) at (prev + 0, 21) to (start + 2, 6)
 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
 Highest counter ID seen: c0
diff --git a/tests/coverage/while_early_ret.cov-map b/tests/coverage/while_early_ret.cov-map
index 69b51bf9ca3..b29b5d40c4d 100644
--- a/tests/coverage/while_early_ret.cov-map
+++ b/tests/coverage/while_early_ret.cov-map
@@ -1,27 +1,32 @@
 Function name: while_early_ret::main
-Raw bytes (63): 0x[01, 01, 07, 0f, 05, 01, 09, 0f, 13, 01, 09, 05, 0d, 05, 01, 05, 09, 09, 01, 05, 01, 01, 1b, 05, 03, 09, 02, 0a, 09, 05, 0d, 02, 0e, 02, 06, 15, 02, 16, 0d, 04, 15, 00, 1b, 0a, 04, 15, 00, 1b, 16, 03, 0a, 03, 0a, 1a, 06, 05, 00, 0b, 01, 01, 01, 00, 02]
+Raw bytes (80): 0x[01, 01, 08, 0f, 05, 01, 09, 0f, 13, 01, 09, 05, 0d, 05, 01, 05, 01, 05, 09, 0c, 01, 05, 01, 00, 1c, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 02, 09, 02, 0a, 09, 05, 0d, 02, 0e, 02, 06, 15, 02, 16, 0d, 04, 15, 00, 1b, 0a, 04, 15, 00, 1b, 1a, 03, 09, 00, 0a, 1a, 01, 09, 02, 0a, 1e, 05, 05, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
-Number of expressions: 7
+- file 0 => $DIR/while_early_ret.rs
+Number of expressions: 8
 - expression 0 operands: lhs = Expression(3, Add), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(2)
 - expression 2 operands: lhs = Expression(3, Add), rhs = Expression(4, Add)
 - expression 3 operands: lhs = Counter(0), rhs = Counter(2)
 - expression 4 operands: lhs = Counter(1), rhs = Counter(3)
 - expression 5 operands: lhs = Counter(1), rhs = Counter(0)
-- expression 6 operands: lhs = Counter(1), rhs = Counter(2)
-Number of file 0 mappings: 9
-- Code(Counter(0)) at (prev + 5, 1) to (start + 1, 27)
-- Code(Counter(1)) at (prev + 3, 9) to (start + 2, 10)
+- expression 6 operands: lhs = Counter(1), rhs = Counter(0)
+- expression 7 operands: lhs = Counter(1), rhs = Counter(2)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 28)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 27)
+- Code(Counter(1)) at (prev + 2, 9) to (start + 2, 10)
 - Code(Counter(2)) at (prev + 5, 13) to (start + 2, 14)
 - Code(Expression(0, Sub)) at (prev + 6, 21) to (start + 2, 22)
     = ((c0 + c2) - c1)
 - Code(Counter(3)) at (prev + 4, 21) to (start + 0, 27)
 - Code(Expression(2, Sub)) at (prev + 4, 21) to (start + 0, 27)
     = ((c0 + c2) - (c1 + c3))
-- Code(Expression(5, Sub)) at (prev + 3, 10) to (start + 3, 10)
+- Code(Expression(6, Sub)) at (prev + 3, 9) to (start + 0, 10)
     = (c1 - c0)
-- Code(Expression(6, Sub)) at (prev + 6, 5) to (start + 0, 11)
+- Code(Expression(6, Sub)) at (prev + 1, 9) to (start + 2, 10)
+    = (c1 - c0)
+- Code(Expression(7, Sub)) at (prev + 5, 5) to (start + 0, 11)
     = (c1 - c2)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c3
diff --git a/tests/coverage/yield.cov-map b/tests/coverage/yield.cov-map
index bf0916e5503..87d0a047261 100644
--- a/tests/coverage/yield.cov-map
+++ b/tests/coverage/yield.cov-map
@@ -1,30 +1,39 @@
 Function name: yield::main
-Raw bytes (94): 0x[01, 01, 05, 01, 05, 05, 09, 09, 11, 11, 15, 11, 15, 10, 01, 07, 01, 01, 16, 01, 07, 0b, 00, 2e, 05, 01, 27, 00, 29, 02, 01, 0e, 00, 14, 05, 02, 0b, 00, 2e, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 14, 09, 03, 09, 00, 16, 09, 08, 0b, 00, 2e, 11, 01, 27, 00, 29, 0a, 01, 0e, 00, 14, 11, 02, 0b, 00, 2e, 12, 01, 27, 00, 29, 15, 01, 0e, 00, 14, 12, 02, 01, 00, 02]
+Raw bytes (139): 0x[01, 01, 05, 01, 05, 05, 09, 09, 11, 11, 15, 11, 15, 19, 01, 07, 01, 00, 0a, 01, 01, 09, 00, 16, 01, 06, 0b, 00, 13, 01, 00, 0b, 00, 2e, 01, 00, 14, 00, 22, 05, 01, 27, 00, 29, 02, 01, 0e, 00, 14, 05, 02, 0b, 00, 13, 05, 00, 0b, 00, 2e, 05, 00, 14, 00, 22, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 14, 09, 03, 09, 00, 16, 09, 08, 0b, 00, 13, 09, 00, 0b, 00, 2e, 09, 00, 14, 00, 22, 11, 01, 27, 00, 29, 0a, 01, 0e, 00, 14, 11, 02, 0b, 00, 13, 11, 00, 0b, 00, 2e, 11, 00, 14, 00, 22, 12, 01, 27, 00, 29, 15, 01, 0e, 00, 14, 12, 02, 01, 00, 02]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/yield.rs
 Number of expressions: 5
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(2), rhs = Counter(4)
 - expression 3 operands: lhs = Counter(4), rhs = Counter(5)
 - expression 4 operands: lhs = Counter(4), rhs = Counter(5)
-Number of file 0 mappings: 16
-- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 22)
-- Code(Counter(0)) at (prev + 7, 11) to (start + 0, 46)
+Number of file 0 mappings: 25
+- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
+- Code(Counter(0)) at (prev + 6, 11) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 0, 11) to (start + 0, 46)
+- Code(Counter(0)) at (prev + 0, 20) to (start + 0, 34)
 - Code(Counter(1)) at (prev + 1, 39) to (start + 0, 41)
 - Code(Expression(0, Sub)) at (prev + 1, 14) to (start + 0, 20)
     = (c0 - c1)
-- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 46)
+- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 19)
+- Code(Counter(1)) at (prev + 0, 11) to (start + 0, 46)
+- Code(Counter(1)) at (prev + 0, 20) to (start + 0, 34)
 - Code(Counter(3)) at (prev + 1, 34) to (start + 0, 39)
 - Code(Counter(2)) at (prev + 0, 44) to (start + 0, 46)
 - Code(Expression(1, Sub)) at (prev + 1, 14) to (start + 0, 20)
     = (c1 - c2)
 - Code(Counter(2)) at (prev + 3, 9) to (start + 0, 22)
-- Code(Counter(2)) at (prev + 8, 11) to (start + 0, 46)
+- Code(Counter(2)) at (prev + 8, 11) to (start + 0, 19)
+- Code(Counter(2)) at (prev + 0, 11) to (start + 0, 46)
+- Code(Counter(2)) at (prev + 0, 20) to (start + 0, 34)
 - Code(Counter(4)) at (prev + 1, 39) to (start + 0, 41)
 - Code(Expression(2, Sub)) at (prev + 1, 14) to (start + 0, 20)
     = (c2 - c4)
-- Code(Counter(4)) at (prev + 2, 11) to (start + 0, 46)
+- Code(Counter(4)) at (prev + 2, 11) to (start + 0, 19)
+- Code(Counter(4)) at (prev + 0, 11) to (start + 0, 46)
+- Code(Counter(4)) at (prev + 0, 20) to (start + 0, 34)
 - Code(Expression(4, Sub)) at (prev + 1, 39) to (start + 0, 41)
     = (c4 - c5)
 - Code(Counter(5)) at (prev + 1, 14) to (start + 0, 20)
@@ -33,24 +42,28 @@ Number of file 0 mappings: 16
 Highest counter ID seen: c5
 
 Function name: yield::main::{closure#0}
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 09, 08, 01, 10, 05, 02, 10, 01, 06]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 09, 08, 00, 09, 01, 01, 09, 00, 10, 05, 01, 10, 00, 15, 05, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/yield.rs
 Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 9, 8) to (start + 1, 16)
-- Code(Counter(1)) at (prev + 2, 16) to (start + 1, 6)
+Number of file 0 mappings: 4
+- Code(Counter(0)) at (prev + 9, 8) to (start + 0, 9)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 1, 16) to (start + 0, 21)
+- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: c1
 
 Function name: yield::main::{closure#1}
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 18, 08, 01, 10, 05, 02, 09, 00, 10, 09, 01, 09, 00, 10, 0d, 01, 10, 01, 06]
+Raw bytes (34): 0x[01, 01, 00, 06, 01, 18, 08, 00, 09, 01, 01, 09, 00, 10, 05, 01, 09, 00, 10, 09, 01, 09, 00, 10, 0d, 01, 10, 00, 15, 0d, 01, 05, 00, 06]
 Number of files: 1
-- file 0 => global file 1
+- file 0 => $DIR/yield.rs
 Number of expressions: 0
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 24, 8) to (start + 1, 16)
-- Code(Counter(1)) at (prev + 2, 9) to (start + 0, 16)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 24, 8) to (start + 0, 9)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 16)
 - Code(Counter(2)) at (prev + 1, 9) to (start + 0, 16)
-- Code(Counter(3)) at (prev + 1, 16) to (start + 1, 6)
+- Code(Counter(3)) at (prev + 1, 16) to (start + 0, 21)
+- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 6)
 Highest counter ID seen: c3
 
diff --git a/tests/crashes/127643.rs b/tests/crashes/127643.rs
index a4db9397bde..b5ec58b70e9 100644
--- a/tests/crashes/127643.rs
+++ b/tests/crashes/127643.rs
@@ -1,18 +1,18 @@
 //@ known-bug: #127643
 
-#![feature(associated_const_equality)]
+#![feature(generic_const_items, associated_const_equality)]
+#![expect(incomplete_features)]
 
-fn user() -> impl Owner<dyn Sized, C = 0> {}
-
-trait Owner<K> {
-    const C: K;
-}
-impl<K: ConstDefault> Owner<K> for () {
-    const C: K = K::DEFAULT;
+trait Foo {
+    const ASSOC<const N: u32>: u32;
 }
 
-trait ConstDefault {
-    const DEFAULT: Self;
+impl Foo for () {
+    const ASSOC<const N: u32>: u32 = N;
 }
 
-fn main() {}
+fn bar<const N: u64, T: Foo<ASSOC<N> = { N }>>() {}
+
+fn main() {
+    bar::<10_u64, ()>();
+}
diff --git a/tests/crashes/131758.rs b/tests/crashes/131758.rs
deleted file mode 100644
index 942c5fd7a50..00000000000
--- a/tests/crashes/131758.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-//@ known-bug: #131758
-#![feature(unboxed_closures)]
-trait Foo {}
-
-impl<T: Fn<(i32,)>> Foo for T {}
-
-fn baz<T: Foo>(_: T) {}
-
-fn main() {
-    baz(|x| ());
-}
diff --git a/tests/crashes/133066.rs b/tests/crashes/133066.rs
deleted file mode 100644
index 732ebb7079f..00000000000
--- a/tests/crashes/133066.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//@ known-bug: #133066
-trait Owner {
-    const C<const N: u32>: u32;
-}
-
-impl Owner for () {;}
-
-fn take0<const N: u64>(_: impl Owner<C<N> = { N }>) {}
-
-fn main() {
-    take0::<f32, >(());
-}
diff --git a/tests/debuginfo/step-into-match.rs b/tests/debuginfo/step-into-match.rs
index 577e553c119..d4b7ea20119 100644
--- a/tests/debuginfo/step-into-match.rs
+++ b/tests/debuginfo/step-into-match.rs
@@ -1,6 +1,10 @@
 //@ compile-flags: -g
 //@ ignore-android: FIXME(#10381)
 
+// On Arm64 Windows, stepping at the end of a function on goes to the callsite, not the instruction
+// after it.
+//@ ignore-aarch64-pc-windows-msvc: Stepping out of functions behaves differently.
+
 // === GDB TESTS ==============================================================
 
 // gdb-command: r
diff --git a/tests/debuginfo/type-names.rs b/tests/debuginfo/type-names.rs
index 4df6daf7b6e..3c7eab7e8d7 100644
--- a/tests/debuginfo/type-names.rs
+++ b/tests/debuginfo/type-names.rs
@@ -1,5 +1,7 @@
 //@ ignore-lldb
 
+//@ ignore-aarch64-pc-windows-msvc: Arm64 Windows cdb doesn't support JavaScript extensions.
+
 // GDB changed the way that it formatted Foreign types
 //@ min-gdb-version: 9.2
 
diff --git a/tests/incremental/circular-dependencies.rs b/tests/incremental/circular-dependencies.rs
index bd3b109b62c..c7b5b931fbb 100644
--- a/tests/incremental/circular-dependencies.rs
+++ b/tests/incremental/circular-dependencies.rs
@@ -15,7 +15,6 @@ pub struct Foo;
 
 pub fn consume_foo(_: Foo) {}
 //[cfail2]~^ NOTE function defined here
-//[cfail2]~| NOTE
 
 pub fn produce_foo() -> Foo {
     Foo
diff --git a/tests/incremental/ich_nested_items.rs b/tests/incremental/ich_nested_items.rs
index 19628e0bce1..c2a041ba268 100644
--- a/tests/incremental/ich_nested_items.rs
+++ b/tests/incremental/ich_nested_items.rs
@@ -7,6 +7,7 @@
 
 #![crate_type = "rlib"]
 #![feature(rustc_attrs)]
+#![allow(dead_code)]
 
 #[rustc_clean(except = "opt_hir_owner_nodes", cfg = "cfail2")]
 pub fn foo() {
diff --git a/tests/incremental/incremental_proc_macro.rs b/tests/incremental/incremental_proc_macro.rs
index 3cf89cae652..fc32aad5645 100644
--- a/tests/incremental/incremental_proc_macro.rs
+++ b/tests/incremental/incremental_proc_macro.rs
@@ -12,5 +12,5 @@ extern crate incremental_proc_macro_aux;
 
 #[derive(IncrementalMacro)]
 pub struct Foo {
-    x: u32
+    _x: u32
 }
diff --git a/tests/incremental/issue-49595/issue-49595.rs b/tests/incremental/issue-49595/issue-49595.rs
index a291188f746..7fe843135df 100644
--- a/tests/incremental/issue-49595/issue-49595.rs
+++ b/tests/incremental/issue-49595/issue-49595.rs
@@ -10,7 +10,7 @@
 
 mod tests {
     #[cfg_attr(not(cfail1), test)]
-    fn test() {
+    fn _test() {
     }
 }
 
diff --git a/tests/incremental/issue-84252-global-alloc.rs b/tests/incremental/issue-84252-global-alloc.rs
index 8dc611df9d8..cd2cb2313bd 100644
--- a/tests/incremental/issue-84252-global-alloc.rs
+++ b/tests/incremental/issue-84252-global-alloc.rs
@@ -1,5 +1,6 @@
 //@ revisions: cfail1 cfail2
 //@ build-pass
+//@ needs-crate-type: cdylib
 
 #![crate_type="lib"]
 #![crate_type="cdylib"]
diff --git a/tests/incremental/issue-85360-eval-obligation-ice.rs b/tests/incremental/issue-85360-eval-obligation-ice.rs
index 70bb43f39ec..2148e45bb38 100644
--- a/tests/incremental/issue-85360-eval-obligation-ice.rs
+++ b/tests/incremental/issue-85360-eval-obligation-ice.rs
@@ -4,6 +4,8 @@
 //@ edition: 2021
 //@ build-pass
 
+#![allow(dead_code)]
+
 use core::any::Any;
 use core::marker::PhantomData;
 
diff --git a/tests/incremental/no_mangle.rs b/tests/incremental/no_mangle.rs
index 1a01a40113a..36b82a7b863 100644
--- a/tests/incremental/no_mangle.rs
+++ b/tests/incremental/no_mangle.rs
@@ -1,6 +1,7 @@
 //@ revisions:cfail1 cfail2
 //@ check-pass
 //@ compile-flags: --crate-type cdylib
+//@ needs-crate-type: cdylib
 
 #![deny(unused_attributes)]
 
diff --git a/tests/incremental/thinlto/cgu_keeps_identical_fn.rs b/tests/incremental/thinlto/cgu_keeps_identical_fn.rs
index 5751759223b..d124a3498c4 100644
--- a/tests/incremental/thinlto/cgu_keeps_identical_fn.rs
+++ b/tests/incremental/thinlto/cgu_keeps_identical_fn.rs
@@ -33,12 +33,12 @@
 mod foo {
 
     // Trivial functions like this one are imported very reliably by ThinLTO.
-    #[cfg(any(cfail1, cfail4))]
+    #[cfg(cfail1)]
     pub fn inlined_fn() -> u32 {
         1234
     }
 
-    #[cfg(not(any(cfail1, cfail4)))]
+    #[cfg(not(cfail1))]
     pub fn inlined_fn() -> u32 {
         1234
     }
diff --git a/tests/incremental/unrecoverable_query.rs b/tests/incremental/unrecoverable_query.rs
index e17236bebd2..798a418f799 100644
--- a/tests/incremental/unrecoverable_query.rs
+++ b/tests/incremental/unrecoverable_query.rs
@@ -8,6 +8,8 @@
 //@ compile-flags: --crate-type=lib
 //@ build-pass
 
+#![allow(dead_code)]
+
 pub trait P {
     type A;
 }
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 542b70bcee9..d465b8bded2 100644
--- a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff
@@ -26,11 +26,20 @@
           debug a => _9;
       }
   
-+     coverage Code { bcb: bcb0 } => $DIR/branch_match_arms.rs:14:1: 15:21 (#0);
-+     coverage Code { bcb: bcb1 } => $DIR/branch_match_arms.rs:16:17: 16:32 (#0);
-+     coverage Code { bcb: bcb3 } => $DIR/branch_match_arms.rs:17:17: 17:32 (#0);
-+     coverage Code { bcb: bcb4 } => $DIR/branch_match_arms.rs:18:17: 18:32 (#0);
-+     coverage Code { bcb: bcb5 } => $DIR/branch_match_arms.rs:19:17: 19:32 (#0);
++     coverage Code { bcb: bcb0 } => $DIR/branch_match_arms.rs:14:1: 14:10 (#0);
++     coverage Code { bcb: bcb0 } => $DIR/branch_match_arms.rs:15:11: 15:21 (#0);
++     coverage Code { bcb: bcb1 } => $DIR/branch_match_arms.rs:16:17: 16:18 (#0);
++     coverage Code { bcb: bcb1 } => $DIR/branch_match_arms.rs:16:23: 16:30 (#0);
++     coverage Code { bcb: bcb1 } => $DIR/branch_match_arms.rs:16:31: 16:32 (#0);
++     coverage Code { bcb: bcb3 } => $DIR/branch_match_arms.rs:17:17: 17:18 (#0);
++     coverage Code { bcb: bcb3 } => $DIR/branch_match_arms.rs:17:23: 17:30 (#0);
++     coverage Code { bcb: bcb3 } => $DIR/branch_match_arms.rs:17:31: 17:32 (#0);
++     coverage Code { bcb: bcb4 } => $DIR/branch_match_arms.rs:18:17: 18:18 (#0);
++     coverage Code { bcb: bcb4 } => $DIR/branch_match_arms.rs:18:23: 18:30 (#0);
++     coverage Code { bcb: bcb4 } => $DIR/branch_match_arms.rs:18:31: 18:32 (#0);
++     coverage Code { bcb: bcb5 } => $DIR/branch_match_arms.rs:19:17: 19:18 (#0);
++     coverage Code { bcb: bcb5 } => $DIR/branch_match_arms.rs:19:23: 19:30 (#0);
++     coverage Code { bcb: bcb5 } => $DIR/branch_match_arms.rs:19:31: 19:32 (#0);
 +     coverage Code { bcb: bcb2 } => $DIR/branch_match_arms.rs:21:2: 21:2 (#0);
 + 
       bb0: {
diff --git a/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff
index 06e5f011c76..cf6d85abd80 100644
--- a/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff
@@ -4,7 +4,9 @@
   fn bar() -> bool {
       let mut _0: bool;
   
-+     coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:27:1: 29:2 (#0);
++     coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:27:1: 27:17 (#0);
++     coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:28:5: 28:9 (#0);
++     coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:29:2: 29:2 (#0);
 + 
       bb0: {
 +         Coverage::VirtualCounter(bcb0);
diff --git a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
index 30de92f3b86..980c5e202ff 100644
--- a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
@@ -7,7 +7,7 @@
       let mut _2: bool;
       let mut _3: !;
   
-+     coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:13:1: 13:11 (#0);
++     coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:13:1: 13:10 (#0);
 +     coverage Code { bcb: bcb1 } => $DIR/instrument_coverage.rs:15:12: 15:15 (#0);
 +     coverage Code { bcb: bcb2 } => $DIR/instrument_coverage.rs:16:13: 16:18 (#0);
 +     coverage Code { bcb: bcb3 } => $DIR/instrument_coverage.rs:17:10: 17:10 (#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 1a22adeba6f..b707cd41788 100644
--- a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff
+++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff
@@ -7,7 +7,8 @@
   
       coverage branch { true: BlockMarkerId(0), false: BlockMarkerId(1) } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0)
   
-      coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:13:1: 14:36 (#0);
+      coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:13:1: 13:10 (#0);
+      coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0);
       coverage Code { bcb: bcb3 } => $DIR/instrument_coverage_cleanup.rs:14:37: 14:39 (#0);
       coverage Code { bcb: bcb1 } => $DIR/instrument_coverage_cleanup.rs:14:39: 14:39 (#0);
       coverage Code { bcb: bcb2 } => $DIR/instrument_coverage_cleanup.rs:15:2: 15:2 (#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 b77969a3e16..239b845c231 100644
--- a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff
@@ -7,7 +7,8 @@
   
       coverage branch { true: BlockMarkerId(0), false: BlockMarkerId(1) } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0)
   
-+     coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:13:1: 14:36 (#0);
++     coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:13:1: 13:10 (#0);
++     coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0);
 +     coverage Code { bcb: bcb3 } => $DIR/instrument_coverage_cleanup.rs:14:37: 14:39 (#0);
 +     coverage Code { bcb: bcb1 } => $DIR/instrument_coverage_cleanup.rs:14:39: 14:39 (#0);
 +     coverage Code { bcb: bcb2 } => $DIR/instrument_coverage_cleanup.rs:15:2: 15:2 (#0);
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff
index f36157a762c..39ba480d203 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff
@@ -8,9 +8,9 @@
       let mut _3: u16;
       let mut _4: u32;
 +     scope 1 (inlined core::num::<impl u16>::unchecked_shl) {
-+         let mut _5: bool;
-+         let _6: ();
++         let _5: ();
 +         scope 2 (inlined core::ub_checks::check_language_ub) {
++             let mut _6: bool;
 +             scope 3 (inlined core::ub_checks::check_language_ub::runtime) {
 +             }
 +         }
@@ -22,20 +22,20 @@
           StorageLive(_4);
           _4 = copy _2;
 -         _0 = core::num::<impl u16>::unchecked_shl(move _3, move _4) -> [return: bb1, unwind unreachable];
-+         StorageLive(_6);
 +         StorageLive(_5);
-+         _5 = UbChecks();
-+         switchInt(move _5) -> [0: bb2, otherwise: bb1];
++         StorageLive(_6);
++         _6 = UbChecks();
++         switchInt(copy _6) -> [0: bb2, otherwise: bb1];
       }
   
       bb1: {
-+         _6 = core::num::<impl u16>::unchecked_shl::precondition_check(copy _4) -> [return: bb2, unwind unreachable];
++         _5 = core::num::<impl u16>::unchecked_shl::precondition_check(copy _4) -> [return: bb2, unwind unreachable];
 +     }
 + 
 +     bb2: {
-+         StorageDead(_5);
 +         _0 = ShlUnchecked(copy _3, copy _4);
 +         StorageDead(_6);
++         StorageDead(_5);
           StorageDead(_4);
           StorageDead(_3);
           return;
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff
index be1b066c6c1..5a758d35740 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff
@@ -8,9 +8,9 @@
       let mut _3: u16;
       let mut _4: u32;
 +     scope 1 (inlined core::num::<impl u16>::unchecked_shl) {
-+         let mut _5: bool;
-+         let _6: ();
++         let _5: ();
 +         scope 2 (inlined core::ub_checks::check_language_ub) {
++             let mut _6: bool;
 +             scope 3 (inlined core::ub_checks::check_language_ub::runtime) {
 +             }
 +         }
@@ -22,20 +22,20 @@
           StorageLive(_4);
           _4 = copy _2;
 -         _0 = core::num::<impl u16>::unchecked_shl(move _3, move _4) -> [return: bb1, unwind continue];
-+         StorageLive(_6);
 +         StorageLive(_5);
-+         _5 = UbChecks();
-+         switchInt(move _5) -> [0: bb2, otherwise: bb1];
++         StorageLive(_6);
++         _6 = UbChecks();
++         switchInt(copy _6) -> [0: bb2, otherwise: bb1];
       }
   
       bb1: {
-+         _6 = core::num::<impl u16>::unchecked_shl::precondition_check(copy _4) -> [return: bb2, unwind unreachable];
++         _5 = core::num::<impl u16>::unchecked_shl::precondition_check(copy _4) -> [return: bb2, unwind unreachable];
 +     }
 + 
 +     bb2: {
-+         StorageDead(_5);
 +         _0 = ShlUnchecked(copy _3, copy _4);
 +         StorageDead(_6);
++         StorageDead(_5);
           StorageDead(_4);
           StorageDead(_3);
           return;
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff
index 360687f3c4e..a0caf141f2d 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff
@@ -8,9 +8,9 @@
       let mut _3: i64;
       let mut _4: u32;
 +     scope 1 (inlined core::num::<impl i64>::unchecked_shr) {
-+         let mut _5: bool;
-+         let _6: ();
++         let _5: ();
 +         scope 2 (inlined core::ub_checks::check_language_ub) {
++             let mut _6: bool;
 +             scope 3 (inlined core::ub_checks::check_language_ub::runtime) {
 +             }
 +         }
@@ -22,20 +22,20 @@
           StorageLive(_4);
           _4 = copy _2;
 -         _0 = core::num::<impl i64>::unchecked_shr(move _3, move _4) -> [return: bb1, unwind unreachable];
-+         StorageLive(_6);
 +         StorageLive(_5);
-+         _5 = UbChecks();
-+         switchInt(move _5) -> [0: bb2, otherwise: bb1];
++         StorageLive(_6);
++         _6 = UbChecks();
++         switchInt(copy _6) -> [0: bb2, otherwise: bb1];
       }
   
       bb1: {
-+         _6 = core::num::<impl i64>::unchecked_shr::precondition_check(copy _4) -> [return: bb2, unwind unreachable];
++         _5 = core::num::<impl i64>::unchecked_shr::precondition_check(copy _4) -> [return: bb2, unwind unreachable];
 +     }
 + 
 +     bb2: {
-+         StorageDead(_5);
 +         _0 = ShrUnchecked(copy _3, copy _4);
 +         StorageDead(_6);
++         StorageDead(_5);
           StorageDead(_4);
           StorageDead(_3);
           return;
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff
index 986df55df03..633089e7b2a 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff
@@ -8,9 +8,9 @@
       let mut _3: i64;
       let mut _4: u32;
 +     scope 1 (inlined core::num::<impl i64>::unchecked_shr) {
-+         let mut _5: bool;
-+         let _6: ();
++         let _5: ();
 +         scope 2 (inlined core::ub_checks::check_language_ub) {
++             let mut _6: bool;
 +             scope 3 (inlined core::ub_checks::check_language_ub::runtime) {
 +             }
 +         }
@@ -22,20 +22,20 @@
           StorageLive(_4);
           _4 = copy _2;
 -         _0 = core::num::<impl i64>::unchecked_shr(move _3, move _4) -> [return: bb1, unwind continue];
-+         StorageLive(_6);
 +         StorageLive(_5);
-+         _5 = UbChecks();
-+         switchInt(move _5) -> [0: bb2, otherwise: bb1];
++         StorageLive(_6);
++         _6 = UbChecks();
++         switchInt(copy _6) -> [0: bb2, otherwise: bb1];
       }
   
       bb1: {
-+         _6 = core::num::<impl i64>::unchecked_shr::precondition_check(copy _4) -> [return: bb2, unwind unreachable];
++         _5 = core::num::<impl i64>::unchecked_shr::precondition_check(copy _4) -> [return: bb2, unwind unreachable];
 +     }
 + 
 +     bb2: {
-+         StorageDead(_5);
 +         _0 = ShrUnchecked(copy _3, copy _4);
 +         StorageDead(_6);
++         StorageDead(_5);
           StorageDead(_4);
           StorageDead(_3);
           return;
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff
index 28878736ed7..a5986a4315a 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff
@@ -10,9 +10,9 @@
 +         scope 2 {
 +         }
 +         scope 3 (inlined unreachable_unchecked) {
-+             let mut _4: bool;
-+             let _5: ();
++             let _4: ();
 +             scope 4 (inlined core::ub_checks::check_language_ub) {
++                 let mut _5: bool;
 +                 scope 5 (inlined core::ub_checks::check_language_ub::runtime) {
 +                 }
 +             }
@@ -24,7 +24,7 @@
           _2 = move _1;
 -         _0 = Option::<T>::unwrap_unchecked(move _2) -> [return: bb1, unwind unreachable];
 +         StorageLive(_3);
-+         StorageLive(_5);
++         StorageLive(_4);
 +         _3 = discriminant(_2);
 +         switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1];
       }
@@ -34,15 +34,15 @@
 +     }
 + 
 +     bb2: {
-+         StorageLive(_4);
-+         _4 = UbChecks();
-+         assume(copy _4);
-+         _5 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable];
++         StorageLive(_5);
++         _5 = UbChecks();
++         assume(copy _5);
++         _4 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable];
 +     }
 + 
 +     bb3: {
 +         _0 = move ((_2 as Some).0: T);
-+         StorageDead(_5);
++         StorageDead(_4);
 +         StorageDead(_3);
           StorageDead(_2);
           return;
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff
index 27b6bb6a5bb..12b03a6b6d9 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff
@@ -10,9 +10,9 @@
 +         scope 2 {
 +         }
 +         scope 3 (inlined unreachable_unchecked) {
-+             let mut _4: bool;
-+             let _5: ();
++             let _4: ();
 +             scope 4 (inlined core::ub_checks::check_language_ub) {
++                 let mut _5: bool;
 +                 scope 5 (inlined core::ub_checks::check_language_ub::runtime) {
 +                 }
 +             }
@@ -24,7 +24,7 @@
           _2 = move _1;
 -         _0 = Option::<T>::unwrap_unchecked(move _2) -> [return: bb1, unwind: bb2];
 +         StorageLive(_3);
-+         StorageLive(_5);
++         StorageLive(_4);
 +         _3 = discriminant(_2);
 +         switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1];
       }
@@ -38,15 +38,15 @@
 -     bb2 (cleanup): {
 -         resume;
 +     bb2: {
-+         StorageLive(_4);
-+         _4 = UbChecks();
-+         assume(copy _4);
-+         _5 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable];
++         StorageLive(_5);
++         _5 = UbChecks();
++         assume(copy _5);
++         _4 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable];
 +     }
 + 
 +     bb3: {
 +         _0 = move ((_2 as Some).0: T);
-+         StorageDead(_5);
++         StorageDead(_4);
 +         StorageDead(_3);
 +         StorageDead(_2);
 +         return;
diff --git a/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify-after-simplifycfg.diff b/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify-after-simplifycfg.diff
index 5fee9a6733d..82353a2d540 100644
--- a/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify-after-simplifycfg.diff
+++ b/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify-after-simplifycfg.diff
@@ -10,9 +10,9 @@
           scope 2 {
           }
           scope 3 (inlined unreachable_unchecked) {
-              let mut _4: bool;
-              let _5: ();
+              let _4: ();
               scope 4 (inlined core::ub_checks::check_language_ub) {
+                  let mut _5: bool;
                   scope 5 (inlined core::ub_checks::check_language_ub::runtime) {
                   }
               }
@@ -23,7 +23,7 @@
           StorageLive(_2);
           _2 = copy _1;
           StorageLive(_3);
-          StorageLive(_5);
+          StorageLive(_4);
           _3 = discriminant(_2);
           switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1];
       }
@@ -33,16 +33,16 @@
       }
   
       bb2: {
-          StorageLive(_4);
--         _4 = UbChecks();
-+         _4 = const false;
-          assume(copy _4);
-          _5 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable];
+          StorageLive(_5);
+-         _5 = UbChecks();
++         _5 = const false;
+          assume(copy _5);
+          _4 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable];
       }
   
       bb3: {
           _0 = move ((_2 as Some).0: i32);
-          StorageDead(_5);
+          StorageDead(_4);
           StorageDead(_3);
           StorageDead(_2);
           return;
diff --git a/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff b/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff
index 1ab9be96652..d8eace98d55 100644
--- a/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff
+++ b/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff
@@ -5,23 +5,18 @@
       debug bytes => _1;
       let mut _0: std::option::Option<[u8; 4]>;
       let _2: [u32; 4];
-      let mut _3: [u8; 16];
-      let mut _5: [u8; 4];
-      let mut _6: u32;
+      let mut _4: [u8; 4];
       scope 1 {
           debug dwords => _2;
           scope 2 {
-              debug ip => _4;
-              let _4: u32;
+              debug ip => _3;
+              let _3: u32;
           }
       }
   
       bb0: {
           StorageLive(_2);
-          StorageLive(_3);
-          _3 = copy _1;
-          _2 = move _3 as [u32; 4] (Transmute);
-          StorageDead(_3);
+          _2 = copy _1 as [u32; 4] (Transmute);
           switchInt(copy _2[0 of 4]) -> [0: bb1, otherwise: bb4];
       }
   
@@ -34,15 +29,10 @@
       }
   
       bb3: {
+          _3 = copy _2[3 of 4];
           StorageLive(_4);
-          _4 = copy _2[3 of 4];
-          StorageLive(_5);
-          StorageLive(_6);
-          _6 = copy _4;
-          _5 = move _6 as [u8; 4] (Transmute);
-          StorageDead(_6);
-          _0 = Option::<[u8; 4]>::Some(move _5);
-          StorageDead(_5);
+          _4 = copy _3 as [u8; 4] (Transmute);
+          _0 = Option::<[u8; 4]>::Some(move _4);
           StorageDead(_4);
           goto -> bb5;
       }
diff --git a/tests/mir-opt/pre-codegen/matchbr.match1.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/matchbr.match1.PreCodegen.after.mir
new file mode 100644
index 00000000000..3a202728ea9
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/matchbr.match1.PreCodegen.after.mir
@@ -0,0 +1,13 @@
+// MIR for `match1` after PreCodegen
+
+fn match1(_1: bool, _2: i32, _3: i32) -> i32 {
+    debug c => _1;
+    debug v1 => _2;
+    debug v2 => _3;
+    let mut _0: i32;
+
+    bb0: {
+        _0 = Sub(copy _2, copy _3);
+        return;
+    }
+}
diff --git a/tests/mir-opt/pre-codegen/matchbr.rs b/tests/mir-opt/pre-codegen/matchbr.rs
new file mode 100644
index 00000000000..1822739da2c
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/matchbr.rs
@@ -0,0 +1,10 @@
+#![crate_type = "lib"]
+
+// EMIT_MIR matchbr.match1.PreCodegen.after.mir
+pub fn match1(c: bool, v1: i32, v2: i32) -> i32 {
+    // CHECK-LABEL: fn match1(
+    // CHECK: bb0:
+    // CHECK-NEXT: _0 = Sub
+    // CHECK-NEXT: return;
+    if c { v1 - v2 } else { v1 - v2 }
+}
diff --git a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff
index c363dfcbf70..ff1bc58524b 100644
--- a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff
+++ b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff
@@ -8,6 +8,9 @@
       let mut _3: std::option::Option<T>;
       let mut _4: isize;
       let mut _5: isize;
+-     let mut _7: bool;
+-     let mut _8: u8;
+-     let mut _9: bool;
       scope 1 {
           debug a => _6;
           let _6: u8;
@@ -32,9 +35,7 @@
       }
   
       bb2: {
-          StorageLive(_6);
           _6 = copy (((_1.0: std::option::Option<u8>) as Some).0: u8);
-          StorageDead(_6);
           goto -> bb3;
       }
   
diff --git a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff
index 895b0067d2e..2c289c66475 100644
--- a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff
+++ b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff
@@ -8,6 +8,9 @@
       let mut _3: std::option::Option<T>;
       let mut _4: isize;
       let mut _5: isize;
+-     let mut _7: bool;
+-     let mut _8: u8;
+-     let mut _9: bool;
       scope 1 {
           debug a => _6;
           let _6: u8;
@@ -32,9 +35,7 @@
       }
   
       bb2: {
-          StorageLive(_6);
           _6 = copy (((_1.0: std::option::Option<u8>) as Some).0: u8);
-          StorageDead(_6);
           goto -> bb3;
       }
   
diff --git a/tests/pretty/hir-delegation.pp b/tests/pretty/hir-delegation.pp
index 872a6a45aed..e452cee6365 100644
--- a/tests/pretty/hir-delegation.pp
+++ b/tests/pretty/hir-delegation.pp
@@ -2,7 +2,8 @@
 //@ pretty-mode:hir
 //@ pp-exact:hir-delegation.pp
 
-#![allow(incomplete_features)]#![feature(fn_delegation)]
+#![allow(incomplete_features)]
+#![feature(fn_delegation)]
 #[prelude_import]
 use ::std::prelude::rust_2015::*;
 #[macro_use]
diff --git a/tests/run-make/arm64ec-import-export-static/export.rs b/tests/run-make/arm64ec-import-export-static/export.rs
new file mode 100644
index 00000000000..98b3a66d80c
--- /dev/null
+++ b/tests/run-make/arm64ec-import-export-static/export.rs
@@ -0,0 +1,23 @@
+#![crate_type = "dylib"]
+#![allow(internal_features)]
+#![feature(no_core, lang_items)]
+#![no_core]
+#![no_std]
+
+// This is needed because of #![no_core]:
+#[lang = "sized"]
+trait Sized {}
+#[lang = "sync"]
+trait Sync {}
+impl Sync for i32 {}
+#[lang = "copy"]
+pub trait Copy {}
+impl Copy for i32 {}
+#[lang = "drop_in_place"]
+pub unsafe fn drop_in_place<T: ?Sized>(_: *mut T) {}
+#[no_mangle]
+extern "system" fn _DllMainCRTStartup(_: *const u8, _: u32, _: *const u8) -> u32 {
+    1
+}
+
+pub static VALUE: i32 = 42;
diff --git a/tests/run-make/arm64ec-import-export-static/import.rs b/tests/run-make/arm64ec-import-export-static/import.rs
new file mode 100644
index 00000000000..9d52db25125
--- /dev/null
+++ b/tests/run-make/arm64ec-import-export-static/import.rs
@@ -0,0 +1,12 @@
+#![crate_type = "cdylib"]
+#![allow(internal_features)]
+#![feature(no_core)]
+#![no_std]
+#![no_core]
+
+extern crate export;
+
+#[no_mangle]
+pub extern "C" fn func() -> i32 {
+    export::VALUE
+}
diff --git a/tests/run-make/arm64ec-import-export-static/rmake.rs b/tests/run-make/arm64ec-import-export-static/rmake.rs
new file mode 100644
index 00000000000..7fa31144810
--- /dev/null
+++ b/tests/run-make/arm64ec-import-export-static/rmake.rs
@@ -0,0 +1,15 @@
+// Test that a static can be exported from one crate and imported into another.
+//
+// This was broken for Arm64EC as only functions, not variables, should be
+// decorated with `#`.
+// See https://github.com/rust-lang/rust/issues/138541
+
+//@ needs-llvm-components: aarch64
+//@ only-windows
+
+use run_make_support::rustc;
+
+fn main() {
+    rustc().input("export.rs").target("aarch64-pc-windows-msvc").panic("abort").run();
+    rustc().input("import.rs").target("aarch64-pc-windows-msvc").panic("abort").run();
+}
diff --git a/tests/run-make/export/compile-interface-error/app.rs b/tests/run-make/export/compile-interface-error/app.rs
new file mode 100644
index 00000000000..f619745a711
--- /dev/null
+++ b/tests/run-make/export/compile-interface-error/app.rs
@@ -0,0 +1,3 @@
+extern crate libr;
+
+fn main() {}
diff --git a/tests/run-make/export/compile-interface-error/liblibr.rs b/tests/run-make/export/compile-interface-error/liblibr.rs
new file mode 100644
index 00000000000..906d8d7be12
--- /dev/null
+++ b/tests/run-make/export/compile-interface-error/liblibr.rs
@@ -0,0 +1,5 @@
+#![feature(export_stable)]
+
+// interface file is broken(priv fn):
+#[export_stable]
+extern "C" fn foo();
diff --git a/tests/run-make/export/compile-interface-error/rmake.rs b/tests/run-make/export/compile-interface-error/rmake.rs
new file mode 100644
index 00000000000..89474e9d4fb
--- /dev/null
+++ b/tests/run-make/export/compile-interface-error/rmake.rs
@@ -0,0 +1,9 @@
+use run_make_support::rustc;
+
+fn main() {
+    // Do not produce the interface, use the broken one.
+    rustc()
+        .input("app.rs")
+        .run_fail()
+        .assert_stderr_contains("couldn't compile interface");
+}
diff --git a/tests/run-make/export/disambiguator/app.rs b/tests/run-make/export/disambiguator/app.rs
new file mode 100644
index 00000000000..27e0e2280e5
--- /dev/null
+++ b/tests/run-make/export/disambiguator/app.rs
@@ -0,0 +1,7 @@
+extern crate libr;
+
+use libr::*;
+
+fn main() {
+    assert_eq!(S::<S2>::foo(), 2);
+}
diff --git a/tests/run-make/export/disambiguator/libr.rs b/tests/run-make/export/disambiguator/libr.rs
new file mode 100644
index 00000000000..b294d5c9e8e
--- /dev/null
+++ b/tests/run-make/export/disambiguator/libr.rs
@@ -0,0 +1,27 @@
+// `S::<S2>::foo` and `S::<S1>::foo` have same `DefPath` modulo disambiguator.
+// `libr.rs` interface may not contain `S::<S1>::foo` as private items aren't
+// exportable. We should make sure that original `S::<S2>::foo` and the one
+// produced during interface generation have same mangled names.
+
+#![feature(export_stable)]
+#![crate_type = "sdylib"]
+
+#[export_stable]
+#[repr(C)]
+pub struct S<T>(pub T);
+
+struct S1;
+pub struct S2;
+
+impl S<S1> {
+    extern "C" fn foo() -> i32 {
+        1
+    }
+}
+
+#[export_stable]
+impl S<S2> {
+    pub extern "C" fn foo() -> i32 {
+        2
+    }
+}
diff --git a/tests/run-make/export/disambiguator/rmake.rs b/tests/run-make/export/disambiguator/rmake.rs
new file mode 100644
index 00000000000..743db1933fb
--- /dev/null
+++ b/tests/run-make/export/disambiguator/rmake.rs
@@ -0,0 +1,12 @@
+use run_make_support::rustc;
+
+fn main() {
+    rustc()
+        .env("RUSTC_FORCE_RUSTC_VERSION", "1")
+        .input("libr.rs")
+        .run();
+    rustc()
+        .env("RUSTC_FORCE_RUSTC_VERSION", "2")
+        .input("app.rs")
+        .run();
+}
diff --git a/tests/run-make/export/extern-opt/app.rs b/tests/run-make/export/extern-opt/app.rs
new file mode 100644
index 00000000000..765c9925d5f
--- /dev/null
+++ b/tests/run-make/export/extern-opt/app.rs
@@ -0,0 +1,6 @@
+extern crate libr;
+use libr::*;
+
+fn main() {
+    assert_eq!(foo(1), 1);
+}
diff --git a/tests/run-make/export/extern-opt/libinterface.rs b/tests/run-make/export/extern-opt/libinterface.rs
new file mode 100644
index 00000000000..313cfbe7d59
--- /dev/null
+++ b/tests/run-make/export/extern-opt/libinterface.rs
@@ -0,0 +1,4 @@
+#![feature(export_stable)]
+
+#[export_stable]
+pub extern "C" fn foo(x: i32) -> i32;
diff --git a/tests/run-make/export/extern-opt/libr.rs b/tests/run-make/export/extern-opt/libr.rs
new file mode 100644
index 00000000000..026ebb4233d
--- /dev/null
+++ b/tests/run-make/export/extern-opt/libr.rs
@@ -0,0 +1,5 @@
+#![feature(export_stable)]
+#![crate_type = "sdylib"]
+
+#[export_stable]
+pub extern "C" fn foo(x: i32) -> i32 { x }
diff --git a/tests/run-make/export/extern-opt/rmake.rs b/tests/run-make/export/extern-opt/rmake.rs
new file mode 100644
index 00000000000..821e2eb2149
--- /dev/null
+++ b/tests/run-make/export/extern-opt/rmake.rs
@@ -0,0 +1,23 @@
+use run_make_support::{rustc, dynamic_lib_name};
+
+fn main() {
+    rustc()
+        .env("RUSTC_FORCE_RUSTC_VERSION", "1")
+        .input("libr.rs")
+        .run();
+
+    rustc()
+        .env("RUSTC_FORCE_RUSTC_VERSION", "2")
+        .input("app.rs")
+        .extern_("libr", "libinterface.rs")
+        .extern_("libr", dynamic_lib_name("libr"))
+        .run();
+
+    rustc()
+        .env("RUSTC_FORCE_RUSTC_VERSION", "2")
+        .input("app.rs")
+        .extern_("libr", "interface.rs") // wrong interface format
+        .extern_("libr", dynamic_lib_name("libr"))
+        .run_fail()
+        .assert_stderr_contains("extern location for libr does not exist");
+}
diff --git a/tests/run-make/export/simple/app.rs b/tests/run-make/export/simple/app.rs
new file mode 100644
index 00000000000..ba34bdd7b56
--- /dev/null
+++ b/tests/run-make/export/simple/app.rs
@@ -0,0 +1,8 @@
+extern crate libr;
+use libr::*;
+
+fn main() {
+    let s = m::S { x: 42 };
+    assert_eq!(m::foo1(s), 42);
+    assert_eq!(m::S::foo2(1), 1);
+}
diff --git a/tests/run-make/export/simple/libr.rs b/tests/run-make/export/simple/libr.rs
new file mode 100644
index 00000000000..e10b76a6e52
--- /dev/null
+++ b/tests/run-make/export/simple/libr.rs
@@ -0,0 +1,22 @@
+#![feature(export_stable)]
+#![crate_type = "sdylib"]
+
+#[export_stable]
+pub mod m {
+    #[repr(C)]
+    pub struct S {
+        pub x: i32,
+    }
+
+    pub extern "C" fn foo1(x: S) -> i32 {
+        x.x
+    }
+
+    pub type Integer = i32;
+
+    impl S {
+        pub extern "C" fn foo2(x: Integer) -> Integer {
+            x
+        }
+    }
+}
diff --git a/tests/run-make/export/simple/rmake.rs b/tests/run-make/export/simple/rmake.rs
new file mode 100644
index 00000000000..743db1933fb
--- /dev/null
+++ b/tests/run-make/export/simple/rmake.rs
@@ -0,0 +1,12 @@
+use run_make_support::rustc;
+
+fn main() {
+    rustc()
+        .env("RUSTC_FORCE_RUSTC_VERSION", "1")
+        .input("libr.rs")
+        .run();
+    rustc()
+        .env("RUSTC_FORCE_RUSTC_VERSION", "2")
+        .input("app.rs")
+        .run();
+}
diff --git a/tests/run-make/pointer-auth-link-with-c/test.rs b/tests/run-make/pointer-auth-link-with-c/test.rs
index 1a3be80e898..795c6a45f8e 100644
--- a/tests/run-make/pointer-auth-link-with-c/test.rs
+++ b/tests/run-make/pointer-auth-link-with-c/test.rs
@@ -1,4 +1,4 @@
-#[link(name = "test")]
+#[link(name = "test", kind = "static")]
 extern "C" {
     fn foo() -> i32;
 }
diff --git a/tests/run-make/remap-path-prefix-dwarf/rmake.rs b/tests/run-make/remap-path-prefix-dwarf/rmake.rs
index ede1d615742..3d6ca014fc2 100644
--- a/tests/run-make/remap-path-prefix-dwarf/rmake.rs
+++ b/tests/run-make/remap-path-prefix-dwarf/rmake.rs
@@ -91,6 +91,59 @@ fn main() {
         )),
         dwarf_test: DwarfDump::ParentTest,
     });
+
+    check_dwarf_deps("macro", DwarfDump::AvoidSrcPath);
+    check_dwarf_deps("diagnostics", DwarfDump::AvoidSrcPath);
+    check_dwarf_deps("macro,diagnostics", DwarfDump::AvoidSrcPath);
+    check_dwarf_deps("object", DwarfDump::ContainsSrcPath);
+}
+
+#[track_caller]
+fn check_dwarf_deps(scope: &str, dwarf_test: DwarfDump) {
+    // build some_value.rs
+    let mut rustc_sm = rustc();
+    rustc_sm.input(cwd().join("src/some_value.rs"));
+    rustc_sm.arg("-Cdebuginfo=2");
+    rustc_sm.arg(format!("-Zremap-path-scope={}", scope));
+    rustc_sm.arg("--remap-path-prefix");
+    rustc_sm.arg(format!("{}=/REMAPPED", cwd().display()));
+    rustc_sm.arg("-Csplit-debuginfo=off");
+    rustc_sm.run();
+
+    // build print_value.rs
+    let print_value_rlib = rust_lib_name(&format!("print_value.{scope}"));
+    let mut rustc_pv = rustc();
+    rustc_pv.input(cwd().join("src/print_value.rs"));
+    rustc_pv.output(&print_value_rlib);
+    rustc_pv.arg("-Cdebuginfo=2");
+    rustc_pv.arg(format!("-Zremap-path-scope={}", scope));
+    rustc_pv.arg("--remap-path-prefix");
+    rustc_pv.arg(format!("{}=/REMAPPED", cwd().display()));
+    rustc_pv.arg("-Csplit-debuginfo=off");
+    rustc_pv.run();
+
+    match dwarf_test {
+        DwarfDump::AvoidSrcPath => {
+            llvm_dwarfdump()
+                .input(print_value_rlib)
+                .run()
+                .assert_stdout_not_contains("REMAPPED/src/some_value.rs")
+                .assert_stdout_not_contains("REMAPPED/src/print_value.rs")
+                .assert_stdout_not_contains("REMAPPED/REMAPPED")
+                .assert_stdout_contains(cwd().join("src/some_value.rs").display().to_string())
+                .assert_stdout_contains(cwd().join("src/print_value.rs").display().to_string());
+        }
+        DwarfDump::ContainsSrcPath => {
+            llvm_dwarfdump()
+                .input(print_value_rlib)
+                .run()
+                .assert_stdout_contains("REMAPPED/src/some_value.rs")
+                .assert_stdout_contains("REMAPPED/src/print_value.rs")
+                .assert_stdout_not_contains(cwd().join("src/some_value.rs").display().to_string())
+                .assert_stdout_not_contains(cwd().join("src/print_value.rs").display().to_string());
+        }
+        _ => unreachable!(),
+    }
 }
 
 #[track_caller]
diff --git a/tests/run-make/remap-path-prefix-dwarf/src/print_value.rs b/tests/run-make/remap-path-prefix-dwarf/src/print_value.rs
new file mode 100644
index 00000000000..f7653025ba5
--- /dev/null
+++ b/tests/run-make/remap-path-prefix-dwarf/src/print_value.rs
@@ -0,0 +1,7 @@
+#![crate_type = "rlib"]
+
+extern crate some_value;
+
+pub fn print_value() {
+    println!("{}", some_value::get_some_value());
+}
diff --git a/tests/run-make/remap-path-prefix-dwarf/src/some_value.rs b/tests/run-make/remap-path-prefix-dwarf/src/some_value.rs
new file mode 100644
index 00000000000..aa95a1bdf73
--- /dev/null
+++ b/tests/run-make/remap-path-prefix-dwarf/src/some_value.rs
@@ -0,0 +1,6 @@
+#![crate_type = "rlib"]
+
+#[inline]
+pub fn get_some_value() -> i32 {
+    42
+}
diff --git a/tests/run-make/remap-path-prefix/rmake.rs b/tests/run-make/remap-path-prefix/rmake.rs
index aeb30e72d5b..b4f7f4769b5 100644
--- a/tests/run-make/remap-path-prefix/rmake.rs
+++ b/tests/run-make/remap-path-prefix/rmake.rs
@@ -47,10 +47,10 @@ fn main() {
 
     out_object.run();
     rmeta_contains("/the/aux/lib.rs");
-    rmeta_not_contains("auxiliary");
+    rmeta_contains("auxiliary");
     out_macro.run();
     rmeta_contains("/the/aux/lib.rs");
-    rmeta_not_contains("auxiliary");
+    rmeta_contains("auxiliary");
     out_diagobj.run();
     rmeta_contains("/the/aux/lib.rs");
     rmeta_not_contains("auxiliary");
@@ -58,6 +58,7 @@ fn main() {
 
 //FIXME(Oneirical): These could be generalized into run_make_support
 // helper functions.
+#[track_caller]
 fn rmeta_contains(expected: &str) {
     // Normalize to account for path differences in Windows.
     if !bstr::BString::from(rfs::read("liblib.rmeta")).replace(b"\\", b"/").contains_str(expected) {
@@ -69,6 +70,7 @@ fn rmeta_contains(expected: &str) {
     }
 }
 
+#[track_caller]
 fn rmeta_not_contains(expected: &str) {
     // Normalize to account for path differences in Windows.
     if bstr::BString::from(rfs::read("liblib.rmeta")).replace(b"\\", b"/").contains_str(expected) {
diff --git a/tests/run-make/rustdoc-tempdir-removal/compile-error.rs b/tests/run-make/rustdoc-tempdir-removal/compile-error.rs
new file mode 100644
index 00000000000..66a3b3f270b
--- /dev/null
+++ b/tests/run-make/rustdoc-tempdir-removal/compile-error.rs
@@ -0,0 +1,5 @@
+#![doc(test(attr(deny(warnings))))]
+
+//! ```
+//! let a = 12;
+//! ```
diff --git a/tests/run-make/rustdoc-tempdir-removal/rmake.rs b/tests/run-make/rustdoc-tempdir-removal/rmake.rs
new file mode 100644
index 00000000000..9ad369ae5b1
--- /dev/null
+++ b/tests/run-make/rustdoc-tempdir-removal/rmake.rs
@@ -0,0 +1,42 @@
+// This test ensures that no temporary folder is "left behind" when doctests fail for any reason.
+
+//@ ignore-cross-compile
+
+use std::path::Path;
+
+use run_make_support::{path, rfs, rustdoc};
+
+fn run_doctest_and_check_tmpdir(tmp_dir: &Path, doctest: &str, edition: &str) {
+    let mut runner = rustdoc();
+    runner.input(doctest).arg("--test").edition(edition);
+    let output = if cfg!(unix) {
+        runner.env("TMPDIR", tmp_dir)
+    } else if cfg!(windows) {
+        runner.env("TEMP", tmp_dir).env("TMP", tmp_dir)
+    } else {
+        panic!("unsupported OS")
+    }
+    .run_fail();
+
+    output.assert_exit_code(101).assert_stdout_contains(
+        "test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out",
+    );
+
+    rfs::read_dir_entries(tmp_dir, |entry| {
+        panic!("Found an item inside the temporary folder: {entry:?}");
+    });
+}
+
+fn run_doctest_and_check_tmpdir_for_edition(tmp_dir: &Path, edition: &str) {
+    run_doctest_and_check_tmpdir(tmp_dir, "compile-error.rs", edition);
+    run_doctest_and_check_tmpdir(tmp_dir, "run-error.rs", edition);
+}
+
+fn main() {
+    let tmp_dir = path("tmp");
+    rfs::create_dir(&tmp_dir);
+
+    run_doctest_and_check_tmpdir_for_edition(&tmp_dir, "2018");
+    // We use the 2024 edition to check that it's also working for merged doctests.
+    run_doctest_and_check_tmpdir_for_edition(&tmp_dir, "2024");
+}
diff --git a/tests/run-make/rustdoc-tempdir-removal/run-error.rs b/tests/run-make/rustdoc-tempdir-removal/run-error.rs
new file mode 100644
index 00000000000..4ac95f6dd61
--- /dev/null
+++ b/tests/run-make/rustdoc-tempdir-removal/run-error.rs
@@ -0,0 +1,3 @@
+//! ```
+//! panic!();
+//! ```
diff --git a/tests/run-make/sanitizer-dylib-link/program.rs b/tests/run-make/sanitizer-dylib-link/program.rs
index 1026c7f89ba..dbf885d343f 100644
--- a/tests/run-make/sanitizer-dylib-link/program.rs
+++ b/tests/run-make/sanitizer-dylib-link/program.rs
@@ -1,4 +1,4 @@
-#[cfg_attr(windows, link(name = "library.dll.lib", modifiers = "+verbatim"))]
+#[cfg_attr(windows, link(name = "library", kind = "raw-dylib"))]
 #[cfg_attr(not(windows), link(name = "library"))]
 extern "C" {
     fn overflow();
diff --git a/tests/rustdoc-gui/sidebar.goml b/tests/rustdoc-gui/sidebar.goml
index 38160cc49d0..9c66b84165f 100644
--- a/tests/rustdoc-gui/sidebar.goml
+++ b/tests/rustdoc-gui/sidebar.goml
@@ -199,6 +199,42 @@ assert-position-false: (".sidebar-crate > h2 > a", {"x": -3})
 drag-and-drop: ((205, 100), (108, 100))
 assert-position: (".sidebar-crate > h2 > a", {"x": -3})
 
+// Check that the mobile sidebar and the source sidebar use the same icon.
+store-css: (".mobile-topbar .sidebar-menu-toggle::before", {"content": image_url})
+// Then we go to a source page.
+click: ".main-heading .src"
+assert-css: ("#sidebar-button a::before", {"content": |image_url|})
+// Check that hover events work as expected.
+store-css: ("#sidebar-button a", {"background-color": sidebar_background})
+move-cursor-to: "#sidebar-button a"
+store-css: ("#sidebar-button a:hover", {"background-color": sidebar_background_hover})
+assert: |sidebar_background| != |sidebar_background_hover|
+click: "#sidebar-button a"
+wait-for: "html.src-sidebar-expanded"
+assert-css: ("#sidebar-button a:hover", {"background-color": |sidebar_background_hover|})
+move-cursor-to: "#settings-menu"
+assert-css: ("#sidebar-button a:not(:hover)", {"background-color": |sidebar_background|})
+// Closing sidebar.
+click: "#sidebar-button a"
+wait-for: "html:not(.src-sidebar-expanded)"
+// Now we check the same when the sidebar button is moved alongside the search.
+set-window-size: (500, 500)
+store-css: ("#sidebar-button a:hover", {"background-color": not_sidebar_background_hover})
+move-cursor-to: "#settings-menu"
+store-css: ("#sidebar-button a:not(:hover)", {"background-color": not_sidebar_background})
+// The sidebar background is supposed to be the same as the main background.
+assert-css: ("body", {"background-color": |not_sidebar_background|})
+assert: |not_sidebar_background| != |not_sidebar_background_hover| && |not_sidebar_background| != |sidebar_background|
+// The hover background is supposed to be the same as the sidebar background.
+assert: |not_sidebar_background_hover| == |sidebar_background|
+click: "#sidebar-button a"
+wait-for: "html.src-sidebar-expanded"
+// And now the background colors are supposed to be the same as the sidebar since the sidebar has
+// been open.
+assert-css: ("#sidebar-button a:hover", {"background-color": |sidebar_background_hover|})
+move-cursor-to: "h2"
+assert-css: ("#sidebar-button a:not(:hover)", {"background-color": |sidebar_background|})
+
 // Configuration option to show TOC in sidebar.
 set-local-storage: {"rustdoc-hide-toc": "true"}
 go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
diff --git a/tests/rustdoc-js-std/path-maxeditdistance.js b/tests/rustdoc-js-std/path-maxeditdistance.js
index fd12a056496..6989e7d6488 100644
--- a/tests/rustdoc-js-std/path-maxeditdistance.js
+++ b/tests/rustdoc-js-std/path-maxeditdistance.js
@@ -13,9 +13,9 @@ const EXPECTED = [
             { 'path': 'std::vec', 'name': 'IntoIter' },
             { 'path': 'std::vec::Vec', 'name': 'from_iter' },
             { 'path': 'std::vec::Vec', 'name': 'into_iter' },
+            { 'path': 'std::vec::ExtractIf', '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::VecDeque', 'name': 'iter' },
             { 'path': 'std::collections::VecDeque', 'name': 'iter_mut' },
diff --git a/tests/rustdoc-ui/ice-bug-report-url.rs b/tests/rustdoc-ui/ice-bug-report-url.rs
index 9260644e44f..2e384fa1be6 100644
--- a/tests/rustdoc-ui/ice-bug-report-url.rs
+++ b/tests/rustdoc-ui/ice-bug-report-url.rs
@@ -1,8 +1,6 @@
 //@ compile-flags: -Ztreat-err-as-bug
 //@ rustc-env:RUSTC_ICE=0
 //@ failure-status: 101
-//@ error-pattern: aborting due to
-//@ error-pattern: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md
 
 //@ normalize-stderr: "note: compiler flags.*\n\n" -> ""
 //@ normalize-stderr: "note: rustc.*running on.*" -> "note: rustc {version} running on {platform}"
@@ -13,3 +11,6 @@
 
 fn wrong()
 //~^ ERROR expected one of
+
+//~? RAW aborting due to
+//~? RAW we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md
diff --git a/tests/rustdoc-ui/ice-bug-report-url.stderr b/tests/rustdoc-ui/ice-bug-report-url.stderr
index 14a961c2ce0..b6eb8a1792d 100644
--- a/tests/rustdoc-ui/ice-bug-report-url.stderr
+++ b/tests/rustdoc-ui/ice-bug-report-url.stderr
@@ -1,5 +1,5 @@
 error: internal compiler error: expected one of `->`, `where`, or `{`, found `<eof>`
-  --> $DIR/ice-bug-report-url.rs:14:10
+  --> $DIR/ice-bug-report-url.rs:12:10
    |
 LL | fn wrong()
    |          ^ expected one of `->`, `where`, or `{`
diff --git a/tests/rustdoc-ui/issues/issue-81662-shortness.rs b/tests/rustdoc-ui/issues/issue-81662-shortness.rs
index 8719442c34f..5d1951dbe3e 100644
--- a/tests/rustdoc-ui/issues/issue-81662-shortness.rs
+++ b/tests/rustdoc-ui/issues/issue-81662-shortness.rs
@@ -1,6 +1,5 @@
 //@ compile-flags:--test --error-format=short
 //@ check-stdout
-//@ error-pattern:cannot find function `foo`
 //@ normalize-stdout: "tests/rustdoc-ui/issues" -> "$$DIR"
 //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
 //@ failure-status: 101
@@ -11,3 +10,5 @@
 fn foo() {
     println!("Hello, world!");
 }
+
+//~? RAW cannot find function `foo`
diff --git a/tests/rustdoc-ui/issues/issue-81662-shortness.stdout b/tests/rustdoc-ui/issues/issue-81662-shortness.stdout
index 8fcc7ed272f..94a82cf0afc 100644
--- a/tests/rustdoc-ui/issues/issue-81662-shortness.stdout
+++ b/tests/rustdoc-ui/issues/issue-81662-shortness.stdout
@@ -1,16 +1,16 @@
 
 running 1 test
-test $DIR/issue-81662-shortness.rs - foo (line 8) ... FAILED
+test $DIR/issue-81662-shortness.rs - foo (line 7) ... FAILED
 
 failures:
 
----- $DIR/issue-81662-shortness.rs - foo (line 8) stdout ----
-$DIR/issue-81662-shortness.rs:9:1: error[E0425]: cannot find function `foo` in this scope: not found in this scope
+---- $DIR/issue-81662-shortness.rs - foo (line 7) stdout ----
+$DIR/issue-81662-shortness.rs:8:1: error[E0425]: cannot find function `foo` in this scope: not found in this scope
 error: aborting due to 1 previous error
 Couldn't compile the test.
 
 failures:
-    $DIR/issue-81662-shortness.rs - foo (line 8)
+    $DIR/issue-81662-shortness.rs - foo (line 7)
 
 test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
 
diff --git a/tests/rustdoc-ui/issues/issue-83883-describe-lints.rs b/tests/rustdoc-ui/issues/issue-83883-describe-lints.rs
index 35d2fda4585..62a0942df1b 100644
--- a/tests/rustdoc-ui/issues/issue-83883-describe-lints.rs
+++ b/tests/rustdoc-ui/issues/issue-83883-describe-lints.rs
@@ -1,10 +1,11 @@
 //@ compile-flags: -W help
 //@ check-pass
 //@ check-stdout
-//@ error-pattern:Lint checks provided
-//@ error-pattern:rustdoc::broken-intra-doc-links
 //
 // ignore-tidy-linelength
 //
 //@ normalize-stdout: "( +name  default  meaning\n +----  -------  -------\n)?( *[[:word:]:-]+  (allow  |warn   |deny   |forbid )  [^\n]+\n)+" -> "    $$NAMES  $$LEVELS  $$MEANINGS"
 //@ normalize-stdout: " +name  sub-lints\n +----  ---------\n( *[[:word:]:-]+  [^\n]+\n)+" -> "    $$NAMES  $$SUB_LINTS"
+
+//~? RAW Lint checks provided
+//~? RAW rustdoc::broken-intra-doc-links
diff --git a/tests/rustdoc-ui/unportable-markdown.rs b/tests/rustdoc-ui/unportable-markdown.rs
deleted file mode 100644
index 105fc1e59d5..00000000000
--- a/tests/rustdoc-ui/unportable-markdown.rs
+++ /dev/null
@@ -1,62 +0,0 @@
-// https://internals.rust-lang.org/t/proposal-migrate-the-syntax-of-rustdoc-markdown-footnotes-to-be-compatible-with-the-syntax-used-in-github/18929
-//
-// A series of test cases for CommonMark corner cases that pulldown-cmark 0.11 fixes.
-//
-// This version of the lint is targeted at two especially-common cases where docs got broken.
-// Other differences in parsing should not warn.
-#![allow(rustdoc::broken_intra_doc_links)]
-#![deny(rustdoc::unportable_markdown)]
-
-/// <https://github.com/pulldown-cmark/pulldown-cmark/pull/654>
-///
-/// Test footnote [^foot].
-///
-/// [^foot]: This is nested within the footnote now, but didn't used to be.
-///
-///     This is a multi-paragraph footnote.
-pub struct GfmFootnotes;
-
-/// <https://github.com/pulldown-cmark/pulldown-cmark/pull/773>
-///
-/// test [^foo][^bar]
-///
-/// [^foo]: test
-/// [^bar]: test2
-pub struct FootnoteSmashedName;
-
-/// <https://github.com/pulldown-cmark/pulldown-cmark/pull/829>
-///
-/// - _t
-///   # test
-///   t_
-pub struct NestingCornerCase;
-
-/// <https://github.com/pulldown-cmark/pulldown-cmark/pull/650>
-///
-/// *~~__emphasis strike strong__~~* ~~*__strike emphasis strong__*~~
-pub struct Emphasis1;
-
-/// <https://github.com/pulldown-cmark/pulldown-cmark/pull/732>
-///
-/// |
-/// |
-pub struct NotEnoughTable;
-
-/// <https://github.com/pulldown-cmark/pulldown-cmark/pull/675>
-///
-/// foo
-/// >bar
-//~^ ERROR unportable markdown
-pub struct BlockQuoteNoSpace;
-
-/// Negative test.
-///
-/// foo
-/// > bar
-pub struct BlockQuoteSpace;
-
-/// Negative test.
-///
-/// >bar
-/// baz
-pub struct BlockQuoteNoSpaceStart;
diff --git a/tests/rustdoc-ui/unportable-markdown.stderr b/tests/rustdoc-ui/unportable-markdown.stderr
deleted file mode 100644
index 952ae4bb6ee..00000000000
--- a/tests/rustdoc-ui/unportable-markdown.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error: unportable markdown
-  --> $DIR/unportable-markdown.rs:48:5
-   |
-LL | /// >bar
-   |     ^
-   |
-   = help: confusing block quote with no space after the `>` marker
-note: the lint level is defined here
-  --> $DIR/unportable-markdown.rs:8:9
-   |
-LL | #![deny(rustdoc::unportable_markdown)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: if the quote is intended, add a space
-   |
-LL | /// > bar
-   |      +
-help: if it should not be a quote, escape it
-   |
-LL | /// \>bar
-   |     +
-
-error: aborting due to 1 previous error
-
diff --git a/tests/rustdoc/anchor-id-duplicate-method-name-25001.rs b/tests/rustdoc/anchors/anchor-id-duplicate-method-name-25001.rs
index d7f4e587d5e..d7f4e587d5e 100644
--- a/tests/rustdoc/anchor-id-duplicate-method-name-25001.rs
+++ b/tests/rustdoc/anchors/anchor-id-duplicate-method-name-25001.rs
diff --git a/tests/rustdoc/anchor-id-trait-method-15169.rs b/tests/rustdoc/anchors/anchor-id-trait-method-15169.rs
index 19eeeaee9d1..19eeeaee9d1 100644
--- a/tests/rustdoc/anchor-id-trait-method-15169.rs
+++ b/tests/rustdoc/anchors/anchor-id-trait-method-15169.rs
diff --git a/tests/rustdoc/anchor-id-trait-tymethod-28478.rs b/tests/rustdoc/anchors/anchor-id-trait-tymethod-28478.rs
index e7adba7d06e..e7adba7d06e 100644
--- a/tests/rustdoc/anchor-id-trait-tymethod-28478.rs
+++ b/tests/rustdoc/anchors/anchor-id-trait-tymethod-28478.rs
diff --git a/tests/rustdoc/anchors.no_const_anchor.html b/tests/rustdoc/anchors/anchors.no_const_anchor.html
index 07a7507fa2e..07a7507fa2e 100644
--- a/tests/rustdoc/anchors.no_const_anchor.html
+++ b/tests/rustdoc/anchors/anchors.no_const_anchor.html
diff --git a/tests/rustdoc/anchors.no_const_anchor2.html b/tests/rustdoc/anchors/anchors.no_const_anchor2.html
index 091dac3e4b2..091dac3e4b2 100644
--- a/tests/rustdoc/anchors.no_const_anchor2.html
+++ b/tests/rustdoc/anchors/anchors.no_const_anchor2.html
diff --git a/tests/rustdoc/anchors.no_method_anchor.html b/tests/rustdoc/anchors/anchors.no_method_anchor.html
index 89f9898624c..89f9898624c 100644
--- a/tests/rustdoc/anchors.no_method_anchor.html
+++ b/tests/rustdoc/anchors/anchors.no_method_anchor.html
diff --git a/tests/rustdoc/anchors.no_trait_method_anchor.html b/tests/rustdoc/anchors/anchors.no_trait_method_anchor.html
index 51656a3e58f..51656a3e58f 100644
--- a/tests/rustdoc/anchors.no_trait_method_anchor.html
+++ b/tests/rustdoc/anchors/anchors.no_trait_method_anchor.html
diff --git a/tests/rustdoc/anchors.no_tymethod_anchor.html b/tests/rustdoc/anchors/anchors.no_tymethod_anchor.html
index 49ee624bdbc..49ee624bdbc 100644
--- a/tests/rustdoc/anchors.no_tymethod_anchor.html
+++ b/tests/rustdoc/anchors/anchors.no_tymethod_anchor.html
diff --git a/tests/rustdoc/anchors.no_type_anchor.html b/tests/rustdoc/anchors/anchors.no_type_anchor.html
index c5ac3c93818..c5ac3c93818 100644
--- a/tests/rustdoc/anchors.no_type_anchor.html
+++ b/tests/rustdoc/anchors/anchors.no_type_anchor.html
diff --git a/tests/rustdoc/anchors.no_type_anchor2.html b/tests/rustdoc/anchors/anchors.no_type_anchor2.html
index 14dd31d87b6..14dd31d87b6 100644
--- a/tests/rustdoc/anchors.no_type_anchor2.html
+++ b/tests/rustdoc/anchors/anchors.no_type_anchor2.html
diff --git a/tests/rustdoc/anchors.rs b/tests/rustdoc/anchors/anchors.rs
index 255ef87351c..255ef87351c 100644
--- a/tests/rustdoc/anchors.rs
+++ b/tests/rustdoc/anchors/anchors.rs
diff --git a/tests/rustdoc/auxiliary/issue-86620-1.rs b/tests/rustdoc/anchors/auxiliary/issue-86620-1.rs
index f6debf6fb4e..f6debf6fb4e 100644
--- a/tests/rustdoc/auxiliary/issue-86620-1.rs
+++ b/tests/rustdoc/anchors/auxiliary/issue-86620-1.rs
diff --git a/tests/rustdoc/disambiguate-anchors-32890.rs b/tests/rustdoc/anchors/disambiguate-anchors-32890.rs
index 0b726d5fba4..0b726d5fba4 100644
--- a/tests/rustdoc/disambiguate-anchors-32890.rs
+++ b/tests/rustdoc/anchors/disambiguate-anchors-32890.rs
diff --git a/tests/rustdoc/disambiguate-anchors-header-29449.rs b/tests/rustdoc/anchors/disambiguate-anchors-header-29449.rs
index feb0632775e..feb0632775e 100644
--- a/tests/rustdoc/disambiguate-anchors-header-29449.rs
+++ b/tests/rustdoc/anchors/disambiguate-anchors-header-29449.rs
diff --git a/tests/rustdoc/method-anchor-in-blanket-impl-86620.rs b/tests/rustdoc/anchors/method-anchor-in-blanket-impl-86620.rs
index 89e8712169a..89e8712169a 100644
--- a/tests/rustdoc/method-anchor-in-blanket-impl-86620.rs
+++ b/tests/rustdoc/anchors/method-anchor-in-blanket-impl-86620.rs
diff --git a/tests/rustdoc/trait-impl-items-links-and-anchors.rs b/tests/rustdoc/anchors/trait-impl-items-links-and-anchors.rs
index c1845a33b9d..c1845a33b9d 100644
--- a/tests/rustdoc/trait-impl-items-links-and-anchors.rs
+++ b/tests/rustdoc/anchors/trait-impl-items-links-and-anchors.rs
diff --git a/tests/rustdoc/assoc-fns.rs b/tests/rustdoc/assoc/assoc-fns.rs
index 6ffbebc3d27..6ffbebc3d27 100644
--- a/tests/rustdoc/assoc-fns.rs
+++ b/tests/rustdoc/assoc/assoc-fns.rs
diff --git a/tests/rustdoc/assoc-item-cast.rs b/tests/rustdoc/assoc/assoc-item-cast.rs
index 17b7cf6f0da..17b7cf6f0da 100644
--- a/tests/rustdoc/assoc-item-cast.rs
+++ b/tests/rustdoc/assoc/assoc-item-cast.rs
diff --git a/tests/rustdoc/assoc-type-bindings-20646.rs b/tests/rustdoc/assoc/assoc-type-bindings-20646.rs
index c79d07ff5bd..c79d07ff5bd 100644
--- a/tests/rustdoc/assoc-type-bindings-20646.rs
+++ b/tests/rustdoc/assoc/assoc-type-bindings-20646.rs
diff --git a/tests/rustdoc/assoc-types.rs b/tests/rustdoc/assoc/assoc-types.rs
index 8247d8b91e8..8247d8b91e8 100644
--- a/tests/rustdoc/assoc-types.rs
+++ b/tests/rustdoc/assoc/assoc-types.rs
diff --git a/tests/rustdoc/auxiliary/cross-crate-hidden-assoc-trait-items.rs b/tests/rustdoc/assoc/auxiliary/cross-crate-hidden-assoc-trait-items.rs
index 3baf8a6c07e..3baf8a6c07e 100644
--- a/tests/rustdoc/auxiliary/cross-crate-hidden-assoc-trait-items.rs
+++ b/tests/rustdoc/assoc/auxiliary/cross-crate-hidden-assoc-trait-items.rs
diff --git a/tests/rustdoc/auxiliary/issue-20646.rs b/tests/rustdoc/assoc/auxiliary/issue-20646.rs
index d1df1defb05..d1df1defb05 100644
--- a/tests/rustdoc/auxiliary/issue-20646.rs
+++ b/tests/rustdoc/assoc/auxiliary/issue-20646.rs
diff --git a/tests/rustdoc/auxiliary/issue-20727.rs b/tests/rustdoc/assoc/auxiliary/issue-20727.rs
index a102d1a4897..a102d1a4897 100644
--- a/tests/rustdoc/auxiliary/issue-20727.rs
+++ b/tests/rustdoc/assoc/auxiliary/issue-20727.rs
diff --git a/tests/rustdoc/auxiliary/normalize-assoc-item.rs b/tests/rustdoc/assoc/auxiliary/normalize-assoc-item.rs
index fbd111c3035..fbd111c3035 100644
--- a/tests/rustdoc/auxiliary/normalize-assoc-item.rs
+++ b/tests/rustdoc/assoc/auxiliary/normalize-assoc-item.rs
diff --git a/tests/rustdoc/cross-crate-hidden-assoc-trait-items.rs b/tests/rustdoc/assoc/cross-crate-hidden-assoc-trait-items.rs
index d3771c2e7a2..d3771c2e7a2 100644
--- a/tests/rustdoc/cross-crate-hidden-assoc-trait-items.rs
+++ b/tests/rustdoc/assoc/cross-crate-hidden-assoc-trait-items.rs
diff --git a/tests/rustdoc/doc-assoc-item.rs b/tests/rustdoc/assoc/doc-assoc-item.rs
index 2eb82abfc0b..2eb82abfc0b 100644
--- a/tests/rustdoc/doc-assoc-item.rs
+++ b/tests/rustdoc/assoc/doc-assoc-item.rs
diff --git a/tests/rustdoc/inline-assoc-type-20727-bindings.rs b/tests/rustdoc/assoc/inline-assoc-type-20727-bindings.rs
index b3447a759df..b3447a759df 100644
--- a/tests/rustdoc/inline-assoc-type-20727-bindings.rs
+++ b/tests/rustdoc/assoc/inline-assoc-type-20727-bindings.rs
diff --git a/tests/rustdoc/inline-assoc-type-20727-bounds-deref.rs b/tests/rustdoc/assoc/inline-assoc-type-20727-bounds-deref.rs
index afb9087cc7a..afb9087cc7a 100644
--- a/tests/rustdoc/inline-assoc-type-20727-bounds-deref.rs
+++ b/tests/rustdoc/assoc/inline-assoc-type-20727-bounds-deref.rs
diff --git a/tests/rustdoc/inline-assoc-type-20727-bounds-index.rs b/tests/rustdoc/assoc/inline-assoc-type-20727-bounds-index.rs
index 9dd234e8202..9dd234e8202 100644
--- a/tests/rustdoc/inline-assoc-type-20727-bounds-index.rs
+++ b/tests/rustdoc/assoc/inline-assoc-type-20727-bounds-index.rs
diff --git a/tests/rustdoc/inline-assoc-type-20727-bounds.rs b/tests/rustdoc/assoc/inline-assoc-type-20727-bounds.rs
index bd8d46f4a56..bd8d46f4a56 100644
--- a/tests/rustdoc/inline-assoc-type-20727-bounds.rs
+++ b/tests/rustdoc/assoc/inline-assoc-type-20727-bounds.rs
diff --git a/tests/rustdoc/normalize-assoc-item.rs b/tests/rustdoc/assoc/normalize-assoc-item.rs
index 7ef9d3067e1..7ef9d3067e1 100644
--- a/tests/rustdoc/normalize-assoc-item.rs
+++ b/tests/rustdoc/assoc/normalize-assoc-item.rs
diff --git a/tests/rustdoc/async-fn-opaque-item.rs b/tests/rustdoc/async/async-fn-opaque-item.rs
index d45183f96dd..d45183f96dd 100644
--- a/tests/rustdoc/async-fn-opaque-item.rs
+++ b/tests/rustdoc/async/async-fn-opaque-item.rs
diff --git a/tests/rustdoc/async-fn.rs b/tests/rustdoc/async/async-fn.rs
index 3d49766c55e..3d49766c55e 100644
--- a/tests/rustdoc/async-fn.rs
+++ b/tests/rustdoc/async/async-fn.rs
diff --git a/tests/rustdoc/async-move-doctest.rs b/tests/rustdoc/async/async-move-doctest.rs
index e18ec353533..e18ec353533 100644
--- a/tests/rustdoc/async-move-doctest.rs
+++ b/tests/rustdoc/async/async-move-doctest.rs
diff --git a/tests/rustdoc/async-trait-sig.rs b/tests/rustdoc/async/async-trait-sig.rs
index be790f6ed7f..be790f6ed7f 100644
--- a/tests/rustdoc/async-trait-sig.rs
+++ b/tests/rustdoc/async/async-trait-sig.rs
diff --git a/tests/rustdoc/async-trait.rs b/tests/rustdoc/async/async-trait.rs
index a6ee340e2dd..a6ee340e2dd 100644
--- a/tests/rustdoc/async-trait.rs
+++ b/tests/rustdoc/async/async-trait.rs
diff --git a/tests/rustdoc/auxiliary/async-trait-dep.rs b/tests/rustdoc/async/auxiliary/async-trait-dep.rs
index d89ec6d2998..d89ec6d2998 100644
--- a/tests/rustdoc/auxiliary/async-trait-dep.rs
+++ b/tests/rustdoc/async/auxiliary/async-trait-dep.rs
diff --git a/tests/rustdoc/auto-impl-for-trait.rs b/tests/rustdoc/auto/auto-impl-for-trait.rs
index bc658fbfc8c..bc658fbfc8c 100644
--- a/tests/rustdoc/auto-impl-for-trait.rs
+++ b/tests/rustdoc/auto/auto-impl-for-trait.rs
diff --git a/tests/rustdoc/auto-impl-primitive.rs b/tests/rustdoc/auto/auto-impl-primitive.rs
index 3dab02506ca..3dab02506ca 100644
--- a/tests/rustdoc/auto-impl-primitive.rs
+++ b/tests/rustdoc/auto/auto-impl-primitive.rs
diff --git a/tests/rustdoc/auto-trait-bounds-by-associated-type-50159.rs b/tests/rustdoc/auto/auto-trait-bounds-by-associated-type-50159.rs
index 2803c4da437..2803c4da437 100644
--- a/tests/rustdoc/auto-trait-bounds-by-associated-type-50159.rs
+++ b/tests/rustdoc/auto/auto-trait-bounds-by-associated-type-50159.rs
diff --git a/tests/rustdoc/auto-trait-bounds-inference-variables-54705.rs b/tests/rustdoc/auto/auto-trait-bounds-inference-variables-54705.rs
index ef159fca872..ef159fca872 100644
--- a/tests/rustdoc/auto-trait-bounds-inference-variables-54705.rs
+++ b/tests/rustdoc/auto/auto-trait-bounds-inference-variables-54705.rs
diff --git a/tests/rustdoc/auto-trait-bounds-where-51236.rs b/tests/rustdoc/auto/auto-trait-bounds-where-51236.rs
index c892b6d0abf..c892b6d0abf 100644
--- a/tests/rustdoc/auto-trait-bounds-where-51236.rs
+++ b/tests/rustdoc/auto/auto-trait-bounds-where-51236.rs
diff --git a/tests/rustdoc/auto-trait-negative-impl-55321.rs b/tests/rustdoc/auto/auto-trait-negative-impl-55321.rs
index 147f44da117..147f44da117 100644
--- a/tests/rustdoc/auto-trait-negative-impl-55321.rs
+++ b/tests/rustdoc/auto/auto-trait-negative-impl-55321.rs
diff --git a/tests/rustdoc/auto-trait-not-send.rs b/tests/rustdoc/auto/auto-trait-not-send.rs
index 0a31952f5e1..0a31952f5e1 100644
--- a/tests/rustdoc/auto-trait-not-send.rs
+++ b/tests/rustdoc/auto/auto-trait-not-send.rs
diff --git a/tests/rustdoc/auto-traits.rs b/tests/rustdoc/auto/auto-traits.rs
index dce406ed3e3..dce406ed3e3 100644
--- a/tests/rustdoc/auto-traits.rs
+++ b/tests/rustdoc/auto/auto-traits.rs
diff --git a/tests/rustdoc/auto_aliases.rs b/tests/rustdoc/auto/auto_aliases.rs
index 920aba805cd..920aba805cd 100644
--- a/tests/rustdoc/auto_aliases.rs
+++ b/tests/rustdoc/auto/auto_aliases.rs
diff --git a/tests/rustdoc/auxiliary/auto-traits.rs b/tests/rustdoc/auto/auxiliary/auto-traits.rs
index 84976c73bee..84976c73bee 100644
--- a/tests/rustdoc/auxiliary/auto-traits.rs
+++ b/tests/rustdoc/auto/auxiliary/auto-traits.rs
diff --git a/tests/rustdoc/assoc-consts-underscore.rs b/tests/rustdoc/constant/assoc-consts-underscore.rs
index f48098094db..f48098094db 100644
--- a/tests/rustdoc/assoc-consts-underscore.rs
+++ b/tests/rustdoc/constant/assoc-consts-underscore.rs
diff --git a/tests/rustdoc/assoc-consts-version.rs b/tests/rustdoc/constant/assoc-consts-version.rs
index db4d759acab..db4d759acab 100644
--- a/tests/rustdoc/assoc-consts-version.rs
+++ b/tests/rustdoc/constant/assoc-consts-version.rs
diff --git a/tests/rustdoc/assoc-consts.rs b/tests/rustdoc/constant/assoc-consts.rs
index 247b5b180a8..247b5b180a8 100644
--- a/tests/rustdoc/assoc-consts.rs
+++ b/tests/rustdoc/constant/assoc-consts.rs
diff --git a/tests/rustdoc/associated-consts.rs b/tests/rustdoc/constant/associated-consts.rs
index 2a7269a89be..2a7269a89be 100644
--- a/tests/rustdoc/associated-consts.rs
+++ b/tests/rustdoc/constant/associated-consts.rs
diff --git a/tests/rustdoc/const-display.rs b/tests/rustdoc/constant/const-display.rs
index bc4270c421d..bc4270c421d 100644
--- a/tests/rustdoc/const-display.rs
+++ b/tests/rustdoc/constant/const-display.rs
diff --git a/tests/rustdoc/const-doc.rs b/tests/rustdoc/constant/const-doc.rs
index f33083a267c..f33083a267c 100644
--- a/tests/rustdoc/const-doc.rs
+++ b/tests/rustdoc/constant/const-doc.rs
diff --git a/tests/rustdoc/const-effect-param.rs b/tests/rustdoc/constant/const-effect-param.rs
index cceb0adac30..cceb0adac30 100644
--- a/tests/rustdoc/const-effect-param.rs
+++ b/tests/rustdoc/constant/const-effect-param.rs
diff --git a/tests/rustdoc/const-underscore.rs b/tests/rustdoc/constant/const-underscore.rs
index fafc4b4e25c..fafc4b4e25c 100644
--- a/tests/rustdoc/const-underscore.rs
+++ b/tests/rustdoc/constant/const-underscore.rs
diff --git a/tests/rustdoc/const-value-display.rs b/tests/rustdoc/constant/const-value-display.rs
index 658978a3490..658978a3490 100644
--- a/tests/rustdoc/const-value-display.rs
+++ b/tests/rustdoc/constant/const-value-display.rs
diff --git a/tests/rustdoc/const.rs b/tests/rustdoc/constant/const.rs
index fe6a828505a..fe6a828505a 100644
--- a/tests/rustdoc/const.rs
+++ b/tests/rustdoc/constant/const.rs
diff --git a/tests/rustdoc/document-item-with-associated-const-in-where-clause.rs b/tests/rustdoc/constant/document-item-with-associated-const-in-where-clause.rs
index c9408ef3360..c9408ef3360 100644
--- a/tests/rustdoc/document-item-with-associated-const-in-where-clause.rs
+++ b/tests/rustdoc/constant/document-item-with-associated-const-in-where-clause.rs
diff --git a/tests/rustdoc/generic-const-items.rs b/tests/rustdoc/constant/generic-const-items.rs
index 31c300f2ff1..31c300f2ff1 100644
--- a/tests/rustdoc/generic-const-items.rs
+++ b/tests/rustdoc/constant/generic-const-items.rs
diff --git a/tests/rustdoc/generic_const_exprs.rs b/tests/rustdoc/constant/generic_const_exprs.rs
index 44f7bf5b24c..44f7bf5b24c 100644
--- a/tests/rustdoc/generic_const_exprs.rs
+++ b/tests/rustdoc/constant/generic_const_exprs.rs
diff --git a/tests/rustdoc/glob-shadowing-const.rs b/tests/rustdoc/constant/glob-shadowing-const.rs
index fbc22dbccaa..fbc22dbccaa 100644
--- a/tests/rustdoc/glob-shadowing-const.rs
+++ b/tests/rustdoc/constant/glob-shadowing-const.rs
diff --git a/tests/rustdoc/hide-complex-unevaluated-const-arguments.rs b/tests/rustdoc/constant/hide-complex-unevaluated-const-arguments.rs
index e94c1ea5c61..e94c1ea5c61 100644
--- a/tests/rustdoc/hide-complex-unevaluated-const-arguments.rs
+++ b/tests/rustdoc/constant/hide-complex-unevaluated-const-arguments.rs
diff --git a/tests/rustdoc/hide-complex-unevaluated-consts.rs b/tests/rustdoc/constant/hide-complex-unevaluated-consts.rs
index 61ae8c801dd..61ae8c801dd 100644
--- a/tests/rustdoc/hide-complex-unevaluated-consts.rs
+++ b/tests/rustdoc/constant/hide-complex-unevaluated-consts.rs
diff --git a/tests/rustdoc/ice-associated-const-equality-105952.rs b/tests/rustdoc/constant/ice-associated-const-equality-105952.rs
index 1bcdfac7342..1bcdfac7342 100644
--- a/tests/rustdoc/ice-associated-const-equality-105952.rs
+++ b/tests/rustdoc/constant/ice-associated-const-equality-105952.rs
diff --git a/tests/rustdoc/legacy-const-generic.rs b/tests/rustdoc/constant/legacy-const-generic.rs
index 41df535f3e0..41df535f3e0 100644
--- a/tests/rustdoc/legacy-const-generic.rs
+++ b/tests/rustdoc/constant/legacy-const-generic.rs
diff --git a/tests/rustdoc/link-assoc-const.rs b/tests/rustdoc/constant/link-assoc-const.rs
index 56b82fb2d39..56b82fb2d39 100644
--- a/tests/rustdoc/link-assoc-const.rs
+++ b/tests/rustdoc/constant/link-assoc-const.rs
diff --git a/tests/rustdoc/redirect-const.rs b/tests/rustdoc/constant/redirect-const.rs
index e636a915f30..e636a915f30 100644
--- a/tests/rustdoc/redirect-const.rs
+++ b/tests/rustdoc/constant/redirect-const.rs
diff --git a/tests/rustdoc/rfc-2632-const-trait-impl.rs b/tests/rustdoc/constant/rfc-2632-const-trait-impl.rs
index 8a86e3e5e97..8a86e3e5e97 100644
--- a/tests/rustdoc/rfc-2632-const-trait-impl.rs
+++ b/tests/rustdoc/constant/rfc-2632-const-trait-impl.rs
diff --git a/tests/rustdoc/show-const-contents.rs b/tests/rustdoc/constant/show-const-contents.rs
index 6d2701693ce..6d2701693ce 100644
--- a/tests/rustdoc/show-const-contents.rs
+++ b/tests/rustdoc/constant/show-const-contents.rs
diff --git a/tests/rustdoc/doc-cfg-hide.rs b/tests/rustdoc/doc-cfg/doc-cfg-hide.rs
index ceb1f99fae0..ceb1f99fae0 100644
--- a/tests/rustdoc/doc-cfg-hide.rs
+++ b/tests/rustdoc/doc-cfg/doc-cfg-hide.rs
diff --git a/tests/rustdoc/doc-cfg-implicit-gate.rs b/tests/rustdoc/doc-cfg/doc-cfg-implicit-gate.rs
index b5b8d0f427b..b5b8d0f427b 100644
--- a/tests/rustdoc/doc-cfg-implicit-gate.rs
+++ b/tests/rustdoc/doc-cfg/doc-cfg-implicit-gate.rs
diff --git a/tests/rustdoc/doc-cfg-implicit.rs b/tests/rustdoc/doc-cfg/doc-cfg-implicit.rs
index 69b10867ee3..69b10867ee3 100644
--- a/tests/rustdoc/doc-cfg-implicit.rs
+++ b/tests/rustdoc/doc-cfg/doc-cfg-implicit.rs
diff --git a/tests/rustdoc/doc-cfg-inherit-from-module-79201.rs b/tests/rustdoc/doc-cfg/doc-cfg-inherit-from-module-79201.rs
index 256e3b0015c..256e3b0015c 100644
--- a/tests/rustdoc/doc-cfg-inherit-from-module-79201.rs
+++ b/tests/rustdoc/doc-cfg/doc-cfg-inherit-from-module-79201.rs
diff --git a/tests/rustdoc/doc-cfg-simplification.rs b/tests/rustdoc/doc-cfg/doc-cfg-simplification.rs
index ce70de289c6..ce70de289c6 100644
--- a/tests/rustdoc/doc-cfg-simplification.rs
+++ b/tests/rustdoc/doc-cfg/doc-cfg-simplification.rs
diff --git a/tests/rustdoc/doc-cfg-target-feature.rs b/tests/rustdoc/doc-cfg/doc-cfg-target-feature.rs
index b66e86e36af..b66e86e36af 100644
--- a/tests/rustdoc/doc-cfg-target-feature.rs
+++ b/tests/rustdoc/doc-cfg/doc-cfg-target-feature.rs
diff --git a/tests/rustdoc/doc-cfg-traits.rs b/tests/rustdoc/doc-cfg/doc-cfg-traits.rs
index 1256a7ae2c1..1256a7ae2c1 100644
--- a/tests/rustdoc/doc-cfg-traits.rs
+++ b/tests/rustdoc/doc-cfg/doc-cfg-traits.rs
diff --git a/tests/rustdoc/doc-cfg.rs b/tests/rustdoc/doc-cfg/doc-cfg.rs
index 652c8419b4f..652c8419b4f 100644
--- a/tests/rustdoc/doc-cfg.rs
+++ b/tests/rustdoc/doc-cfg/doc-cfg.rs
diff --git a/tests/rustdoc/auxiliary/enum-variant.rs b/tests/rustdoc/enum/auxiliary/enum-variant.rs
index a0a7fd894f9..a0a7fd894f9 100644
--- a/tests/rustdoc/auxiliary/enum-variant.rs
+++ b/tests/rustdoc/enum/auxiliary/enum-variant.rs
diff --git a/tests/rustdoc/auxiliary/variant-struct.rs b/tests/rustdoc/enum/auxiliary/variant-struct.rs
index 0f3d2e5f1b7..0f3d2e5f1b7 100644
--- a/tests/rustdoc/auxiliary/variant-struct.rs
+++ b/tests/rustdoc/enum/auxiliary/variant-struct.rs
diff --git a/tests/rustdoc/enum-headings.rs b/tests/rustdoc/enum/enum-headings.rs
index 6deabf1cd9a..6deabf1cd9a 100644
--- a/tests/rustdoc/enum-headings.rs
+++ b/tests/rustdoc/enum/enum-headings.rs
diff --git a/tests/rustdoc/enum-non-exhaustive-108925.rs b/tests/rustdoc/enum/enum-non-exhaustive-108925.rs
index ea2462449d2..ea2462449d2 100644
--- a/tests/rustdoc/enum-non-exhaustive-108925.rs
+++ b/tests/rustdoc/enum/enum-non-exhaustive-108925.rs
diff --git a/tests/rustdoc/enum-variant-doc-hidden-field-88600.rs b/tests/rustdoc/enum/enum-variant-doc-hidden-field-88600.rs
index f1d461c66c3..f1d461c66c3 100644
--- a/tests/rustdoc/enum-variant-doc-hidden-field-88600.rs
+++ b/tests/rustdoc/enum/enum-variant-doc-hidden-field-88600.rs
diff --git a/tests/rustdoc/enum-variant-fields-heading.rs b/tests/rustdoc/enum/enum-variant-fields-heading.rs
index e210667d3c0..e210667d3c0 100644
--- a/tests/rustdoc/enum-variant-fields-heading.rs
+++ b/tests/rustdoc/enum/enum-variant-fields-heading.rs
diff --git a/tests/rustdoc/enum-variant-fields-heading.variants.html b/tests/rustdoc/enum/enum-variant-fields-heading.variants.html
index bcb36f7cf86..bcb36f7cf86 100644
--- a/tests/rustdoc/enum-variant-fields-heading.variants.html
+++ b/tests/rustdoc/enum/enum-variant-fields-heading.variants.html
diff --git a/tests/rustdoc/enum-variant-value.rs b/tests/rustdoc/enum/enum-variant-value.rs
index 1670de8a24f..1670de8a24f 100644
--- a/tests/rustdoc/enum-variant-value.rs
+++ b/tests/rustdoc/enum/enum-variant-value.rs
diff --git a/tests/rustdoc/render-enum-variant-structlike-32395.rs b/tests/rustdoc/enum/render-enum-variant-structlike-32395.rs
index d4cefb2911d..d4cefb2911d 100644
--- a/tests/rustdoc/render-enum-variant-structlike-32395.rs
+++ b/tests/rustdoc/enum/render-enum-variant-structlike-32395.rs
diff --git a/tests/rustdoc/strip-enum-variant.no-not-shown.html b/tests/rustdoc/enum/strip-enum-variant.no-not-shown.html
index d7a36cc631a..d7a36cc631a 100644
--- a/tests/rustdoc/strip-enum-variant.no-not-shown.html
+++ b/tests/rustdoc/enum/strip-enum-variant.no-not-shown.html
diff --git a/tests/rustdoc/strip-enum-variant.rs b/tests/rustdoc/enum/strip-enum-variant.rs
index 9874588ef59..9874588ef59 100644
--- a/tests/rustdoc/strip-enum-variant.rs
+++ b/tests/rustdoc/enum/strip-enum-variant.rs
diff --git a/tests/rustdoc/extern/auxiliary/empty.rs b/tests/rustdoc/extern/auxiliary/empty.rs
new file mode 100644
index 00000000000..d11c69f812a
--- /dev/null
+++ b/tests/rustdoc/extern/auxiliary/empty.rs
@@ -0,0 +1 @@
+// intentionally empty
diff --git a/tests/rustdoc/auxiliary/extern-links.rs b/tests/rustdoc/extern/auxiliary/extern-links.rs
index 4a835673a59..4a835673a59 100644
--- a/tests/rustdoc/auxiliary/extern-links.rs
+++ b/tests/rustdoc/extern/auxiliary/extern-links.rs
diff --git a/tests/rustdoc/auxiliary/external-cross-doc.md b/tests/rustdoc/extern/auxiliary/external-cross-doc.md
index d3c85326559..d3c85326559 100644
--- a/tests/rustdoc/auxiliary/external-cross-doc.md
+++ b/tests/rustdoc/extern/auxiliary/external-cross-doc.md
diff --git a/tests/rustdoc/auxiliary/external-cross.rs b/tests/rustdoc/extern/auxiliary/external-cross.rs
index 5de63cdabc6..5de63cdabc6 100644
--- a/tests/rustdoc/auxiliary/external-cross.rs
+++ b/tests/rustdoc/extern/auxiliary/external-cross.rs
diff --git a/tests/rustdoc/auxiliary/external-doc.md b/tests/rustdoc/extern/auxiliary/external-doc.md
index babde0a05ad..babde0a05ad 100644
--- a/tests/rustdoc/auxiliary/external-doc.md
+++ b/tests/rustdoc/extern/auxiliary/external-doc.md
diff --git a/tests/rustdoc/auxiliary/html_root.rs b/tests/rustdoc/extern/auxiliary/html_root.rs
index 4eb0b700f8f..4eb0b700f8f 100644
--- a/tests/rustdoc/auxiliary/html_root.rs
+++ b/tests/rustdoc/extern/auxiliary/html_root.rs
diff --git a/tests/rustdoc/auxiliary/issue-30109-1.rs b/tests/rustdoc/extern/auxiliary/issue-30109-1.rs
index ca05a6a9076..ca05a6a9076 100644
--- a/tests/rustdoc/auxiliary/issue-30109-1.rs
+++ b/tests/rustdoc/extern/auxiliary/issue-30109-1.rs
diff --git a/tests/rustdoc/auxiliary/no_html_root.rs b/tests/rustdoc/extern/auxiliary/no_html_root.rs
index c5c0bc606cd..c5c0bc606cd 100644
--- a/tests/rustdoc/auxiliary/no_html_root.rs
+++ b/tests/rustdoc/extern/auxiliary/no_html_root.rs
diff --git a/tests/rustdoc/auxiliary/panic-item.rs b/tests/rustdoc/extern/auxiliary/panic-item.rs
index ccf784f7284..ccf784f7284 100644
--- a/tests/rustdoc/auxiliary/panic-item.rs
+++ b/tests/rustdoc/extern/auxiliary/panic-item.rs
diff --git a/tests/rustdoc/auxiliary/pub-extern-crate.rs b/tests/rustdoc/extern/auxiliary/pub-extern-crate.rs
index 8c89c8d6c76..8c89c8d6c76 100644
--- a/tests/rustdoc/auxiliary/pub-extern-crate.rs
+++ b/tests/rustdoc/extern/auxiliary/pub-extern-crate.rs
diff --git a/tests/rustdoc/auxiliary/rustdoc-extern-default-method.rs b/tests/rustdoc/extern/auxiliary/rustdoc-extern-default-method.rs
index 12934238a8e..12934238a8e 100644
--- a/tests/rustdoc/auxiliary/rustdoc-extern-default-method.rs
+++ b/tests/rustdoc/extern/auxiliary/rustdoc-extern-default-method.rs
diff --git a/tests/rustdoc/auxiliary/rustdoc-extern-method.rs b/tests/rustdoc/extern/auxiliary/rustdoc-extern-method.rs
index e493048d9da..e493048d9da 100644
--- a/tests/rustdoc/auxiliary/rustdoc-extern-method.rs
+++ b/tests/rustdoc/extern/auxiliary/rustdoc-extern-method.rs
diff --git a/tests/rustdoc/extern/auxiliary/variant-struct.rs b/tests/rustdoc/extern/auxiliary/variant-struct.rs
new file mode 100644
index 00000000000..0f3d2e5f1b7
--- /dev/null
+++ b/tests/rustdoc/extern/auxiliary/variant-struct.rs
@@ -0,0 +1,5 @@
+pub enum Foo {
+    Bar {
+        qux: (),
+    }
+}
diff --git a/tests/rustdoc/extern-default-method.no_href_on_anchor.html b/tests/rustdoc/extern/extern-default-method.no_href_on_anchor.html
index ef14836ccb8..ef14836ccb8 100644
--- a/tests/rustdoc/extern-default-method.no_href_on_anchor.html
+++ b/tests/rustdoc/extern/extern-default-method.no_href_on_anchor.html
diff --git a/tests/rustdoc/extern-default-method.rs b/tests/rustdoc/extern/extern-default-method.rs
index 1af9fab152e..1af9fab152e 100644
--- a/tests/rustdoc/extern-default-method.rs
+++ b/tests/rustdoc/extern/extern-default-method.rs
diff --git a/tests/rustdoc/extern-fn-22038.rs b/tests/rustdoc/extern/extern-fn-22038.rs
index 206c6e181d1..206c6e181d1 100644
--- a/tests/rustdoc/extern-fn-22038.rs
+++ b/tests/rustdoc/extern/extern-fn-22038.rs
diff --git a/tests/rustdoc/extern-html-root-url-precedence.rs b/tests/rustdoc/extern/extern-html-root-url-precedence.rs
index 93775087997..93775087997 100644
--- a/tests/rustdoc/extern-html-root-url-precedence.rs
+++ b/tests/rustdoc/extern/extern-html-root-url-precedence.rs
diff --git a/tests/rustdoc/extern-html-root-url.rs b/tests/rustdoc/extern/extern-html-root-url.rs
index a503e829de4..a503e829de4 100644
--- a/tests/rustdoc/extern-html-root-url.rs
+++ b/tests/rustdoc/extern/extern-html-root-url.rs
diff --git a/tests/rustdoc/extern-links.rs b/tests/rustdoc/extern/extern-links.rs
index d1fee224755..d1fee224755 100644
--- a/tests/rustdoc/extern-links.rs
+++ b/tests/rustdoc/extern/extern-links.rs
diff --git a/tests/rustdoc/extern-method.rs b/tests/rustdoc/extern/extern-method.rs
index c3e042f2da8..c3e042f2da8 100644
--- a/tests/rustdoc/extern-method.rs
+++ b/tests/rustdoc/extern/extern-method.rs
diff --git a/tests/rustdoc/external-cross.rs b/tests/rustdoc/extern/external-cross.rs
index 13646ec38cf..13646ec38cf 100644
--- a/tests/rustdoc/external-cross.rs
+++ b/tests/rustdoc/extern/external-cross.rs
diff --git a/tests/rustdoc/external-doc.rs b/tests/rustdoc/extern/external-doc.rs
index c81aa17ed5a..c81aa17ed5a 100644
--- a/tests/rustdoc/external-doc.rs
+++ b/tests/rustdoc/extern/external-doc.rs
diff --git a/tests/rustdoc/hidden-extern-34025.rs b/tests/rustdoc/extern/hidden-extern-34025.rs
index 2a7b21a874d..2a7b21a874d 100644
--- a/tests/rustdoc/hidden-extern-34025.rs
+++ b/tests/rustdoc/extern/hidden-extern-34025.rs
diff --git a/tests/rustdoc/link-extern-crate-33178.rs b/tests/rustdoc/extern/link-extern-crate-33178.rs
index 94822798af3..94822798af3 100644
--- a/tests/rustdoc/link-extern-crate-33178.rs
+++ b/tests/rustdoc/extern/link-extern-crate-33178.rs
diff --git a/tests/rustdoc/link-extern-crate-item-30109.rs b/tests/rustdoc/extern/link-extern-crate-item-30109.rs
index 544cfa14971..544cfa14971 100644
--- a/tests/rustdoc/link-extern-crate-item-30109.rs
+++ b/tests/rustdoc/extern/link-extern-crate-item-30109.rs
diff --git a/tests/rustdoc/link-extern-crate-title-33178.rs b/tests/rustdoc/extern/link-extern-crate-title-33178.rs
index 39c4fec1cd9..39c4fec1cd9 100644
--- a/tests/rustdoc/link-extern-crate-title-33178.rs
+++ b/tests/rustdoc/extern/link-extern-crate-title-33178.rs
diff --git a/tests/rustdoc/pub-extern-crate.rs b/tests/rustdoc/extern/pub-extern-crate.rs
index 05f70301e33..05f70301e33 100644
--- a/tests/rustdoc/pub-extern-crate.rs
+++ b/tests/rustdoc/extern/pub-extern-crate.rs
diff --git a/tests/rustdoc/unsafe-extern-blocks.rs b/tests/rustdoc/extern/unsafe-extern-blocks.rs
index 9a4e292dc83..9a4e292dc83 100644
--- a/tests/rustdoc/unsafe-extern-blocks.rs
+++ b/tests/rustdoc/extern/unsafe-extern-blocks.rs
diff --git a/tests/rustdoc/unused-extern-crate.rs b/tests/rustdoc/extern/unused-extern-crate.rs
index cdc00fd313a..cdc00fd313a 100644
--- a/tests/rustdoc/unused-extern-crate.rs
+++ b/tests/rustdoc/extern/unused-extern-crate.rs
diff --git a/tests/rustdoc/auxiliary/cross-crate-hidden-impl-parameter.rs b/tests/rustdoc/impl/auxiliary/cross-crate-hidden-impl-parameter.rs
index 15953122280..15953122280 100644
--- a/tests/rustdoc/auxiliary/cross-crate-hidden-impl-parameter.rs
+++ b/tests/rustdoc/impl/auxiliary/cross-crate-hidden-impl-parameter.rs
diff --git a/tests/rustdoc/auxiliary/extern-impl-trait.rs b/tests/rustdoc/impl/auxiliary/extern-impl-trait.rs
index dbd54393098..dbd54393098 100644
--- a/tests/rustdoc/auxiliary/extern-impl-trait.rs
+++ b/tests/rustdoc/impl/auxiliary/extern-impl-trait.rs
diff --git a/tests/rustdoc/auxiliary/incoherent-impl-types.rs b/tests/rustdoc/impl/auxiliary/incoherent-impl-types.rs
index fc51e42e500..fc51e42e500 100644
--- a/tests/rustdoc/auxiliary/incoherent-impl-types.rs
+++ b/tests/rustdoc/impl/auxiliary/incoherent-impl-types.rs
diff --git a/tests/rustdoc/auxiliary/issue-100204-aux.rs b/tests/rustdoc/impl/auxiliary/issue-100204-aux.rs
index df1b59069be..df1b59069be 100644
--- a/tests/rustdoc/auxiliary/issue-100204-aux.rs
+++ b/tests/rustdoc/impl/auxiliary/issue-100204-aux.rs
diff --git a/tests/rustdoc/auxiliary/issue-17476.rs b/tests/rustdoc/impl/auxiliary/issue-17476.rs
index 0a63b893fff..0a63b893fff 100644
--- a/tests/rustdoc/auxiliary/issue-17476.rs
+++ b/tests/rustdoc/impl/auxiliary/issue-17476.rs
diff --git a/tests/rustdoc/auxiliary/issue-21092.rs b/tests/rustdoc/impl/auxiliary/issue-21092.rs
index 49522e0d4b5..49522e0d4b5 100644
--- a/tests/rustdoc/auxiliary/issue-21092.rs
+++ b/tests/rustdoc/impl/auxiliary/issue-21092.rs
diff --git a/tests/rustdoc/auxiliary/issue-22025.rs b/tests/rustdoc/impl/auxiliary/issue-22025.rs
index 6bc55073283..6bc55073283 100644
--- a/tests/rustdoc/auxiliary/issue-22025.rs
+++ b/tests/rustdoc/impl/auxiliary/issue-22025.rs
diff --git a/tests/rustdoc/auxiliary/issue-53689.rs b/tests/rustdoc/impl/auxiliary/issue-53689.rs
index 5003c2c00f4..5003c2c00f4 100644
--- a/tests/rustdoc/auxiliary/issue-53689.rs
+++ b/tests/rustdoc/impl/auxiliary/issue-53689.rs
diff --git a/tests/rustdoc/auxiliary/precise-capturing.rs b/tests/rustdoc/impl/auxiliary/precise-capturing.rs
index 531d4dfdccc..531d4dfdccc 100644
--- a/tests/rustdoc/auxiliary/precise-capturing.rs
+++ b/tests/rustdoc/impl/auxiliary/precise-capturing.rs
diff --git a/tests/rustdoc/auxiliary/real_gimli.rs b/tests/rustdoc/impl/auxiliary/real_gimli.rs
index 871d9b31be9..871d9b31be9 100644
--- a/tests/rustdoc/auxiliary/real_gimli.rs
+++ b/tests/rustdoc/impl/auxiliary/real_gimli.rs
diff --git a/tests/rustdoc/auxiliary/realcore.rs b/tests/rustdoc/impl/auxiliary/realcore.rs
index e0a906df002..e0a906df002 100644
--- a/tests/rustdoc/auxiliary/realcore.rs
+++ b/tests/rustdoc/impl/auxiliary/realcore.rs
diff --git a/tests/rustdoc/auxiliary/rustdoc-default-impl.rs b/tests/rustdoc/impl/auxiliary/rustdoc-default-impl.rs
index 032db3b25e6..032db3b25e6 100644
--- a/tests/rustdoc/auxiliary/rustdoc-default-impl.rs
+++ b/tests/rustdoc/impl/auxiliary/rustdoc-default-impl.rs
diff --git a/tests/rustdoc/auxiliary/rustdoc-impl-parts-crosscrate.rs b/tests/rustdoc/impl/auxiliary/rustdoc-impl-parts-crosscrate.rs
index 135987fc00d..135987fc00d 100644
--- a/tests/rustdoc/auxiliary/rustdoc-impl-parts-crosscrate.rs
+++ b/tests/rustdoc/impl/auxiliary/rustdoc-impl-parts-crosscrate.rs
diff --git a/tests/rustdoc/blanket-impl-29503.rs b/tests/rustdoc/impl/blanket-impl-29503.rs
index f43fe79ca58..f43fe79ca58 100644
--- a/tests/rustdoc/blanket-impl-29503.rs
+++ b/tests/rustdoc/impl/blanket-impl-29503.rs
diff --git a/tests/rustdoc/blanket-impl-78673.rs b/tests/rustdoc/impl/blanket-impl-78673.rs
index 412d4057406..412d4057406 100644
--- a/tests/rustdoc/blanket-impl-78673.rs
+++ b/tests/rustdoc/impl/blanket-impl-78673.rs
diff --git a/tests/rustdoc/cross-crate-hidden-impl-parameter.rs b/tests/rustdoc/impl/cross-crate-hidden-impl-parameter.rs
index ebfe251134a..ebfe251134a 100644
--- a/tests/rustdoc/cross-crate-hidden-impl-parameter.rs
+++ b/tests/rustdoc/impl/cross-crate-hidden-impl-parameter.rs
diff --git a/tests/rustdoc/deduplicate-glob-import-impl-21474.rs b/tests/rustdoc/impl/deduplicate-glob-import-impl-21474.rs
index 5812d414997..5812d414997 100644
--- a/tests/rustdoc/deduplicate-glob-import-impl-21474.rs
+++ b/tests/rustdoc/impl/deduplicate-glob-import-impl-21474.rs
diff --git a/tests/rustdoc/deduplicate-trait-impl-22025.rs b/tests/rustdoc/impl/deduplicate-trait-impl-22025.rs
index 7b1648a56ac..7b1648a56ac 100644
--- a/tests/rustdoc/deduplicate-trait-impl-22025.rs
+++ b/tests/rustdoc/impl/deduplicate-trait-impl-22025.rs
diff --git a/tests/rustdoc/default-impl.rs b/tests/rustdoc/impl/default-impl.rs
index 2ba9c4ab5ad..2ba9c4ab5ad 100644
--- a/tests/rustdoc/default-impl.rs
+++ b/tests/rustdoc/impl/default-impl.rs
diff --git a/tests/rustdoc/deprecated-impls.rs b/tests/rustdoc/impl/deprecated-impls.rs
index a57f26ec7fd..a57f26ec7fd 100644
--- a/tests/rustdoc/deprecated-impls.rs
+++ b/tests/rustdoc/impl/deprecated-impls.rs
diff --git a/tests/rustdoc/doc-hidden-trait-implementors-33069.rs b/tests/rustdoc/impl/doc-hidden-trait-implementors-33069.rs
index d5ee3d09276..d5ee3d09276 100644
--- a/tests/rustdoc/doc-hidden-trait-implementors-33069.rs
+++ b/tests/rustdoc/impl/doc-hidden-trait-implementors-33069.rs
diff --git a/tests/rustdoc/doc_auto_cfg_nested_impl.rs b/tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs
index f85d7b23637..f85d7b23637 100644
--- a/tests/rustdoc/doc_auto_cfg_nested_impl.rs
+++ b/tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs
diff --git a/tests/rustdoc/duplicated_impl.rs b/tests/rustdoc/impl/duplicated_impl.rs
index e7828885cc1..e7828885cc1 100644
--- a/tests/rustdoc/duplicated_impl.rs
+++ b/tests/rustdoc/impl/duplicated_impl.rs
diff --git a/tests/rustdoc/empty-impl-block.rs b/tests/rustdoc/impl/empty-impl-block.rs
index 91fd4a64ef9..91fd4a64ef9 100644
--- a/tests/rustdoc/empty-impl-block.rs
+++ b/tests/rustdoc/impl/empty-impl-block.rs
diff --git a/tests/rustdoc/empty-impls.rs b/tests/rustdoc/impl/empty-impls.rs
index 912a8d3d913..912a8d3d913 100644
--- a/tests/rustdoc/empty-impls.rs
+++ b/tests/rustdoc/impl/empty-impls.rs
diff --git a/tests/rustdoc/extern-impl-trait.rs b/tests/rustdoc/impl/extern-impl-trait.rs
index 65b7a8cef49..65b7a8cef49 100644
--- a/tests/rustdoc/extern-impl-trait.rs
+++ b/tests/rustdoc/impl/extern-impl-trait.rs
diff --git a/tests/rustdoc/extern-impl.rs b/tests/rustdoc/impl/extern-impl.rs
index 4fc31393988..4fc31393988 100644
--- a/tests/rustdoc/extern-impl.rs
+++ b/tests/rustdoc/impl/extern-impl.rs
diff --git a/tests/rustdoc/foreign-implementors-js-43701.rs b/tests/rustdoc/impl/foreign-implementors-js-43701.rs
index 03147da02c2..03147da02c2 100644
--- a/tests/rustdoc/foreign-implementors-js-43701.rs
+++ b/tests/rustdoc/impl/foreign-implementors-js-43701.rs
diff --git a/tests/rustdoc/generic-impl.rs b/tests/rustdoc/impl/generic-impl.rs
index 9d15d0fff77..9d15d0fff77 100644
--- a/tests/rustdoc/generic-impl.rs
+++ b/tests/rustdoc/impl/generic-impl.rs
diff --git a/tests/rustdoc/hidden-implementors-90781.rs b/tests/rustdoc/impl/hidden-implementors-90781.rs
index 960a85b91f0..960a85b91f0 100644
--- a/tests/rustdoc/hidden-implementors-90781.rs
+++ b/tests/rustdoc/impl/hidden-implementors-90781.rs
diff --git a/tests/rustdoc/hidden-impls.rs b/tests/rustdoc/impl/hidden-impls.rs
index 73deeed9e90..73deeed9e90 100644
--- a/tests/rustdoc/hidden-impls.rs
+++ b/tests/rustdoc/impl/hidden-impls.rs
diff --git a/tests/rustdoc/hidden-trait-struct-impls.rs b/tests/rustdoc/impl/hidden-trait-struct-impls.rs
index 1010cb45960..1010cb45960 100644
--- a/tests/rustdoc/hidden-trait-struct-impls.rs
+++ b/tests/rustdoc/impl/hidden-trait-struct-impls.rs
diff --git a/tests/rustdoc/hide-mut-methods-if-no-derefmut-impl-74083.rs b/tests/rustdoc/impl/hide-mut-methods-if-no-derefmut-impl-74083.rs
index 995121a8455..995121a8455 100644
--- a/tests/rustdoc/hide-mut-methods-if-no-derefmut-impl-74083.rs
+++ b/tests/rustdoc/impl/hide-mut-methods-if-no-derefmut-impl-74083.rs
diff --git a/tests/rustdoc/impl-alias-substituted.rs b/tests/rustdoc/impl/impl-alias-substituted.rs
index 02efcd88df8..02efcd88df8 100644
--- a/tests/rustdoc/impl-alias-substituted.rs
+++ b/tests/rustdoc/impl/impl-alias-substituted.rs
diff --git a/tests/rustdoc/impl-assoc-type-21092.rs b/tests/rustdoc/impl/impl-assoc-type-21092.rs
index c350456195d..c350456195d 100644
--- a/tests/rustdoc/impl-assoc-type-21092.rs
+++ b/tests/rustdoc/impl/impl-assoc-type-21092.rs
diff --git a/tests/rustdoc/impl-associated-items-order.rs b/tests/rustdoc/impl/impl-associated-items-order.rs
index 759e0f0b400..759e0f0b400 100644
--- a/tests/rustdoc/impl-associated-items-order.rs
+++ b/tests/rustdoc/impl/impl-associated-items-order.rs
diff --git a/tests/rustdoc/impl-associated-items-sidebar.rs b/tests/rustdoc/impl/impl-associated-items-sidebar.rs
index d393a577e50..d393a577e50 100644
--- a/tests/rustdoc/impl-associated-items-sidebar.rs
+++ b/tests/rustdoc/impl/impl-associated-items-sidebar.rs
diff --git a/tests/rustdoc/impl-blanket-53689.rs b/tests/rustdoc/impl/impl-blanket-53689.rs
index 4b1697349f2..4b1697349f2 100644
--- a/tests/rustdoc/impl-blanket-53689.rs
+++ b/tests/rustdoc/impl/impl-blanket-53689.rs
diff --git a/tests/rustdoc/impl-box.rs b/tests/rustdoc/impl/impl-box.rs
index 1fb63e21685..1fb63e21685 100644
--- a/tests/rustdoc/impl-box.rs
+++ b/tests/rustdoc/impl/impl-box.rs
diff --git a/tests/rustdoc/impl-disambiguation.rs b/tests/rustdoc/impl/impl-disambiguation.rs
index cfd5013964b..cfd5013964b 100644
--- a/tests/rustdoc/impl-disambiguation.rs
+++ b/tests/rustdoc/impl/impl-disambiguation.rs
diff --git a/tests/rustdoc/impl-everywhere.rs b/tests/rustdoc/impl/impl-everywhere.rs
index d1a4e901bad..d1a4e901bad 100644
--- a/tests/rustdoc/impl-everywhere.rs
+++ b/tests/rustdoc/impl/impl-everywhere.rs
diff --git a/tests/rustdoc/impl-in-const-block.rs b/tests/rustdoc/impl/impl-in-const-block.rs
index 3f757fa9566..3f757fa9566 100644
--- a/tests/rustdoc/impl-in-const-block.rs
+++ b/tests/rustdoc/impl/impl-in-const-block.rs
diff --git a/tests/rustdoc/impl-on-ty-alias-issue-119015.rs b/tests/rustdoc/impl/impl-on-ty-alias-issue-119015.rs
index a514bc35bfc..a514bc35bfc 100644
--- a/tests/rustdoc/impl-on-ty-alias-issue-119015.rs
+++ b/tests/rustdoc/impl/impl-on-ty-alias-issue-119015.rs
diff --git a/tests/rustdoc/impl-parts-crosscrate.rs b/tests/rustdoc/impl/impl-parts-crosscrate.rs
index 631c8bb3eb3..631c8bb3eb3 100644
--- a/tests/rustdoc/impl-parts-crosscrate.rs
+++ b/tests/rustdoc/impl/impl-parts-crosscrate.rs
diff --git a/tests/rustdoc/impl-parts.rs b/tests/rustdoc/impl/impl-parts.rs
index 4f281bfd63c..4f281bfd63c 100644
--- a/tests/rustdoc/impl-parts.rs
+++ b/tests/rustdoc/impl/impl-parts.rs
diff --git a/tests/rustdoc/impl-ref-20175.rs b/tests/rustdoc/impl/impl-ref-20175.rs
index b1a9286fd41..b1a9286fd41 100644
--- a/tests/rustdoc/impl-ref-20175.rs
+++ b/tests/rustdoc/impl/impl-ref-20175.rs
diff --git a/tests/rustdoc/impl-trait-43869.rs b/tests/rustdoc/impl/impl-trait-43869.rs
index 89176f59ca1..89176f59ca1 100644
--- a/tests/rustdoc/impl-trait-43869.rs
+++ b/tests/rustdoc/impl/impl-trait-43869.rs
diff --git a/tests/rustdoc/impl-trait-alias.rs b/tests/rustdoc/impl/impl-trait-alias.rs
index f7ecfffbf46..f7ecfffbf46 100644
--- a/tests/rustdoc/impl-trait-alias.rs
+++ b/tests/rustdoc/impl/impl-trait-alias.rs
diff --git a/tests/rustdoc/impl-trait-precise-capturing.rs b/tests/rustdoc/impl/impl-trait-precise-capturing.rs
index 3ec8c578013..3ec8c578013 100644
--- a/tests/rustdoc/impl-trait-precise-capturing.rs
+++ b/tests/rustdoc/impl/impl-trait-precise-capturing.rs
diff --git a/tests/rustdoc/impl-type-parameter-33592.rs b/tests/rustdoc/impl/impl-type-parameter-33592.rs
index ac5df460925..ac5df460925 100644
--- a/tests/rustdoc/impl-type-parameter-33592.rs
+++ b/tests/rustdoc/impl/impl-type-parameter-33592.rs
diff --git a/tests/rustdoc/implementor-stable-version.rs b/tests/rustdoc/impl/implementor-stable-version.rs
index cd4fa93f803..cd4fa93f803 100644
--- a/tests/rustdoc/implementor-stable-version.rs
+++ b/tests/rustdoc/impl/implementor-stable-version.rs
diff --git a/tests/rustdoc/implementors-unstable-75588.rs b/tests/rustdoc/impl/implementors-unstable-75588.rs
index 44a785c4ad9..44a785c4ad9 100644
--- a/tests/rustdoc/implementors-unstable-75588.rs
+++ b/tests/rustdoc/impl/implementors-unstable-75588.rs
diff --git a/tests/rustdoc/inline-impl-through-glob-import-100204.rs b/tests/rustdoc/impl/inline-impl-through-glob-import-100204.rs
index ba6ed427871..ba6ed427871 100644
--- a/tests/rustdoc/inline-impl-through-glob-import-100204.rs
+++ b/tests/rustdoc/impl/inline-impl-through-glob-import-100204.rs
diff --git a/tests/rustdoc/manual_impl.rs b/tests/rustdoc/impl/manual_impl.rs
index 281262bb40a..281262bb40a 100644
--- a/tests/rustdoc/manual_impl.rs
+++ b/tests/rustdoc/impl/manual_impl.rs
diff --git a/tests/rustdoc/method-link-foreign-trait-impl-17476.rs b/tests/rustdoc/impl/method-link-foreign-trait-impl-17476.rs
index cda828d3967..cda828d3967 100644
--- a/tests/rustdoc/method-link-foreign-trait-impl-17476.rs
+++ b/tests/rustdoc/impl/method-link-foreign-trait-impl-17476.rs
diff --git a/tests/rustdoc/module-impls.rs b/tests/rustdoc/impl/module-impls.rs
index b66721ecb13..b66721ecb13 100644
--- a/tests/rustdoc/module-impls.rs
+++ b/tests/rustdoc/impl/module-impls.rs
diff --git a/tests/rustdoc/must_implement_one_of.rs b/tests/rustdoc/impl/must_implement_one_of.rs
index ab965bab356..ab965bab356 100644
--- a/tests/rustdoc/must_implement_one_of.rs
+++ b/tests/rustdoc/impl/must_implement_one_of.rs
diff --git a/tests/rustdoc/negative-impl-no-items.rs b/tests/rustdoc/impl/negative-impl-no-items.rs
index c628e542033..c628e542033 100644
--- a/tests/rustdoc/negative-impl-no-items.rs
+++ b/tests/rustdoc/impl/negative-impl-no-items.rs
diff --git a/tests/rustdoc/negative-impl-sidebar.rs b/tests/rustdoc/impl/negative-impl-sidebar.rs
index 1742dce1945..1742dce1945 100644
--- a/tests/rustdoc/negative-impl-sidebar.rs
+++ b/tests/rustdoc/impl/negative-impl-sidebar.rs
diff --git a/tests/rustdoc/negative-impl.rs b/tests/rustdoc/impl/negative-impl.rs
index f057a749b72..f057a749b72 100644
--- a/tests/rustdoc/negative-impl.rs
+++ b/tests/rustdoc/impl/negative-impl.rs
diff --git a/tests/rustdoc/return-impl-trait.rs b/tests/rustdoc/impl/return-impl-trait.rs
index 175867d2204..175867d2204 100644
--- a/tests/rustdoc/return-impl-trait.rs
+++ b/tests/rustdoc/impl/return-impl-trait.rs
diff --git a/tests/rustdoc/rustc-incoherent-impls.rs b/tests/rustdoc/impl/rustc-incoherent-impls.rs
index 81a7025906b..81a7025906b 100644
--- a/tests/rustdoc/rustc-incoherent-impls.rs
+++ b/tests/rustdoc/impl/rustc-incoherent-impls.rs
diff --git a/tests/rustdoc/same-crate-hidden-impl-parameter.rs b/tests/rustdoc/impl/same-crate-hidden-impl-parameter.rs
index b0beb1bdfa0..b0beb1bdfa0 100644
--- a/tests/rustdoc/same-crate-hidden-impl-parameter.rs
+++ b/tests/rustdoc/impl/same-crate-hidden-impl-parameter.rs
diff --git a/tests/rustdoc/sidebar-trait-impl-disambiguate-78701.rs b/tests/rustdoc/impl/sidebar-trait-impl-disambiguate-78701.rs
index b1bf029cf84..b1bf029cf84 100644
--- a/tests/rustdoc/sidebar-trait-impl-disambiguate-78701.rs
+++ b/tests/rustdoc/impl/sidebar-trait-impl-disambiguate-78701.rs
diff --git a/tests/rustdoc/struct-implementations-title.rs b/tests/rustdoc/impl/struct-implementations-title.rs
index ca5b5c0ee20..ca5b5c0ee20 100644
--- a/tests/rustdoc/struct-implementations-title.rs
+++ b/tests/rustdoc/impl/struct-implementations-title.rs
diff --git a/tests/rustdoc/trait-impl.rs b/tests/rustdoc/impl/trait-impl.rs
index c65eecc4edf..c65eecc4edf 100644
--- a/tests/rustdoc/trait-impl.rs
+++ b/tests/rustdoc/impl/trait-impl.rs
diff --git a/tests/rustdoc/trait-implementations-duplicate-self-45584.rs b/tests/rustdoc/impl/trait-implementations-duplicate-self-45584.rs
index 8eb6d007525..8eb6d007525 100644
--- a/tests/rustdoc/trait-implementations-duplicate-self-45584.rs
+++ b/tests/rustdoc/impl/trait-implementations-duplicate-self-45584.rs
diff --git a/tests/rustdoc/underscore-type-in-trait-impl-96381.rs b/tests/rustdoc/impl/underscore-type-in-trait-impl-96381.rs
index 6d6e5e0a839..6d6e5e0a839 100644
--- a/tests/rustdoc/underscore-type-in-trait-impl-96381.rs
+++ b/tests/rustdoc/impl/underscore-type-in-trait-impl-96381.rs
diff --git a/tests/rustdoc/universal-impl-trait.rs b/tests/rustdoc/impl/universal-impl-trait.rs
index b78d69c0690..b78d69c0690 100644
--- a/tests/rustdoc/universal-impl-trait.rs
+++ b/tests/rustdoc/impl/universal-impl-trait.rs
diff --git a/tests/rustdoc/unneeded-trait-implementations-title.rs b/tests/rustdoc/impl/unneeded-trait-implementations-title.rs
index f7a97dfaaef..f7a97dfaaef 100644
--- a/tests/rustdoc/unneeded-trait-implementations-title.rs
+++ b/tests/rustdoc/impl/unneeded-trait-implementations-title.rs
diff --git a/tests/rustdoc/ice-intra-doc-links-107995.rs b/tests/rustdoc/intra-doc/ice-intra-doc-links-107995.rs
index 57669909aa1..57669909aa1 100644
--- a/tests/rustdoc/ice-intra-doc-links-107995.rs
+++ b/tests/rustdoc/intra-doc/ice-intra-doc-links-107995.rs
diff --git a/tests/rustdoc/intra-doc-link-method-trait-impl-72340.rs b/tests/rustdoc/intra-doc/intra-doc-link-method-trait-impl-72340.rs
index 0cf46bb3f95..0cf46bb3f95 100644
--- a/tests/rustdoc/intra-doc-link-method-trait-impl-72340.rs
+++ b/tests/rustdoc/intra-doc/intra-doc-link-method-trait-impl-72340.rs
diff --git a/tests/rustdoc/auxiliary/jump-to-def-macro.rs b/tests/rustdoc/jump-to-def/auxiliary/jump-to-def-macro.rs
index f442b9461e8..f442b9461e8 100644
--- a/tests/rustdoc/auxiliary/jump-to-def-macro.rs
+++ b/tests/rustdoc/jump-to-def/auxiliary/jump-to-def-macro.rs
diff --git a/tests/rustdoc/jump-to-def-doc-links-calls.rs b/tests/rustdoc/jump-to-def/jump-to-def-doc-links-calls.rs
index 61856978773..61856978773 100644
--- a/tests/rustdoc/jump-to-def-doc-links-calls.rs
+++ b/tests/rustdoc/jump-to-def/jump-to-def-doc-links-calls.rs
diff --git a/tests/rustdoc/jump-to-def-doc-links.rs b/tests/rustdoc/jump-to-def/jump-to-def-doc-links.rs
index 2abb52e0a00..2abb52e0a00 100644
--- a/tests/rustdoc/jump-to-def-doc-links.rs
+++ b/tests/rustdoc/jump-to-def/jump-to-def-doc-links.rs
diff --git a/tests/rustdoc/jump-to-def-macro.rs b/tests/rustdoc/jump-to-def/jump-to-def-macro.rs
index 680477937c6..680477937c6 100644
--- a/tests/rustdoc/jump-to-def-macro.rs
+++ b/tests/rustdoc/jump-to-def/jump-to-def-macro.rs
diff --git a/tests/rustdoc/jump-to-def-pats.rs b/tests/rustdoc/jump-to-def/jump-to-def-pats.rs
index 147902b44cf..147902b44cf 100644
--- a/tests/rustdoc/jump-to-def-pats.rs
+++ b/tests/rustdoc/jump-to-def/jump-to-def-pats.rs
diff --git a/tests/rustdoc/jump-to-def-prelude-types.rs b/tests/rustdoc/jump-to-def/jump-to-def-prelude-types.rs
index 43617b1bc9d..43617b1bc9d 100644
--- a/tests/rustdoc/jump-to-def-prelude-types.rs
+++ b/tests/rustdoc/jump-to-def/jump-to-def-prelude-types.rs
diff --git a/tests/rustdoc/jump-to-non-local-method.rs b/tests/rustdoc/jump-to-def/jump-to-non-local-method.rs
index e2f530425f0..e2f530425f0 100644
--- a/tests/rustdoc/jump-to-non-local-method.rs
+++ b/tests/rustdoc/jump-to-def/jump-to-non-local-method.rs
diff --git a/tests/rustdoc/auxiliary/external-macro-src.rs b/tests/rustdoc/macro/auxiliary/external-macro-src.rs
index 79df5dc98eb..79df5dc98eb 100644
--- a/tests/rustdoc/auxiliary/external-macro-src.rs
+++ b/tests/rustdoc/macro/auxiliary/external-macro-src.rs
diff --git a/tests/rustdoc/macro/auxiliary/issue-99221-aux.rs b/tests/rustdoc/macro/auxiliary/issue-99221-aux.rs
new file mode 100644
index 00000000000..e061e42b29d
--- /dev/null
+++ b/tests/rustdoc/macro/auxiliary/issue-99221-aux.rs
@@ -0,0 +1,20 @@
+pub struct Option;
+impl Option {
+    pub fn unwrap(self) {}
+}
+
+mod macros {
+    use crate::Option;
+    /// [`Option::unwrap`]
+    #[macro_export]
+    macro_rules! print {
+        () => ()
+    }
+}
+
+mod structs {
+    use crate::Option;
+    /// [`Option::unwrap`]
+    pub struct Print;
+}
+pub use structs::Print;
diff --git a/tests/rustdoc/auxiliary/macro_pub_in_module.rs b/tests/rustdoc/macro/auxiliary/macro_pub_in_module.rs
index 81efa1db536..81efa1db536 100644
--- a/tests/rustdoc/auxiliary/macro_pub_in_module.rs
+++ b/tests/rustdoc/macro/auxiliary/macro_pub_in_module.rs
diff --git a/tests/rustdoc/auxiliary/pub-use-extern-macros.rs b/tests/rustdoc/macro/auxiliary/pub-use-extern-macros.rs
index 7934e07339a..7934e07339a 100644
--- a/tests/rustdoc/auxiliary/pub-use-extern-macros.rs
+++ b/tests/rustdoc/macro/auxiliary/pub-use-extern-macros.rs
diff --git a/tests/rustdoc/compiler-derive-proc-macro.rs b/tests/rustdoc/macro/compiler-derive-proc-macro.rs
index e8dc5d7c6b7..e8dc5d7c6b7 100644
--- a/tests/rustdoc/compiler-derive-proc-macro.rs
+++ b/tests/rustdoc/macro/compiler-derive-proc-macro.rs
diff --git a/tests/rustdoc/const-rendering-macros-33302.rs b/tests/rustdoc/macro/const-rendering-macros-33302.rs
index 9fd45df08be..9fd45df08be 100644
--- a/tests/rustdoc/const-rendering-macros-33302.rs
+++ b/tests/rustdoc/macro/const-rendering-macros-33302.rs
diff --git a/tests/rustdoc/decl_macro.rs b/tests/rustdoc/macro/decl_macro.rs
index 040859baffb..040859baffb 100644
--- a/tests/rustdoc/decl_macro.rs
+++ b/tests/rustdoc/macro/decl_macro.rs
diff --git a/tests/rustdoc/decl_macro_priv.rs b/tests/rustdoc/macro/decl_macro_priv.rs
index d87c8d22f2d..d87c8d22f2d 100644
--- a/tests/rustdoc/decl_macro_priv.rs
+++ b/tests/rustdoc/macro/decl_macro_priv.rs
diff --git a/tests/rustdoc/doc-proc-macro.rs b/tests/rustdoc/macro/doc-proc-macro.rs
index 19172ffa41d..19172ffa41d 100644
--- a/tests/rustdoc/doc-proc-macro.rs
+++ b/tests/rustdoc/macro/doc-proc-macro.rs
diff --git a/tests/rustdoc/external-macro-src.rs b/tests/rustdoc/macro/external-macro-src.rs
index 998687d93bd..998687d93bd 100644
--- a/tests/rustdoc/external-macro-src.rs
+++ b/tests/rustdoc/macro/external-macro-src.rs
diff --git a/tests/rustdoc/macro-const-display-115295.rs b/tests/rustdoc/macro/macro-const-display-115295.rs
index 445b47e0b24..445b47e0b24 100644
--- a/tests/rustdoc/macro-const-display-115295.rs
+++ b/tests/rustdoc/macro/macro-const-display-115295.rs
diff --git a/tests/rustdoc/macro-doc-comment-23812.rs b/tests/rustdoc/macro/macro-doc-comment-23812.rs
index 03fda4a25b9..03fda4a25b9 100644
--- a/tests/rustdoc/macro-doc-comment-23812.rs
+++ b/tests/rustdoc/macro/macro-doc-comment-23812.rs
diff --git a/tests/rustdoc/macro-export-crate-root-108231.rs b/tests/rustdoc/macro/macro-export-crate-root-108231.rs
index 0d3ad1b0571..0d3ad1b0571 100644
--- a/tests/rustdoc/macro-export-crate-root-108231.rs
+++ b/tests/rustdoc/macro/macro-export-crate-root-108231.rs
diff --git a/tests/rustdoc/macro-generated-macro.macro_linebreak_pre.html b/tests/rustdoc/macro/macro-generated-macro.macro_linebreak_pre.html
index ce5d3a8461b..ce5d3a8461b 100644
--- a/tests/rustdoc/macro-generated-macro.macro_linebreak_pre.html
+++ b/tests/rustdoc/macro/macro-generated-macro.macro_linebreak_pre.html
diff --git a/tests/rustdoc/macro-generated-macro.macro_morestuff_pre.html b/tests/rustdoc/macro/macro-generated-macro.macro_morestuff_pre.html
index 28f15522a82..28f15522a82 100644
--- a/tests/rustdoc/macro-generated-macro.macro_morestuff_pre.html
+++ b/tests/rustdoc/macro/macro-generated-macro.macro_morestuff_pre.html
diff --git a/tests/rustdoc/macro-generated-macro.rs b/tests/rustdoc/macro/macro-generated-macro.rs
index e77d0cf89e7..e77d0cf89e7 100644
--- a/tests/rustdoc/macro-generated-macro.rs
+++ b/tests/rustdoc/macro/macro-generated-macro.rs
diff --git a/tests/rustdoc/macro-higher-kinded-function.rs b/tests/rustdoc/macro/macro-higher-kinded-function.rs
index 738ea8fb3f1..738ea8fb3f1 100644
--- a/tests/rustdoc/macro-higher-kinded-function.rs
+++ b/tests/rustdoc/macro/macro-higher-kinded-function.rs
diff --git a/tests/rustdoc/macro-ice-16019.rs b/tests/rustdoc/macro/macro-ice-16019.rs
index d0f82e0a314..d0f82e0a314 100644
--- a/tests/rustdoc/macro-ice-16019.rs
+++ b/tests/rustdoc/macro/macro-ice-16019.rs
diff --git a/tests/rustdoc/macro-in-async-block.rs b/tests/rustdoc/macro/macro-in-async-block.rs
index 43822fb9c52..43822fb9c52 100644
--- a/tests/rustdoc/macro-in-async-block.rs
+++ b/tests/rustdoc/macro/macro-in-async-block.rs
diff --git a/tests/rustdoc/macro-in-closure.rs b/tests/rustdoc/macro/macro-in-closure.rs
index b4411d927e2..b4411d927e2 100644
--- a/tests/rustdoc/macro-in-closure.rs
+++ b/tests/rustdoc/macro/macro-in-closure.rs
diff --git a/tests/rustdoc/macro-indirect-use.rs b/tests/rustdoc/macro/macro-indirect-use.rs
index e410e96ae6a..e410e96ae6a 100644
--- a/tests/rustdoc/macro-indirect-use.rs
+++ b/tests/rustdoc/macro/macro-indirect-use.rs
diff --git a/tests/rustdoc/macro_pub_in_module.rs b/tests/rustdoc/macro/macro_pub_in_module.rs
index 2dce73c2cf2..2dce73c2cf2 100644
--- a/tests/rustdoc/macro_pub_in_module.rs
+++ b/tests/rustdoc/macro/macro_pub_in_module.rs
diff --git a/tests/rustdoc/macro_rules-matchers.rs b/tests/rustdoc/macro/macro_rules-matchers.rs
index 2c9fb50539a..2c9fb50539a 100644
--- a/tests/rustdoc/macro_rules-matchers.rs
+++ b/tests/rustdoc/macro/macro_rules-matchers.rs
diff --git a/tests/rustdoc/macros.rs b/tests/rustdoc/macro/macros.rs
index d08babc25f8..d08babc25f8 100644
--- a/tests/rustdoc/macros.rs
+++ b/tests/rustdoc/macro/macros.rs
diff --git a/tests/rustdoc/multiple-macro-rules-w-same-name-99221.rs b/tests/rustdoc/macro/multiple-macro-rules-w-same-name-99221.rs
index 4a1798a8496..4a1798a8496 100644
--- a/tests/rustdoc/multiple-macro-rules-w-same-name-99221.rs
+++ b/tests/rustdoc/macro/multiple-macro-rules-w-same-name-99221.rs
diff --git a/tests/rustdoc/multiple-macro-rules-w-same-name-submodule-99221.rs b/tests/rustdoc/macro/multiple-macro-rules-w-same-name-submodule-99221.rs
index bf59788073e..bf59788073e 100644
--- a/tests/rustdoc/multiple-macro-rules-w-same-name-submodule-99221.rs
+++ b/tests/rustdoc/macro/multiple-macro-rules-w-same-name-submodule-99221.rs
diff --git a/tests/rustdoc/proc-macro.rs b/tests/rustdoc/macro/proc-macro.rs
index a821f68ab93..a821f68ab93 100644
--- a/tests/rustdoc/proc-macro.rs
+++ b/tests/rustdoc/macro/proc-macro.rs
diff --git a/tests/rustdoc/pub-use-extern-macros.rs b/tests/rustdoc/macro/pub-use-extern-macros.rs
index 2316e620343..2316e620343 100644
--- a/tests/rustdoc/pub-use-extern-macros.rs
+++ b/tests/rustdoc/macro/pub-use-extern-macros.rs
diff --git a/tests/rustdoc/rustc-macro-crate.rs b/tests/rustdoc/macro/rustc-macro-crate.rs
index f0443364bb2..f0443364bb2 100644
--- a/tests/rustdoc/rustc-macro-crate.rs
+++ b/tests/rustdoc/macro/rustc-macro-crate.rs
diff --git a/tests/rustdoc/auxiliary/issue-15318.rs b/tests/rustdoc/primitive/auxiliary/issue-15318.rs
index d3dc89113fc..d3dc89113fc 100644
--- a/tests/rustdoc/auxiliary/issue-15318.rs
+++ b/tests/rustdoc/primitive/auxiliary/issue-15318.rs
diff --git a/tests/rustdoc/auxiliary/primitive-doc.rs b/tests/rustdoc/primitive/auxiliary/primitive-doc.rs
index 859716c38e4..859716c38e4 100644
--- a/tests/rustdoc/auxiliary/primitive-doc.rs
+++ b/tests/rustdoc/primitive/auxiliary/primitive-doc.rs
diff --git a/tests/rustdoc/cross-crate-primitive-doc.rs b/tests/rustdoc/primitive/cross-crate-primitive-doc.rs
index 0ffde5b0f2d..0ffde5b0f2d 100644
--- a/tests/rustdoc/cross-crate-primitive-doc.rs
+++ b/tests/rustdoc/primitive/cross-crate-primitive-doc.rs
diff --git a/tests/rustdoc/no_std-primitive.rs b/tests/rustdoc/primitive/no_std-primitive.rs
index 78076a601de..78076a601de 100644
--- a/tests/rustdoc/no_std-primitive.rs
+++ b/tests/rustdoc/primitive/no_std-primitive.rs
diff --git a/tests/rustdoc/primitive-link.rs b/tests/rustdoc/primitive/primitive-link.rs
index 3fe9cdc3ca7..3fe9cdc3ca7 100644
--- a/tests/rustdoc/primitive-link.rs
+++ b/tests/rustdoc/primitive/primitive-link.rs
diff --git a/tests/rustdoc/primitive-raw-pointer-dox-15318-3.rs b/tests/rustdoc/primitive/primitive-raw-pointer-dox-15318-3.rs
index 5520abf2925..5520abf2925 100644
--- a/tests/rustdoc/primitive-raw-pointer-dox-15318-3.rs
+++ b/tests/rustdoc/primitive/primitive-raw-pointer-dox-15318-3.rs
diff --git a/tests/rustdoc/primitive-raw-pointer-link-15318.rs b/tests/rustdoc/primitive/primitive-raw-pointer-link-15318.rs
index a6f6f67dc84..a6f6f67dc84 100644
--- a/tests/rustdoc/primitive-raw-pointer-link-15318.rs
+++ b/tests/rustdoc/primitive/primitive-raw-pointer-link-15318.rs
diff --git a/tests/rustdoc/primitive-raw-pointer-link-no-inlined-15318-2.rs b/tests/rustdoc/primitive/primitive-raw-pointer-link-no-inlined-15318-2.rs
index 16b007e8bbd..16b007e8bbd 100644
--- a/tests/rustdoc/primitive-raw-pointer-link-no-inlined-15318-2.rs
+++ b/tests/rustdoc/primitive/primitive-raw-pointer-link-no-inlined-15318-2.rs
diff --git a/tests/rustdoc/primitive-reference.rs b/tests/rustdoc/primitive/primitive-reference.rs
index bd6b2a32f75..bd6b2a32f75 100644
--- a/tests/rustdoc/primitive-reference.rs
+++ b/tests/rustdoc/primitive/primitive-reference.rs
diff --git a/tests/rustdoc/primitive-slice-auto-trait.rs b/tests/rustdoc/primitive/primitive-slice-auto-trait.rs
index 647c1cca948..647c1cca948 100644
--- a/tests/rustdoc/primitive-slice-auto-trait.rs
+++ b/tests/rustdoc/primitive/primitive-slice-auto-trait.rs
diff --git a/tests/rustdoc/primitive-tuple-auto-trait.rs b/tests/rustdoc/primitive/primitive-tuple-auto-trait.rs
index 51300bd6b2f..51300bd6b2f 100644
--- a/tests/rustdoc/primitive-tuple-auto-trait.rs
+++ b/tests/rustdoc/primitive/primitive-tuple-auto-trait.rs
diff --git a/tests/rustdoc/primitive-tuple-variadic.rs b/tests/rustdoc/primitive/primitive-tuple-variadic.rs
index bab5eaae9a2..bab5eaae9a2 100644
--- a/tests/rustdoc/primitive-tuple-variadic.rs
+++ b/tests/rustdoc/primitive/primitive-tuple-variadic.rs
diff --git a/tests/rustdoc/primitive-unit-auto-trait.rs b/tests/rustdoc/primitive/primitive-unit-auto-trait.rs
index 7dada1f9832..7dada1f9832 100644
--- a/tests/rustdoc/primitive-unit-auto-trait.rs
+++ b/tests/rustdoc/primitive/primitive-unit-auto-trait.rs
diff --git a/tests/rustdoc/search-index-primitive-inherent-method-23511.rs b/tests/rustdoc/primitive/search-index-primitive-inherent-method-23511.rs
index 6054d8f12f5..6054d8f12f5 100644
--- a/tests/rustdoc/search-index-primitive-inherent-method-23511.rs
+++ b/tests/rustdoc/primitive/search-index-primitive-inherent-method-23511.rs
diff --git a/tests/rustdoc/doc-hidden-private-67851-both.rs b/tests/rustdoc/private/doc-hidden-private-67851-both.rs
index 2e2190d8755..2e2190d8755 100644
--- a/tests/rustdoc/doc-hidden-private-67851-both.rs
+++ b/tests/rustdoc/private/doc-hidden-private-67851-both.rs
diff --git a/tests/rustdoc/doc-hidden-private-67851-hidden.rs b/tests/rustdoc/private/doc-hidden-private-67851-hidden.rs
index a811a04a668..a811a04a668 100644
--- a/tests/rustdoc/doc-hidden-private-67851-hidden.rs
+++ b/tests/rustdoc/private/doc-hidden-private-67851-hidden.rs
diff --git a/tests/rustdoc/doc-hidden-private-67851-neither.rs b/tests/rustdoc/private/doc-hidden-private-67851-neither.rs
index 1f70ceefe44..1f70ceefe44 100644
--- a/tests/rustdoc/doc-hidden-private-67851-neither.rs
+++ b/tests/rustdoc/private/doc-hidden-private-67851-neither.rs
diff --git a/tests/rustdoc/doc-hidden-private-67851-private.rs b/tests/rustdoc/private/doc-hidden-private-67851-private.rs
index f6f546ad5ea..f6f546ad5ea 100644
--- a/tests/rustdoc/doc-hidden-private-67851-private.rs
+++ b/tests/rustdoc/private/doc-hidden-private-67851-private.rs
diff --git a/tests/rustdoc/empty-impl-block-private-with-doc.rs b/tests/rustdoc/private/empty-impl-block-private-with-doc.rs
index 5dc7e1aed7a..5dc7e1aed7a 100644
--- a/tests/rustdoc/empty-impl-block-private-with-doc.rs
+++ b/tests/rustdoc/private/empty-impl-block-private-with-doc.rs
diff --git a/tests/rustdoc/empty-impl-block-private.rs b/tests/rustdoc/private/empty-impl-block-private.rs
index 2ee65d1a969..2ee65d1a969 100644
--- a/tests/rustdoc/empty-impl-block-private.rs
+++ b/tests/rustdoc/private/empty-impl-block-private.rs
diff --git a/tests/rustdoc/empty-mod-private.rs b/tests/rustdoc/private/empty-mod-private.rs
index 5a8638cd5f5..5a8638cd5f5 100644
--- a/tests/rustdoc/empty-mod-private.rs
+++ b/tests/rustdoc/private/empty-mod-private.rs
diff --git a/tests/rustdoc/enum-variant-private-46767.rs b/tests/rustdoc/private/enum-variant-private-46767.rs
index cc93684e723..cc93684e723 100644
--- a/tests/rustdoc/enum-variant-private-46767.rs
+++ b/tests/rustdoc/private/enum-variant-private-46767.rs
diff --git a/tests/rustdoc/files-creation-private.rs b/tests/rustdoc/private/files-creation-private.rs
index 54579380f0b..54579380f0b 100644
--- a/tests/rustdoc/files-creation-private.rs
+++ b/tests/rustdoc/private/files-creation-private.rs
diff --git a/tests/rustdoc/hidden-private.rs b/tests/rustdoc/private/hidden-private.rs
index 658e093cc23..658e093cc23 100644
--- a/tests/rustdoc/hidden-private.rs
+++ b/tests/rustdoc/private/hidden-private.rs
diff --git a/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs b/tests/rustdoc/private/inline-private-with-intermediate-doc-hidden.rs
index d27ecbad169..d27ecbad169 100644
--- a/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs
+++ b/tests/rustdoc/private/inline-private-with-intermediate-doc-hidden.rs
diff --git a/tests/rustdoc/inner-private-110422.rs b/tests/rustdoc/private/inner-private-110422.rs
index 31e28676879..31e28676879 100644
--- a/tests/rustdoc/inner-private-110422.rs
+++ b/tests/rustdoc/private/inner-private-110422.rs
diff --git a/tests/rustdoc/macro-document-private-duplicate.rs b/tests/rustdoc/private/macro-document-private-duplicate.rs
index 35cdc60dfdc..35cdc60dfdc 100644
--- a/tests/rustdoc/macro-document-private-duplicate.rs
+++ b/tests/rustdoc/private/macro-document-private-duplicate.rs
diff --git a/tests/rustdoc/macro-document-private.rs b/tests/rustdoc/private/macro-document-private.rs
index 224e31f8312..224e31f8312 100644
--- a/tests/rustdoc/macro-document-private.rs
+++ b/tests/rustdoc/private/macro-document-private.rs
diff --git a/tests/rustdoc/macro-private-not-documented.rs b/tests/rustdoc/private/macro-private-not-documented.rs
index bd97be5d366..bd97be5d366 100644
--- a/tests/rustdoc/macro-private-not-documented.rs
+++ b/tests/rustdoc/private/macro-private-not-documented.rs
diff --git a/tests/rustdoc/missing-private-inlining-109258.rs b/tests/rustdoc/private/missing-private-inlining-109258.rs
index 7f010f160c4..7f010f160c4 100644
--- a/tests/rustdoc/missing-private-inlining-109258.rs
+++ b/tests/rustdoc/private/missing-private-inlining-109258.rs
diff --git a/tests/rustdoc/private-fields-tuple-struct.rs b/tests/rustdoc/private/private-fields-tuple-struct.rs
index 51141923cd8..51141923cd8 100644
--- a/tests/rustdoc/private-fields-tuple-struct.rs
+++ b/tests/rustdoc/private/private-fields-tuple-struct.rs
diff --git a/tests/rustdoc/private-non-local-fields-2.rs b/tests/rustdoc/private/private-non-local-fields-2.rs
index f2d3530c088..f2d3530c088 100644
--- a/tests/rustdoc/private-non-local-fields-2.rs
+++ b/tests/rustdoc/private/private-non-local-fields-2.rs
diff --git a/tests/rustdoc/private-non-local-fields.rs b/tests/rustdoc/private/private-non-local-fields.rs
index aa7f01a58c6..aa7f01a58c6 100644
--- a/tests/rustdoc/private-non-local-fields.rs
+++ b/tests/rustdoc/private/private-non-local-fields.rs
diff --git a/tests/rustdoc/private-type-alias.rs b/tests/rustdoc/private/private-type-alias.rs
index 5b5f52728a9..5b5f52728a9 100644
--- a/tests/rustdoc/private-type-alias.rs
+++ b/tests/rustdoc/private/private-type-alias.rs
diff --git a/tests/rustdoc/private-type-cycle-110629.rs b/tests/rustdoc/private/private-type-cycle-110629.rs
index e2376809697..e2376809697 100644
--- a/tests/rustdoc/private-type-cycle-110629.rs
+++ b/tests/rustdoc/private/private-type-cycle-110629.rs
diff --git a/tests/rustdoc/private-use-decl-macro-47038.rs b/tests/rustdoc/private/private-use-decl-macro-47038.rs
index b72fca06d3b..b72fca06d3b 100644
--- a/tests/rustdoc/private-use-decl-macro-47038.rs
+++ b/tests/rustdoc/private/private-use-decl-macro-47038.rs
diff --git a/tests/rustdoc/private-use.rs b/tests/rustdoc/private/private-use.rs
index 689ed73140d..689ed73140d 100644
--- a/tests/rustdoc/private-use.rs
+++ b/tests/rustdoc/private/private-use.rs
diff --git a/tests/rustdoc/public-impl-mention-private-generic-46380-2.rs b/tests/rustdoc/private/public-impl-mention-private-generic-46380-2.rs
index 0445ae75e85..0445ae75e85 100644
--- a/tests/rustdoc/public-impl-mention-private-generic-46380-2.rs
+++ b/tests/rustdoc/private/public-impl-mention-private-generic-46380-2.rs
diff --git a/tests/rustdoc/traits-in-bodies-private.rs b/tests/rustdoc/private/traits-in-bodies-private.rs
index a3455b3255b..a3455b3255b 100644
--- a/tests/rustdoc/traits-in-bodies-private.rs
+++ b/tests/rustdoc/private/traits-in-bodies-private.rs
diff --git a/tests/rustdoc/alias-reexport.rs b/tests/rustdoc/reexport/alias-reexport.rs
index 41f1f8df0f6..41f1f8df0f6 100644
--- a/tests/rustdoc/alias-reexport.rs
+++ b/tests/rustdoc/reexport/alias-reexport.rs
diff --git a/tests/rustdoc/alias-reexport2.rs b/tests/rustdoc/reexport/alias-reexport2.rs
index 2fb69b922c8..2fb69b922c8 100644
--- a/tests/rustdoc/alias-reexport2.rs
+++ b/tests/rustdoc/reexport/alias-reexport2.rs
diff --git a/tests/rustdoc/anonymous-reexport-108931.rs b/tests/rustdoc/reexport/anonymous-reexport-108931.rs
index b995c89b614..b995c89b614 100644
--- a/tests/rustdoc/anonymous-reexport-108931.rs
+++ b/tests/rustdoc/reexport/anonymous-reexport-108931.rs
diff --git a/tests/rustdoc/anonymous-reexport.rs b/tests/rustdoc/reexport/anonymous-reexport.rs
index bf5fa93f953..bf5fa93f953 100644
--- a/tests/rustdoc/anonymous-reexport.rs
+++ b/tests/rustdoc/reexport/anonymous-reexport.rs
diff --git a/tests/rustdoc/auxiliary/alias-reexport.rs b/tests/rustdoc/reexport/auxiliary/alias-reexport.rs
index 14fafc02d36..14fafc02d36 100644
--- a/tests/rustdoc/auxiliary/alias-reexport.rs
+++ b/tests/rustdoc/reexport/auxiliary/alias-reexport.rs
diff --git a/tests/rustdoc/auxiliary/alias-reexport2.rs b/tests/rustdoc/reexport/auxiliary/alias-reexport2.rs
index ee1f242c1d4..ee1f242c1d4 100644
--- a/tests/rustdoc/auxiliary/alias-reexport2.rs
+++ b/tests/rustdoc/reexport/auxiliary/alias-reexport2.rs
diff --git a/tests/rustdoc/reexport/auxiliary/all-item-types.rs b/tests/rustdoc/reexport/auxiliary/all-item-types.rs
new file mode 100644
index 00000000000..f94bd998717
--- /dev/null
+++ b/tests/rustdoc/reexport/auxiliary/all-item-types.rs
@@ -0,0 +1,22 @@
+#![feature(extern_types)]
+
+pub mod foo_mod {}
+extern "C" {
+    pub fn foo_ffn();
+    pub static FOO_FSTATIC: FooStruct;
+    pub type FooFType;
+}
+pub fn foo_fn() {}
+pub trait FooTrait {}
+pub struct FooStruct;
+pub enum FooEnum {}
+pub union FooUnion {
+    x: (),
+}
+pub type FooType = FooStruct;
+pub static FOO_STATIC: FooStruct = FooStruct;
+pub const FOO_CONSTANT: FooStruct = FooStruct;
+#[macro_export]
+macro_rules! foo_macro {
+    () => ();
+}
diff --git a/tests/rustdoc/auxiliary/issue-113982-doc_auto_cfg-reexport-foreign.rs b/tests/rustdoc/reexport/auxiliary/issue-113982-doc_auto_cfg-reexport-foreign.rs
index a1a716f5a41..a1a716f5a41 100644
--- a/tests/rustdoc/auxiliary/issue-113982-doc_auto_cfg-reexport-foreign.rs
+++ b/tests/rustdoc/reexport/auxiliary/issue-113982-doc_auto_cfg-reexport-foreign.rs
diff --git a/tests/rustdoc/auxiliary/issue-28927-1.rs b/tests/rustdoc/reexport/auxiliary/issue-28927-1.rs
index 688c73428dd..688c73428dd 100644
--- a/tests/rustdoc/auxiliary/issue-28927-1.rs
+++ b/tests/rustdoc/reexport/auxiliary/issue-28927-1.rs
diff --git a/tests/rustdoc/auxiliary/issue-28927-2.rs b/tests/rustdoc/reexport/auxiliary/issue-28927-2.rs
index 7c0937fce20..7c0937fce20 100644
--- a/tests/rustdoc/auxiliary/issue-28927-2.rs
+++ b/tests/rustdoc/reexport/auxiliary/issue-28927-2.rs
diff --git a/tests/rustdoc/auxiliary/primitive-reexport.rs b/tests/rustdoc/reexport/auxiliary/primitive-reexport.rs
index 7c85038674b..7c85038674b 100644
--- a/tests/rustdoc/auxiliary/primitive-reexport.rs
+++ b/tests/rustdoc/reexport/auxiliary/primitive-reexport.rs
diff --git a/tests/rustdoc/auxiliary/reexport-check.rs b/tests/rustdoc/reexport/auxiliary/reexport-check.rs
index 672ccb1cf0e..672ccb1cf0e 100644
--- a/tests/rustdoc/auxiliary/reexport-check.rs
+++ b/tests/rustdoc/reexport/auxiliary/reexport-check.rs
diff --git a/tests/rustdoc/auxiliary/reexport-doc-aux.rs b/tests/rustdoc/reexport/auxiliary/reexport-doc-aux.rs
index 3400717eba1..3400717eba1 100644
--- a/tests/rustdoc/auxiliary/reexport-doc-aux.rs
+++ b/tests/rustdoc/reexport/auxiliary/reexport-doc-aux.rs
diff --git a/tests/rustdoc/auxiliary/reexports.rs b/tests/rustdoc/reexport/auxiliary/reexports.rs
index 4336993a36e..4336993a36e 100644
--- a/tests/rustdoc/auxiliary/reexports.rs
+++ b/tests/rustdoc/reexport/auxiliary/reexports.rs
diff --git a/tests/rustdoc/blanket-reexport-item.rs b/tests/rustdoc/reexport/blanket-reexport-item.rs
index 199a47019a2..199a47019a2 100644
--- a/tests/rustdoc/blanket-reexport-item.rs
+++ b/tests/rustdoc/reexport/blanket-reexport-item.rs
diff --git a/tests/rustdoc/cfg_doc_reexport.rs b/tests/rustdoc/reexport/cfg_doc_reexport.rs
index 44ec3663284..44ec3663284 100644
--- a/tests/rustdoc/cfg_doc_reexport.rs
+++ b/tests/rustdoc/reexport/cfg_doc_reexport.rs
diff --git a/tests/rustdoc/doc-hidden-reexports-109449.rs b/tests/rustdoc/reexport/doc-hidden-reexports-109449.rs
index 78b9214300a..78b9214300a 100644
--- a/tests/rustdoc/doc-hidden-reexports-109449.rs
+++ b/tests/rustdoc/reexport/doc-hidden-reexports-109449.rs
diff --git a/tests/rustdoc/doc_auto_cfg-reexport-foreign-113982.rs b/tests/rustdoc/reexport/doc_auto_cfg-reexport-foreign-113982.rs
index 76b25127a9c..76b25127a9c 100644
--- a/tests/rustdoc/doc_auto_cfg-reexport-foreign-113982.rs
+++ b/tests/rustdoc/reexport/doc_auto_cfg-reexport-foreign-113982.rs
diff --git a/tests/rustdoc/duplicated-glob-reexport-60522.rs b/tests/rustdoc/reexport/duplicated-glob-reexport-60522.rs
index a75a21c2dac..a75a21c2dac 100644
--- a/tests/rustdoc/duplicated-glob-reexport-60522.rs
+++ b/tests/rustdoc/reexport/duplicated-glob-reexport-60522.rs
diff --git a/tests/rustdoc/enum-variant-reexport-35488.rs b/tests/rustdoc/reexport/enum-variant-reexport-35488.rs
index b8e42ef7a89..b8e42ef7a89 100644
--- a/tests/rustdoc/enum-variant-reexport-35488.rs
+++ b/tests/rustdoc/reexport/enum-variant-reexport-35488.rs
diff --git a/tests/rustdoc/foreigntype-reexport.rs b/tests/rustdoc/reexport/foreigntype-reexport.rs
index 22c1852adf5..22c1852adf5 100644
--- a/tests/rustdoc/foreigntype-reexport.rs
+++ b/tests/rustdoc/reexport/foreigntype-reexport.rs
diff --git a/tests/rustdoc/glob-reexport-attribute-merge-120487.rs b/tests/rustdoc/reexport/glob-reexport-attribute-merge-120487.rs
index 5b918e0ffd9..5b918e0ffd9 100644
--- a/tests/rustdoc/glob-reexport-attribute-merge-120487.rs
+++ b/tests/rustdoc/reexport/glob-reexport-attribute-merge-120487.rs
diff --git a/tests/rustdoc/glob-reexport-attribute-merge-doc-auto-cfg.rs b/tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs
index d0a2165ec8a..d0a2165ec8a 100644
--- a/tests/rustdoc/glob-reexport-attribute-merge-doc-auto-cfg.rs
+++ b/tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs
diff --git a/tests/rustdoc/ice-reexport-crate-root-28927.rs b/tests/rustdoc/reexport/ice-reexport-crate-root-28927.rs
index b4215f7d1aa..b4215f7d1aa 100644
--- a/tests/rustdoc/ice-reexport-crate-root-28927.rs
+++ b/tests/rustdoc/reexport/ice-reexport-crate-root-28927.rs
diff --git a/tests/rustdoc/local-reexport-doc.rs b/tests/rustdoc/reexport/local-reexport-doc.rs
index 6db8f999d29..6db8f999d29 100644
--- a/tests/rustdoc/local-reexport-doc.rs
+++ b/tests/rustdoc/reexport/local-reexport-doc.rs
diff --git a/tests/rustdoc/no-compiler-reexport.rs b/tests/rustdoc/reexport/no-compiler-reexport.rs
index 355d47d7ba7..355d47d7ba7 100644
--- a/tests/rustdoc/no-compiler-reexport.rs
+++ b/tests/rustdoc/reexport/no-compiler-reexport.rs
diff --git a/tests/rustdoc/overlapping-reexport-105735-2.rs b/tests/rustdoc/reexport/overlapping-reexport-105735-2.rs
index fa43924ff4e..fa43924ff4e 100644
--- a/tests/rustdoc/overlapping-reexport-105735-2.rs
+++ b/tests/rustdoc/reexport/overlapping-reexport-105735-2.rs
diff --git a/tests/rustdoc/overlapping-reexport-105735.rs b/tests/rustdoc/reexport/overlapping-reexport-105735.rs
index d1b5c0b6749..d1b5c0b6749 100644
--- a/tests/rustdoc/overlapping-reexport-105735.rs
+++ b/tests/rustdoc/reexport/overlapping-reexport-105735.rs
diff --git a/tests/rustdoc/primitive-reexport.rs b/tests/rustdoc/reexport/primitive-reexport.rs
index 9b23b24fc93..9b23b24fc93 100644
--- a/tests/rustdoc/primitive-reexport.rs
+++ b/tests/rustdoc/reexport/primitive-reexport.rs
diff --git a/tests/rustdoc/pub-reexport-of-pub-reexport-46506.rs b/tests/rustdoc/reexport/pub-reexport-of-pub-reexport-46506.rs
index f9569902927..f9569902927 100644
--- a/tests/rustdoc/pub-reexport-of-pub-reexport-46506.rs
+++ b/tests/rustdoc/reexport/pub-reexport-of-pub-reexport-46506.rs
diff --git a/tests/rustdoc/reexport-attr-merge.rs b/tests/rustdoc/reexport/reexport-attr-merge.rs
index aef302eb0b2..aef302eb0b2 100644
--- a/tests/rustdoc/reexport-attr-merge.rs
+++ b/tests/rustdoc/reexport/reexport-attr-merge.rs
diff --git a/tests/rustdoc/reexport-cfg.rs b/tests/rustdoc/reexport/reexport-cfg.rs
index 73b66824316..73b66824316 100644
--- a/tests/rustdoc/reexport-cfg.rs
+++ b/tests/rustdoc/reexport/reexport-cfg.rs
diff --git a/tests/rustdoc/reexport-check.rs b/tests/rustdoc/reexport/reexport-check.rs
index fc10e3aadd0..fc10e3aadd0 100644
--- a/tests/rustdoc/reexport-check.rs
+++ b/tests/rustdoc/reexport/reexport-check.rs
diff --git a/tests/rustdoc/reexport-dep-foreign-fn.rs b/tests/rustdoc/reexport/reexport-dep-foreign-fn.rs
index 1b63fcff017..1b63fcff017 100644
--- a/tests/rustdoc/reexport-dep-foreign-fn.rs
+++ b/tests/rustdoc/reexport/reexport-dep-foreign-fn.rs
diff --git a/tests/rustdoc/reexport-doc-hidden-inside-private.rs b/tests/rustdoc/reexport/reexport-doc-hidden-inside-private.rs
index bae2aa78ec7..bae2aa78ec7 100644
--- a/tests/rustdoc/reexport-doc-hidden-inside-private.rs
+++ b/tests/rustdoc/reexport/reexport-doc-hidden-inside-private.rs
diff --git a/tests/rustdoc/reexport-doc-hidden.rs b/tests/rustdoc/reexport/reexport-doc-hidden.rs
index 1468e9ad957..1468e9ad957 100644
--- a/tests/rustdoc/reexport-doc-hidden.rs
+++ b/tests/rustdoc/reexport/reexport-doc-hidden.rs
diff --git a/tests/rustdoc/reexport-doc.rs b/tests/rustdoc/reexport/reexport-doc.rs
index 0c20de41231..0c20de41231 100644
--- a/tests/rustdoc/reexport-doc.rs
+++ b/tests/rustdoc/reexport/reexport-doc.rs
diff --git a/tests/rustdoc/reexport-hidden-macro.rs b/tests/rustdoc/reexport/reexport-hidden-macro.rs
index 7345149c645..7345149c645 100644
--- a/tests/rustdoc/reexport-hidden-macro.rs
+++ b/tests/rustdoc/reexport/reexport-hidden-macro.rs
diff --git a/tests/rustdoc/reexport-macro.rs b/tests/rustdoc/reexport/reexport-macro.rs
index 7e041eb90ba..7e041eb90ba 100644
--- a/tests/rustdoc/reexport-macro.rs
+++ b/tests/rustdoc/reexport/reexport-macro.rs
diff --git a/tests/rustdoc/reexport-of-doc-hidden.rs b/tests/rustdoc/reexport/reexport-of-doc-hidden.rs
index e901d0ff8a2..e901d0ff8a2 100644
--- a/tests/rustdoc/reexport-of-doc-hidden.rs
+++ b/tests/rustdoc/reexport/reexport-of-doc-hidden.rs
diff --git a/tests/rustdoc/reexport-of-reexport-108679.rs b/tests/rustdoc/reexport/reexport-of-reexport-108679.rs
index 0d2faf71d32..0d2faf71d32 100644
--- a/tests/rustdoc/reexport-of-reexport-108679.rs
+++ b/tests/rustdoc/reexport/reexport-of-reexport-108679.rs
diff --git a/tests/rustdoc/reexport-stability-tags-deprecated-and-portability.rs b/tests/rustdoc/reexport/reexport-stability-tags-deprecated-and-portability.rs
index f83f28f458e..f83f28f458e 100644
--- a/tests/rustdoc/reexport-stability-tags-deprecated-and-portability.rs
+++ b/tests/rustdoc/reexport/reexport-stability-tags-deprecated-and-portability.rs
diff --git a/tests/rustdoc/reexport-stability-tags-unstable-and-portability.rs b/tests/rustdoc/reexport/reexport-stability-tags-unstable-and-portability.rs
index adf3eed204a..adf3eed204a 100644
--- a/tests/rustdoc/reexport-stability-tags-unstable-and-portability.rs
+++ b/tests/rustdoc/reexport/reexport-stability-tags-unstable-and-portability.rs
diff --git a/tests/rustdoc/reexport-trait-from-hidden-111064-2.rs b/tests/rustdoc/reexport/reexport-trait-from-hidden-111064-2.rs
index 61060b3ff7c..61060b3ff7c 100644
--- a/tests/rustdoc/reexport-trait-from-hidden-111064-2.rs
+++ b/tests/rustdoc/reexport/reexport-trait-from-hidden-111064-2.rs
diff --git a/tests/rustdoc/reexport-trait-from-hidden-111064.rs b/tests/rustdoc/reexport/reexport-trait-from-hidden-111064.rs
index 8b9ad7616ea..8b9ad7616ea 100644
--- a/tests/rustdoc/reexport-trait-from-hidden-111064.rs
+++ b/tests/rustdoc/reexport/reexport-trait-from-hidden-111064.rs
diff --git a/tests/rustdoc/reexports-of-same-name.rs b/tests/rustdoc/reexport/reexports-of-same-name.rs
index 6e5d328b081..6e5d328b081 100644
--- a/tests/rustdoc/reexports-of-same-name.rs
+++ b/tests/rustdoc/reexport/reexports-of-same-name.rs
diff --git a/tests/rustdoc/reexports-priv.rs b/tests/rustdoc/reexport/reexports-priv.rs
index 4521b4feebc..4521b4feebc 100644
--- a/tests/rustdoc/reexports-priv.rs
+++ b/tests/rustdoc/reexport/reexports-priv.rs
diff --git a/tests/rustdoc/reexports.rs b/tests/rustdoc/reexport/reexports.rs
index b17e9cd719a..b17e9cd719a 100644
--- a/tests/rustdoc/reexports.rs
+++ b/tests/rustdoc/reexport/reexports.rs
diff --git a/tests/rustdoc/assoc-type-source-link.rs b/tests/rustdoc/source-code-pages/assoc-type-source-link.rs
index a955a67a457..a955a67a457 100644
--- a/tests/rustdoc/assoc-type-source-link.rs
+++ b/tests/rustdoc/source-code-pages/assoc-type-source-link.rs
diff --git a/tests/rustdoc/auxiliary/issue-26606-macro.rs b/tests/rustdoc/source-code-pages/auxiliary/issue-26606-macro.rs
index d60d32526aa..d60d32526aa 100644
--- a/tests/rustdoc/auxiliary/issue-26606-macro.rs
+++ b/tests/rustdoc/source-code-pages/auxiliary/issue-26606-macro.rs
diff --git a/tests/rustdoc/auxiliary/issue-34274.rs b/tests/rustdoc/source-code-pages/auxiliary/issue-34274.rs
index c46660579a8..c46660579a8 100644
--- a/tests/rustdoc/auxiliary/issue-34274.rs
+++ b/tests/rustdoc/source-code-pages/auxiliary/issue-34274.rs
diff --git a/tests/rustdoc/auxiliary/source-code-bar.rs b/tests/rustdoc/source-code-pages/auxiliary/source-code-bar.rs
index 8700d688ef7..8700d688ef7 100644
--- a/tests/rustdoc/auxiliary/source-code-bar.rs
+++ b/tests/rustdoc/source-code-pages/auxiliary/source-code-bar.rs
diff --git a/tests/rustdoc/auxiliary/source_code.rs b/tests/rustdoc/source-code-pages/auxiliary/source_code.rs
index 72a5c1a0ae9..72a5c1a0ae9 100644
--- a/tests/rustdoc/auxiliary/source_code.rs
+++ b/tests/rustdoc/source-code-pages/auxiliary/source_code.rs
diff --git a/tests/rustdoc/auxiliary/src-links-external.rs b/tests/rustdoc/source-code-pages/auxiliary/src-links-external.rs
index 4a835673a59..4a835673a59 100644
--- a/tests/rustdoc/auxiliary/src-links-external.rs
+++ b/tests/rustdoc/source-code-pages/auxiliary/src-links-external.rs
diff --git a/tests/rustdoc/check-source-code-urls-to-def-std.rs b/tests/rustdoc/source-code-pages/check-source-code-urls-to-def-std.rs
index 42468f7dde6..42468f7dde6 100644
--- a/tests/rustdoc/check-source-code-urls-to-def-std.rs
+++ b/tests/rustdoc/source-code-pages/check-source-code-urls-to-def-std.rs
diff --git a/tests/rustdoc/check-source-code-urls-to-def.rs b/tests/rustdoc/source-code-pages/check-source-code-urls-to-def.rs
index d701b88bf9f..d701b88bf9f 100644
--- a/tests/rustdoc/check-source-code-urls-to-def.rs
+++ b/tests/rustdoc/source-code-pages/check-source-code-urls-to-def.rs
diff --git a/tests/rustdoc/doc-hidden-source.rs b/tests/rustdoc/source-code-pages/doc-hidden-source.rs
index b6bc622dd58..b6bc622dd58 100644
--- a/tests/rustdoc/doc-hidden-source.rs
+++ b/tests/rustdoc/source-code-pages/doc-hidden-source.rs
diff --git a/tests/rustdoc/html-no-source.rs b/tests/rustdoc/source-code-pages/html-no-source.rs
index 248afbd00ef..248afbd00ef 100644
--- a/tests/rustdoc/html-no-source.rs
+++ b/tests/rustdoc/source-code-pages/html-no-source.rs
diff --git a/tests/rustdoc/source-code-highlight.rs b/tests/rustdoc/source-code-pages/source-code-highlight.rs
index f1c905e64c0..f1c905e64c0 100644
--- a/tests/rustdoc/source-code-highlight.rs
+++ b/tests/rustdoc/source-code-pages/source-code-highlight.rs
diff --git a/tests/rustdoc/source-file.rs b/tests/rustdoc/source-code-pages/source-file.rs
index 6cff5edf146..6cff5edf146 100644
--- a/tests/rustdoc/source-file.rs
+++ b/tests/rustdoc/source-code-pages/source-file.rs
diff --git a/tests/rustdoc/source-line-numbers.rs b/tests/rustdoc/source-code-pages/source-line-numbers.rs
index 0b654b1a004..0b654b1a004 100644
--- a/tests/rustdoc/source-line-numbers.rs
+++ b/tests/rustdoc/source-code-pages/source-line-numbers.rs
diff --git a/tests/rustdoc/source-version-separator.rs b/tests/rustdoc/source-code-pages/source-version-separator.rs
index 78b9d364d21..78b9d364d21 100644
--- a/tests/rustdoc/source-version-separator.rs
+++ b/tests/rustdoc/source-code-pages/source-version-separator.rs
diff --git a/tests/rustdoc/src-link-external-macro-26606.rs b/tests/rustdoc/source-code-pages/src-link-external-macro-26606.rs
index 0ce829f06f5..0ce829f06f5 100644
--- a/tests/rustdoc/src-link-external-macro-26606.rs
+++ b/tests/rustdoc/source-code-pages/src-link-external-macro-26606.rs
diff --git a/tests/rustdoc/src-links-auto-impls.rs b/tests/rustdoc/source-code-pages/src-links-auto-impls.rs
index 5a777f59b7e..5a777f59b7e 100644
--- a/tests/rustdoc/src-links-auto-impls.rs
+++ b/tests/rustdoc/source-code-pages/src-links-auto-impls.rs
diff --git a/tests/rustdoc/src-links-external.rs b/tests/rustdoc/source-code-pages/src-links-external.rs
index e8acbf1b9b4..e8acbf1b9b4 100644
--- a/tests/rustdoc/src-links-external.rs
+++ b/tests/rustdoc/source-code-pages/src-links-external.rs
diff --git a/tests/rustdoc/src-links-implementor-43893.rs b/tests/rustdoc/source-code-pages/src-links-implementor-43893.rs
index d9abdcde08d..d9abdcde08d 100644
--- a/tests/rustdoc/src-links-implementor-43893.rs
+++ b/tests/rustdoc/source-code-pages/src-links-implementor-43893.rs
diff --git a/tests/rustdoc/src-links-inlined-34274.rs b/tests/rustdoc/source-code-pages/src-links-inlined-34274.rs
index 8675ae4736e..8675ae4736e 100644
--- a/tests/rustdoc/src-links-inlined-34274.rs
+++ b/tests/rustdoc/source-code-pages/src-links-inlined-34274.rs
diff --git a/tests/rustdoc/src-links.rs b/tests/rustdoc/source-code-pages/src-links.rs
index 24039a5d84e..24039a5d84e 100644
--- a/tests/rustdoc/src-links.rs
+++ b/tests/rustdoc/source-code-pages/src-links.rs
diff --git a/tests/rustdoc/src-links/compiletest-ignore-dir b/tests/rustdoc/source-code-pages/src-links/compiletest-ignore-dir
index e69de29bb2d..e69de29bb2d 100644
--- a/tests/rustdoc/src-links/compiletest-ignore-dir
+++ b/tests/rustdoc/source-code-pages/src-links/compiletest-ignore-dir
diff --git a/tests/rustdoc/src-links/fizz.rs b/tests/rustdoc/source-code-pages/src-links/fizz.rs
index d2b76b1cec8..d2b76b1cec8 100644
--- a/tests/rustdoc/src-links/fizz.rs
+++ b/tests/rustdoc/source-code-pages/src-links/fizz.rs
diff --git a/tests/rustdoc/src-links/mod.rs b/tests/rustdoc/source-code-pages/src-links/mod.rs
index 27b2396811a..27b2396811a 100644
--- a/tests/rustdoc/src-links/mod.rs
+++ b/tests/rustdoc/source-code-pages/src-links/mod.rs
diff --git a/tests/rustdoc/src-mod-path-absolute-26995.rs b/tests/rustdoc/source-code-pages/src-mod-path-absolute-26995.rs
index f754b64977f..f754b64977f 100644
--- a/tests/rustdoc/src-mod-path-absolute-26995.rs
+++ b/tests/rustdoc/source-code-pages/src-mod-path-absolute-26995.rs
diff --git a/tests/rustdoc/version-separator-without-source.rs b/tests/rustdoc/source-code-pages/version-separator-without-source.rs
index 7cd1780f1d3..7cd1780f1d3 100644
--- a/tests/rustdoc/version-separator-without-source.rs
+++ b/tests/rustdoc/source-code-pages/version-separator-without-source.rs
diff --git a/tests/ui-fulldeps/stable-mir/check_assoc_items.rs b/tests/ui-fulldeps/stable-mir/check_assoc_items.rs
index 755bec8747b..bb95bedf973 100644
--- a/tests/ui-fulldeps/stable-mir/check_assoc_items.rs
+++ b/tests/ui-fulldeps/stable-mir/check_assoc_items.rs
@@ -17,13 +17,13 @@ extern crate rustc_driver;
 extern crate rustc_interface;
 extern crate stable_mir;
 
-use std::io::Write;
 use std::collections::HashSet;
-use stable_mir::CrateDef;
-use stable_mir::*;
-use stable_mir::ty::*;
+use std::io::Write;
 use std::ops::ControlFlow;
 
+use stable_mir::ty::*;
+use stable_mir::{CrateDef, *};
+
 const CRATE_NAME: &str = "crate_assoc_items";
 
 /// This function uses the Stable MIR APIs to get information about the test crate.
@@ -45,30 +45,30 @@ fn test_assoc_items() -> ControlFlow<()> {
     let local_impls = local_crate.trait_impls();
     let local_traits = local_crate.trait_decls();
 
-    let trait_assoc_item_defs: Vec<AssocDef> = local_traits[0].associated_items()
-        .iter().map(|assoc_item| assoc_item.def_id).collect();
+    let trait_assoc_item_defs: Vec<AssocDef> =
+        local_traits[0].associated_items().iter().map(|assoc_item| assoc_item.def_id).collect();
     check_items(
         &trait_assoc_item_defs,
         &[
-            "ATrait::{anon_assoc#0}",
+            "ATrait::rpitit::{anon_assoc#0}",
             "ATrait::rpitit",
             "ATrait::Assoc",
             "ATrait::assoc_fn_no_self",
             "ATrait::assoc_fn_has_self",
-        ]
+        ],
     );
 
-    let impl_assoc_item_defs: Vec<AssocDef> = local_impls[0].associated_items()
-        .iter().map(|assoc_item| assoc_item.def_id).collect();
+    let impl_assoc_item_defs: Vec<AssocDef> =
+        local_impls[0].associated_items().iter().map(|assoc_item| assoc_item.def_id).collect();
     check_items(
         &impl_assoc_item_defs,
         &[
-            "<AStruct as ATrait>::{anon_assoc#0}",
+            "<AStruct as ATrait>::rpitit::{anon_assoc#0}",
             "<AStruct as ATrait>::rpitit",
             "<AStruct as ATrait>::Assoc",
             "<AStruct as ATrait>::assoc_fn_no_self",
             "<AStruct as ATrait>::assoc_fn_has_self",
-        ]
+        ],
     );
 
     ControlFlow::Continue(())
diff --git a/tests/ui-fulldeps/stable-mir/check_attribute.rs b/tests/ui-fulldeps/stable-mir/check_attribute.rs
index 81d5399d88a..e4cc7b104b6 100644
--- a/tests/ui-fulldeps/stable-mir/check_attribute.rs
+++ b/tests/ui-fulldeps/stable-mir/check_attribute.rs
@@ -35,12 +35,12 @@ fn test_stable_mir() -> ControlFlow<()> {
 fn test_tool(items: &CrateItems) {
     let rustfmt_fn = *get_item(&items, "do_not_format").unwrap();
     let rustfmt_attrs = rustfmt_fn.tool_attrs(&["rustfmt".to_string(), "skip".to_string()]);
-    assert_eq!(rustfmt_attrs[0].as_str(), "#[rustfmt::skip]");
+    assert_eq!(rustfmt_attrs[0].as_str(), "#[rustfmt::skip]\n");
 
     let clippy_fn = *get_item(&items, "complex_fn").unwrap();
     let clippy_attrs = clippy_fn.tool_attrs(&["clippy".to_string(),
                                                "cyclomatic_complexity".to_string()]);
-    assert_eq!(clippy_attrs[0].as_str(), "#[clippy::cyclomatic_complexity = \"100\"]");
+    assert_eq!(clippy_attrs[0].as_str(), "#[clippy::cyclomatic_complexity = \"100\"]\n");
 }
 
 fn get_item<'a>(
diff --git a/tests/ui/abi/lib-defaults.rs b/tests/ui/abi/lib-defaults.rs
deleted file mode 100644
index 2c2cad4f82d..00000000000
--- a/tests/ui/abi/lib-defaults.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-//@ run-pass
-//@ dont-check-compiler-stderr (rust-lang/rust#54222)
-
-//@ compile-flags: -lrust_test_helpers
-
-#[link(name = "rust_test_helpers", kind = "static")]
-extern "C" {
-    pub fn rust_dbg_extern_identity_u32(x: u32) -> u32;
-}
-
-fn main() {
-    unsafe {
-        rust_dbg_extern_identity_u32(42);
-    }
-}
diff --git a/tests/ui/annotate-snippet/missing-type.rs b/tests/ui/annotate-snippet/missing-type.rs
index ea1c2521103..bfe8ab2f5ff 100644
--- a/tests/ui/annotate-snippet/missing-type.rs
+++ b/tests/ui/annotate-snippet/missing-type.rs
@@ -1,6 +1,7 @@
 //@ compile-flags: --error-format human-annotate-rs -Z unstable-options
-//@ error-pattern:cannot find type `Iter` in this scope
 
 pub fn main() {
     let x: Iter;
 }
+
+//~? RAW cannot find type `Iter` in this scope
diff --git a/tests/ui/annotate-snippet/missing-type.stderr b/tests/ui/annotate-snippet/missing-type.stderr
index 89ce19c182f..c16f022a77f 100644
--- a/tests/ui/annotate-snippet/missing-type.stderr
+++ b/tests/ui/annotate-snippet/missing-type.stderr
@@ -1,5 +1,5 @@
 error[E0412]: cannot find type `Iter` in this scope
-  --> $DIR/missing-type.rs:5:12
+  --> $DIR/missing-type.rs:4:12
    |
 LL |     let x: Iter;
    |            ^^^^ not found in this scope
diff --git a/tests/ui/annotate-snippet/multispan.rs b/tests/ui/annotate-snippet/multispan.rs
index b7cf22eebcb..c2054f62d24 100644
--- a/tests/ui/annotate-snippet/multispan.rs
+++ b/tests/ui/annotate-snippet/multispan.rs
@@ -1,5 +1,4 @@
 //@ proc-macro: multispan.rs
-//@ error-pattern:hello to you, too!
 //@ compile-flags: --error-format human-annotate-rs -Z unstable-options
 
 #![feature(proc_macro_hygiene)]
@@ -27,3 +26,5 @@ fn main() {
     hello!(whoah. hi di hi di ho);
     hello!(hi good hi and good bye);
 }
+
+//~? RAW hello to you, too!
diff --git a/tests/ui/annotate-snippet/multispan.stderr b/tests/ui/annotate-snippet/multispan.stderr
index 833b6773032..baed54c59a4 100644
--- a/tests/ui/annotate-snippet/multispan.stderr
+++ b/tests/ui/annotate-snippet/multispan.stderr
@@ -1,41 +1,41 @@
 error: hello to you, too!
-  --> $DIR/multispan.rs:16:5
+  --> $DIR/multispan.rs:15:5
    |
 LL |     hello!(hi);
    |     ^^^^^^^^^^
    |
 error: hello to you, too!
-  --> $DIR/multispan.rs:19:5
+  --> $DIR/multispan.rs:18:5
    |
 LL |     hello!(hi hi);
    |     ^^^^^^^^^^^^^
    |
 error: hello to you, too!
-  --> $DIR/multispan.rs:22:5
+  --> $DIR/multispan.rs:21:5
    |
 LL |     hello!(hi hi hi);
    |     ^^^^^^^^^^^^^^^^
    |
 error: hello to you, too!
-  --> $DIR/multispan.rs:25:5
+  --> $DIR/multispan.rs:24:5
    |
 LL |     hello!(hi hey hi yo hi beep beep hi hi);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 error: hello to you, too!
-  --> $DIR/multispan.rs:26:5
+  --> $DIR/multispan.rs:25:5
    |
 LL |     hello!(hi there, hi how are you? hi... hi.);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 error: hello to you, too!
-  --> $DIR/multispan.rs:27:5
+  --> $DIR/multispan.rs:26:5
    |
 LL |     hello!(whoah. hi di hi di ho);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 error: hello to you, too!
-  --> $DIR/multispan.rs:28:5
+  --> $DIR/multispan.rs:27:5
    |
 LL |     hello!(hi good hi and good bye);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/asm/global-asm-mono-sym-fn.rs b/tests/ui/asm/global-asm-mono-sym-fn.rs
new file mode 100644
index 00000000000..e584a98badb
--- /dev/null
+++ b/tests/ui/asm/global-asm-mono-sym-fn.rs
@@ -0,0 +1,27 @@
+// Test that we're properly monomorphizing sym args in global asm blocks
+// that point to associated items.
+
+//@ edition: 2021
+//@ needs-asm-support
+//@ only-x86_64-unknown-linux-gnu
+//@ build-pass
+
+#![no_main]
+
+use std::arch::global_asm;
+
+fn foo() {
+    loop {}
+}
+
+trait Foo {
+    fn bar();
+}
+
+impl Foo for i32 {
+    fn bar() {
+        loop {}
+    }
+}
+
+global_asm!(".global main", "main:", "call {}", sym <i32 as Foo>::bar);
diff --git a/tests/ui/asm/naked-asm-mono-sym-fn.rs b/tests/ui/asm/naked-asm-mono-sym-fn.rs
new file mode 100644
index 00000000000..948c290c0b4
--- /dev/null
+++ b/tests/ui/asm/naked-asm-mono-sym-fn.rs
@@ -0,0 +1,35 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/140373>.
+// Test that we're properly monomorphizing sym args in naked asm blocks
+// that point to associated items.
+
+//@ edition: 2021
+//@ needs-asm-support
+//@ only-x86_64
+//@ build-pass
+
+trait Tr {
+    extern "C" fn t();
+}
+
+enum E<const C: usize> {}
+
+impl<const C: usize> Tr for E<C> {
+    extern "C" fn t() {
+        println!("Const generic: {}", C);
+    }
+}
+
+#[unsafe(naked)]
+extern "C" fn foo<U: Tr>() {
+    core::arch::naked_asm!(
+        "push rax",
+        "call {fn}",
+        "pop rax",
+        "ret",
+        fn = sym <U as Tr>::t,
+    );
+}
+
+fn main() {
+    foo::<E<42>>();
+}
diff --git a/tests/ui/asm/naked-functions.rs b/tests/ui/asm/naked-functions.rs
index cb5fde9a80b..a6f41698b41 100644
--- a/tests/ui/asm/naked-functions.rs
+++ b/tests/ui/asm/naked-functions.rs
@@ -231,3 +231,9 @@ pub extern "C" fn compatible_linkage() {
 pub extern "C" fn rustc_std_internal_symbol() {
     naked_asm!("", options(raw));
 }
+
+#[rustfmt::skip]
+#[unsafe(naked)]
+pub extern "C" fn rustfmt_skip() {
+    naked_asm!("", options(raw));
+}
diff --git a/tests/ui/associated-inherent-types/bugs/wf-check-skipped.next.stderr b/tests/ui/associated-inherent-types/bugs/wf-check-skipped.next.stderr
deleted file mode 100644
index 81ace4ebb6d..00000000000
--- a/tests/ui/associated-inherent-types/bugs/wf-check-skipped.next.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0277]: the size for values of type `[u32]` cannot be known at compilation time
-  --> $DIR/wf-check-skipped.rs:17:25
-   |
-LL | fn main() -> Foo::Bar::<Vec<[u32]>> {}
-   |                         ^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `[u32]`
-note: required by an implicit `Sized` bound in `Vec`
-  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-inherent-types/bugs/wf-check-skipped.rs b/tests/ui/associated-inherent-types/bugs/wf-check-skipped.rs
index 52df4efd13e..2949007d770 100644
--- a/tests/ui/associated-inherent-types/bugs/wf-check-skipped.rs
+++ b/tests/ui/associated-inherent-types/bugs/wf-check-skipped.rs
@@ -1,8 +1,8 @@
 //@ revisions: current next
 //@[next] compile-flags: -Znext-solver
 //@ ignore-compare-mode-next-solver (explicit revisions)
-//@[current] known-bug: #100041
-//@[current] check-pass
+//@ known-bug: #100041
+//@ check-pass
 // FIXME(inherent_associated_types): This should fail.
 
 #![feature(inherent_associated_types)]
@@ -15,4 +15,3 @@ impl Foo {
 }
 
 fn main() -> Foo::Bar::<Vec<[u32]>> {}
-//[next]~^ ERROR the size for values of type `[u32]` cannot be known at compilation time
diff --git a/tests/ui/async-await/async-closures/def-path.stderr b/tests/ui/async-await/async-closures/def-path.stderr
index 13ebaf67e54..b50e353b698 100644
--- a/tests/ui/async-await/async-closures/def-path.stderr
+++ b/tests/ui/async-await/async-closures/def-path.stderr
@@ -5,11 +5,11 @@ LL |     let x = async || {};
    |                      -- the expected `async` closure body
 LL |
 LL |     let () = x();
-   |         ^^   --- this expression has type `{static main::{closure#0}::{closure#0}<?17t> upvar_tys=?16t resume_ty=ResumeTy yield_ty=() return_ty=() witness=?6t}`
+   |         ^^   --- this expression has type `{static main::{closure#0}::{closure#0}<?17t> upvar_tys=?16t resume_ty=ResumeTy yield_ty=() return_ty=() witness=?5t}`
    |         |
    |         expected `async` closure body, found `()`
    |
-   = note: expected `async` closure body `{static main::{closure#0}::{closure#0}<?17t> upvar_tys=?16t resume_ty=ResumeTy yield_ty=() return_ty=() witness=?6t}`
+   = note: expected `async` closure body `{static main::{closure#0}::{closure#0}<?17t> upvar_tys=?16t resume_ty=ResumeTy yield_ty=() return_ty=() witness=?5t}`
                          found unit type `()`
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/attributes/export/crate-type-2.rs b/tests/ui/attributes/export/crate-type-2.rs
new file mode 100644
index 00000000000..f0379f6d797
--- /dev/null
+++ b/tests/ui/attributes/export/crate-type-2.rs
@@ -0,0 +1,2 @@
+//@ compile-flags: --crate-type=sdylib
+//~^ ERROR  `sdylib` crate type is unstable
diff --git a/tests/ui/attributes/export/crate-type-2.stderr b/tests/ui/attributes/export/crate-type-2.stderr
new file mode 100644
index 00000000000..7ce6a500113
--- /dev/null
+++ b/tests/ui/attributes/export/crate-type-2.stderr
@@ -0,0 +1,9 @@
+error[E0658]: `sdylib` crate type is unstable
+   |
+   = note: see issue #139939 <https://github.com/rust-lang/rust/issues/139939> for more information
+   = help: add `#![feature(export_stable)]` 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 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/attributes/export/crate-type.rs b/tests/ui/attributes/export/crate-type.rs
new file mode 100644
index 00000000000..bd092bbb1a1
--- /dev/null
+++ b/tests/ui/attributes/export/crate-type.rs
@@ -0,0 +1,2 @@
+#![crate_type = "sdylib"]
+//~^ ERROR  `sdylib` crate type is unstable
diff --git a/tests/ui/attributes/export/crate-type.stderr b/tests/ui/attributes/export/crate-type.stderr
new file mode 100644
index 00000000000..7ce6a500113
--- /dev/null
+++ b/tests/ui/attributes/export/crate-type.stderr
@@ -0,0 +1,9 @@
+error[E0658]: `sdylib` crate type is unstable
+   |
+   = note: see issue #139939 <https://github.com/rust-lang/rust/issues/139939> for more information
+   = help: add `#![feature(export_stable)]` 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 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/attributes/export/exportable.rs b/tests/ui/attributes/export/exportable.rs
new file mode 100644
index 00000000000..f592fce88cd
--- /dev/null
+++ b/tests/ui/attributes/export/exportable.rs
@@ -0,0 +1,139 @@
+//@ compile-flags: -Zunstable-options -Csymbol-mangling-version=v0
+
+#![crate_type = "sdylib"]
+#![allow(incomplete_features, improper_ctypes_definitions)]
+#![feature(export_stable)]
+#![feature(inherent_associated_types)]
+
+mod m {
+    #[export_stable]
+    pub struct S;
+    //~^ ERROR private items are not exportable
+
+    pub fn foo() -> i32 { 0 }
+    //~^ ERROR only functions with "C" ABI are exportable
+}
+
+#[export_stable]
+pub use m::foo;
+
+#[export_stable]
+pub mod m1 {
+    #[repr(C)]
+    pub struct S1; // OK, public type with stable repr
+
+    struct S2;
+
+    pub struct S3;
+    //~^ ERROR types with unstable layout are not exportable
+}
+
+pub mod fn_sig {
+    #[export_stable]
+    pub fn foo1() {}
+    //~^ ERROR only functions with "C" ABI are exportable
+
+    #[export_stable]
+    #[repr(C)]
+    pub struct S;
+
+    #[export_stable]
+    pub extern "C" fn foo2(x: S) -> i32 { 0 }
+
+    #[export_stable]
+    pub extern "C" fn foo3(x: Box<S>) -> i32 { 0 }
+    //~^ ERROR function with `#[export_stable]` attribute uses type `Box<fn_sig::S>`, which is not exportable
+}
+
+pub mod impl_item {
+    pub struct S;
+
+    impl S {
+        #[export_stable]
+        pub extern "C" fn foo1(&self) -> i32 { 0 }
+        //~^ ERROR method with `#[export_stable]` attribute uses type `&impl_item::S`, which is not exportable
+
+        #[export_stable]
+        pub extern "C" fn foo2(self) -> i32 { 0 }
+        //~^ ERROR method with `#[export_stable]` attribute uses type `impl_item::S`, which is not exportable
+    }
+
+    pub struct S2<T>(T);
+
+    impl<T> S2<T> {
+        #[export_stable]
+        pub extern "C" fn foo1(&self) {}
+        //~^ ERROR generic functions are not exportable
+    }
+}
+
+pub mod tys {
+    pub trait Trait {
+        type Type;
+    }
+    pub struct S;
+
+    impl Trait for S {
+        type Type = (u32,);
+    }
+
+    #[export_stable]
+    pub extern "C" fn foo1(x: <S as Trait>::Type) -> u32 { x.0 }
+    //~^ ERROR function with `#[export_stable]` attribute uses type `(u32,)`, which is not exportable
+
+    #[export_stable]
+    pub type Type = [i32; 4];
+
+    #[export_stable]
+    pub extern "C" fn foo2(_x: Type) {}
+    //~^ ERROR function with `#[export_stable]` attribute uses type `[i32; 4]`, which is not exportable
+
+    impl S {
+        #[export_stable]
+        pub type Type = extern "C" fn();
+    }
+
+    #[export_stable]
+    pub extern "C" fn foo3(_x: S::Type) {}
+    //~^ ERROR function with `#[export_stable]` attribute uses type `extern "C" fn()`, which is not exportable
+
+    #[export_stable]
+    pub extern "C" fn foo4() -> impl Copy {
+    //~^ ERROR function with `#[export_stable]` attribute uses type `impl Copy`, which is not exportable
+        0
+    }
+}
+
+pub mod privacy {
+    #[export_stable]
+    #[repr(C)]
+    pub struct S1 {
+        pub x: i32
+    }
+
+    #[export_stable]
+    #[repr(C)]
+    pub struct S2 {
+    //~^ ERROR ADT types with private fields are not exportable
+        x: i32
+    }
+
+    #[export_stable]
+    #[repr(i32)]
+    enum E {
+    //~^ ERROR private items are not exportable
+        Variant1 { x: i32 }
+    }
+}
+
+pub mod use_site {
+    #[export_stable]
+    pub trait Trait {}
+    //~^ ERROR trait's are not exportable
+
+    #[export_stable]
+    pub const C: i32 = 0;
+    //~^ ERROR constant's are not exportable
+}
+
+fn main() {}
diff --git a/tests/ui/attributes/export/exportable.stderr b/tests/ui/attributes/export/exportable.stderr
new file mode 100644
index 00000000000..0f6469d35c3
--- /dev/null
+++ b/tests/ui/attributes/export/exportable.stderr
@@ -0,0 +1,130 @@
+error: private items are not exportable
+  --> $DIR/exportable.rs:10:5
+   |
+LL |     pub struct S;
+   |     ^^^^^^^^^^^^
+   |
+note: is only usable at visibility `pub(crate)`
+  --> $DIR/exportable.rs:10:5
+   |
+LL |     pub struct S;
+   |     ^^^^^^^^^^^^
+
+error: private items are not exportable
+  --> $DIR/exportable.rs:123:5
+   |
+LL |     enum E {
+   |     ^^^^^^
+   |
+note: is only usable at visibility `pub(self)`
+  --> $DIR/exportable.rs:123:5
+   |
+LL |     enum E {
+   |     ^^^^^^
+
+error: trait's are not exportable
+  --> $DIR/exportable.rs:131:5
+   |
+LL |     pub trait Trait {}
+   |     ^^^^^^^^^^^^^^^
+
+error: constant's are not exportable
+  --> $DIR/exportable.rs:135:5
+   |
+LL |     pub const C: i32 = 0;
+   |     ^^^^^^^^^^^^^^^^
+
+error: only functions with "C" ABI are exportable
+  --> $DIR/exportable.rs:13:5
+   |
+LL |     pub fn foo() -> i32 { 0 }
+   |     ^^^^^^^^^^^^^^^^^^^
+
+error: types with unstable layout are not exportable
+  --> $DIR/exportable.rs:27:5
+   |
+LL |     pub struct S3;
+   |     ^^^^^^^^^^^^^
+
+error: only functions with "C" ABI are exportable
+  --> $DIR/exportable.rs:33:5
+   |
+LL |     pub fn foo1() {}
+   |     ^^^^^^^^^^^^^
+
+error: function with `#[export_stable]` attribute uses type `Box<fn_sig::S>`, which is not exportable
+  --> $DIR/exportable.rs:44:5
+   |
+LL |     pub extern "C" fn foo3(x: Box<S>) -> i32 { 0 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^------^^^^^^^^
+   |                               |
+   |                               not exportable
+
+error: method with `#[export_stable]` attribute uses type `&impl_item::S`, which is not exportable
+  --> $DIR/exportable.rs:53:9
+   |
+LL |         pub extern "C" fn foo1(&self) -> i32 { 0 }
+   |         ^^^^^^^^^^^^^^^^^^^^^^^-----^^^^^^^^
+   |                                |
+   |                                not exportable
+
+error: method with `#[export_stable]` attribute uses type `impl_item::S`, which is not exportable
+  --> $DIR/exportable.rs:57:9
+   |
+LL |         pub extern "C" fn foo2(self) -> i32 { 0 }
+   |         ^^^^^^^^^^^^^^^^^^^^^^^----^^^^^^^^
+   |                                |
+   |                                not exportable
+
+error: generic functions are not exportable
+  --> $DIR/exportable.rs:65:9
+   |
+LL |         pub extern "C" fn foo1(&self) {}
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: function with `#[export_stable]` attribute uses type `(u32,)`, which is not exportable
+  --> $DIR/exportable.rs:81:5
+   |
+LL |     pub extern "C" fn foo1(x: <S as Trait>::Type) -> u32 { x.0 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^------------------^^^^^^^^
+   |                               |
+   |                               not exportable
+
+error: function with `#[export_stable]` attribute uses type `[i32; 4]`, which is not exportable
+  --> $DIR/exportable.rs:88:5
+   |
+LL |     pub extern "C" fn foo2(_x: Type) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^----^
+   |                                |
+   |                                not exportable
+
+error: function with `#[export_stable]` attribute uses type `extern "C" fn()`, which is not exportable
+  --> $DIR/exportable.rs:97:5
+   |
+LL |     pub extern "C" fn foo3(_x: S::Type) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^-------^
+   |                                |
+   |                                not exportable
+
+error: function with `#[export_stable]` attribute uses type `impl Copy`, which is not exportable
+  --> $DIR/exportable.rs:101:5
+   |
+LL |     pub extern "C" fn foo4() -> impl Copy {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------
+   |                                 |
+   |                                 not exportable
+
+error: ADT types with private fields are not exportable
+  --> $DIR/exportable.rs:116:5
+   |
+LL |     pub struct S2 {
+   |     ^^^^^^^^^^^^^
+   |
+note: `x` is private
+  --> $DIR/exportable.rs:118:9
+   |
+LL |         x: i32
+   |         ^^^^^^
+
+error: aborting due to 16 previous errors
+
diff --git a/tests/ui/attributes/export/lang-item.rs b/tests/ui/attributes/export/lang-item.rs
new file mode 100644
index 00000000000..b923b41a957
--- /dev/null
+++ b/tests/ui/attributes/export/lang-item.rs
@@ -0,0 +1,8 @@
+#![feature(no_core, lang_items, export_stable)]
+#![allow(incomplete_features)]
+#![crate_type = "sdylib"]
+#![no_core]
+
+#[lang = "sized"]
+//~^ ERROR lang items are not allowed in stable dylibs
+trait Sized {}
diff --git a/tests/ui/attributes/export/lang-item.stderr b/tests/ui/attributes/export/lang-item.stderr
new file mode 100644
index 00000000000..8c0741bdb6f
--- /dev/null
+++ b/tests/ui/attributes/export/lang-item.stderr
@@ -0,0 +1,8 @@
+error: lang items are not allowed in stable dylibs
+  --> $DIR/lang-item.rs:6:1
+   |
+LL | #[lang = "sized"]
+   | ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/auxiliary/issue-13560-1.rs b/tests/ui/attributes/no_link/auxiliary/empty-crate-1.rs
index baca1567e1b..8bd2b3353b8 100644
--- a/tests/ui/auxiliary/issue-13560-1.rs
+++ b/tests/ui/attributes/no_link/auxiliary/empty-crate-1.rs
@@ -1,3 +1 @@
-//@ no-prefer-dynamic
-
 #![crate_type = "dylib"]
diff --git a/tests/ui/auxiliary/issue-13560-2.rs b/tests/ui/attributes/no_link/auxiliary/empty-crate-2.rs
index 1adaf2b0379..1adaf2b0379 100644
--- a/tests/ui/auxiliary/issue-13560-2.rs
+++ b/tests/ui/attributes/no_link/auxiliary/empty-crate-2.rs
diff --git a/tests/ui/attributes/no_link/auxiliary/no_link-crate.rs b/tests/ui/attributes/no_link/auxiliary/no_link-crate.rs
new file mode 100644
index 00000000000..1c3af5431cc
--- /dev/null
+++ b/tests/ui/attributes/no_link/auxiliary/no_link-crate.rs
@@ -0,0 +1,6 @@
+//@ no-prefer-dynamic
+
+#![crate_type = "rlib"]
+
+#[macro_use] #[no_link] extern crate empty_crate_1 as t1;
+#[macro_use] extern crate empty_crate_2 as t2;
diff --git a/tests/ui/attributes/no_link/multiple-crates-and-no_link.rs b/tests/ui/attributes/no_link/multiple-crates-and-no_link.rs
new file mode 100644
index 00000000000..0e6f1deb217
--- /dev/null
+++ b/tests/ui/attributes/no_link/multiple-crates-and-no_link.rs
@@ -0,0 +1,17 @@
+//! Regression test for #13560. Previously, it was possible to
+//! trigger an assert in crate numbering if a series of crates
+//! being loaded included a "syntax-only" extern crate.
+//! But it appears we don't mess with crate numbering for
+//! `#[no_link]` crates anymore, so this test doesn't seem
+//! to test anything now.
+
+//@ run-pass
+//@ needs-crate-type: dylib
+//@ aux-build:empty-crate-1.rs
+//@ aux-build:empty-crate-2.rs
+//@ aux-build:no_link-crate.rs
+
+extern crate empty_crate_2 as t2;
+extern crate no_link_crate as t3;
+
+fn main() {}
diff --git a/tests/ui/attributes/no_link/no-link-unknown-crate.rs b/tests/ui/attributes/no_link/no-link-unknown-crate.rs
new file mode 100644
index 00000000000..3a91fa27ee3
--- /dev/null
+++ b/tests/ui/attributes/no_link/no-link-unknown-crate.rs
@@ -0,0 +1,19 @@
+//! Unfortunately the development of `#[phase]` and `#[no_link]`
+//! predates Zulip, and thus has been lost in the sands of time.
+//! Understanding the true nature of this test has been left as
+//! an exercise for the reader.
+//!
+//! But we guess from the git history that originally this
+//! test was supposed to check that we error if we can't find
+//! an extern crate annotated with `#[phase(syntax)]`,
+//! see `macro-crate-unknown-crate.rs` in
+//! <https://github.com/rust-lang/rust/pull/11151>. Later, we changed
+//! `#[phase]` to `#![feature(plugin)]` and added a `#[no_link]`.
+//!
+//! I suppose that this now tests that we still error if we can't
+//! find a `#[no_link]` extern crate?
+
+#[no_link]
+extern crate doesnt_exist; //~ ERROR can't find crate
+
+fn main() {}
diff --git a/tests/ui/no-link-unknown-crate.stderr b/tests/ui/attributes/no_link/no-link-unknown-crate.stderr
index edc248db09e..999b013866c 100644
--- a/tests/ui/no-link-unknown-crate.stderr
+++ b/tests/ui/attributes/no_link/no-link-unknown-crate.stderr
@@ -1,5 +1,5 @@
 error[E0463]: can't find crate for `doesnt_exist`
-  --> $DIR/no-link-unknown-crate.rs:2:1
+  --> $DIR/no-link-unknown-crate.rs:17:1
    |
 LL | extern crate doesnt_exist;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
diff --git a/tests/ui/auxiliary/inner_static.rs b/tests/ui/auxiliary/inner_static.rs
deleted file mode 100644
index 42dcd379d41..00000000000
--- a/tests/ui/auxiliary/inner_static.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-pub struct A<T> { pub v: T }
-pub struct B<T> { pub v: T }
-
-pub mod test {
-    pub struct A<T> { pub v: T }
-
-    impl<T> A<T> {
-        pub fn foo(&self) -> isize {
-            static a: isize = 5;
-            return a
-        }
-
-        pub fn bar(&self) -> isize {
-            static a: isize = 6;
-            return a;
-        }
-    }
-}
-
-impl<T> A<T> {
-    pub fn foo(&self) -> isize {
-        static a: isize = 1;
-        return a
-    }
-
-    pub fn bar(&self) -> isize {
-        static a: isize = 2;
-        return a;
-    }
-}
-
-impl<T> B<T> {
-    pub fn foo(&self) -> isize {
-        static a: isize = 3;
-        return a
-    }
-
-    pub fn bar(&self) -> isize {
-        static a: isize = 4;
-        return a;
-    }
-}
-
-pub fn foo() -> isize {
-    let a = A { v: () };
-    let b = B { v: () };
-    let c = test::A { v: () };
-    return a.foo() + a.bar() +
-           b.foo() + b.bar() +
-           c.foo() + c.bar();
-}
diff --git a/tests/ui/auxiliary/issue-13560-3.rs b/tests/ui/auxiliary/issue-13560-3.rs
deleted file mode 100644
index 4aab2ddc73a..00000000000
--- a/tests/ui/auxiliary/issue-13560-3.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-//@ no-prefer-dynamic
-
-#![crate_type = "rlib"]
-
-#[macro_use] #[no_link] extern crate issue_13560_1 as t1;
-#[macro_use] extern crate issue_13560_2 as t2;
diff --git a/tests/ui/bootstrap/rustc_bootstrap.rs b/tests/ui/bootstrap/rustc_bootstrap.rs
index daa28e0cdf2..fb72bba95a1 100644
--- a/tests/ui/bootstrap/rustc_bootstrap.rs
+++ b/tests/ui/bootstrap/rustc_bootstrap.rs
@@ -38,10 +38,11 @@
 // also affected by `RUSTC_BOOTSTRAP`.
 //@[force_stable] rustc-env:RUSTC_BOOTSTRAP=-1
 //@[force_stable] compile-flags: -Z unstable-options
-//@[force_stable] regex-error-pattern: error: the option `Z` is only accepted on the nightly compiler
 
 #![crate_type = "lib"]
 
 // Note: `rustc_attrs` is a perma-unstable internal feature that is unlikely to change, which is
 // used as a proxy to check `RUSTC_BOOTSTRAP` versus stability checking logic.
 #![feature(rustc_attrs)]
+
+//[force_stable]~? RAW the option `Z` is only accepted on the nightly compiler
diff --git a/tests/ui/borrowck/regions-bound-missing-bound-in-impl.rs b/tests/ui/borrowck/regions-bound-missing-bound-in-impl.rs
index 141ad5bd2c4..7c0378e068b 100644
--- a/tests/ui/borrowck/regions-bound-missing-bound-in-impl.rs
+++ b/tests/ui/borrowck/regions-bound-missing-bound-in-impl.rs
@@ -17,11 +17,11 @@ pub trait Foo<'a, 't> {
 
 impl<'a, 't> Foo<'a, 't> for &'a isize {
     fn no_bound<'b:'a>(self, b: Inv<'b>) {
-        //~^ ERROR lifetime parameters or bounds on method `no_bound` do not match
+        //~^ ERROR lifetime parameters do not match the trait definition
     }
 
     fn has_bound<'b>(self, b: Inv<'b>) {
-        //~^ ERROR lifetime parameters or bounds on method `has_bound` do not match
+        //~^ ERROR lifetime parameters do not match the trait definition
     }
 
     fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
@@ -40,7 +40,7 @@ impl<'a, 't> Foo<'a, 't> for &'a isize {
     }
 
     fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) {
-        //~^ ERROR lifetime parameters or bounds on method `wrong_bound2` do not match the trait
+        //~^ ERROR lifetime parameters do not match the trait definition
     }
 
     fn okay_bound<'b,'c,'e:'b+'c>(self, b: Inv<'b>, c: Inv<'c>, e: Inv<'e>) {
diff --git a/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr b/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr
index 5f0347bdb4d..207ca57af38 100644
--- a/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr
+++ b/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr
@@ -1,20 +1,48 @@
-error[E0195]: lifetime parameters or bounds on method `no_bound` do not match the trait declaration
-  --> $DIR/regions-bound-missing-bound-in-impl.rs:19:16
+error[E0195]: lifetime parameters do not match the trait definition
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:19:17
    |
+LL |     fn no_bound<'b:'a>(self, b: Inv<'b>) {
+   |                 ^^
+   |
+   = note: lifetime parameters differ in whether they are early- or late-bound
+note: `'b` differs between the trait and impl
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:10:17
+   |
+LL | pub trait Foo<'a, 't> {
+   | --------------------- in this trait...
 LL |     fn no_bound<'b>(self, b: Inv<'b>);
-   |                ---- lifetimes in impl do not match this method in trait
+   |                 ^^ `'b` is late-bound
 ...
+LL | impl<'a, 't> Foo<'a, 't> for &'a isize {
+   | -------------------------------------- in this impl...
 LL |     fn no_bound<'b:'a>(self, b: Inv<'b>) {
-   |                ^^^^^^^ lifetimes do not match method in trait
+   |                 ^^ -- this lifetime bound makes `'b` early-bound
+   |                 |
+   |                 `'b` is early-bound
 
-error[E0195]: lifetime parameters or bounds on method `has_bound` do not match the trait declaration
-  --> $DIR/regions-bound-missing-bound-in-impl.rs:23:17
+error[E0195]: lifetime parameters do not match the trait definition
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:23:18
+   |
+LL |     fn has_bound<'b>(self, b: Inv<'b>) {
+   |                  ^^
    |
+   = note: lifetime parameters differ in whether they are early- or late-bound
+note: `'b` differs between the trait and impl
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:11:18
+   |
+LL | pub trait Foo<'a, 't> {
+   | --------------------- in this trait...
+LL |     fn no_bound<'b>(self, b: Inv<'b>);
 LL |     fn has_bound<'b:'a>(self, b: Inv<'b>);
-   |                 ------- lifetimes in impl do not match this method in trait
+   |                  ^^ -- this lifetime bound makes `'b` early-bound
+   |                  |
+   |                  `'b` is early-bound
+...
+LL | impl<'a, 't> Foo<'a, 't> for &'a isize {
+   | -------------------------------------- in this impl...
 ...
 LL |     fn has_bound<'b>(self, b: Inv<'b>) {
-   |                 ^^^^ lifetimes do not match method in trait
+   |                  ^^ `'b` is late-bound
 
 error[E0308]: method not compatible with trait
   --> $DIR/regions-bound-missing-bound-in-impl.rs:27:5
@@ -54,14 +82,45 @@ note: ...does not necessarily outlive the lifetime `'c` as defined here
 LL |     fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
    |                        ^^
 
-error[E0195]: lifetime parameters or bounds on method `wrong_bound2` do not match the trait declaration
-  --> $DIR/regions-bound-missing-bound-in-impl.rs:42:20
+error[E0195]: lifetime parameters do not match the trait definition
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:42:30
+   |
+LL |     fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) {
+   |                              ^^^             ^^^
    |
+   = note: lifetime parameters differ in whether they are early- or late-bound
+note: `'_` differs between the trait and impl
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:13:21
+   |
+LL | pub trait Foo<'a, 't> {
+   | --------------------- in this trait...
+...
 LL |     fn wrong_bound2<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
-   |                    ---------------- lifetimes in impl do not match this method in trait
+   |                     ^^          -- this lifetime bound makes `'b` early-bound
+   |                     |
+   |                     `'b` is early-bound
+...
+LL | impl<'a, 't> Foo<'a, 't> for &'a isize {
+   | -------------------------------------- in this impl...
+...
+LL |     fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) {
+   |                              ^^^ `'_` is late-bound
+note: `'_` differs between the trait and impl
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:13:27
+   |
+LL | pub trait Foo<'a, 't> {
+   | --------------------- in this trait...
+...
+LL |     fn wrong_bound2<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
+   |                           ^^ -- this lifetime bound makes `'d` early-bound
+   |                           |
+   |                           `'d` is early-bound
+...
+LL | impl<'a, 't> Foo<'a, 't> for &'a isize {
+   | -------------------------------------- in this impl...
 ...
 LL |     fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) {
-   |                    ^ lifetimes do not match method in trait
+   |                                              ^^^ `'_` is late-bound
 
 error[E0276]: impl has stricter requirements than trait
   --> $DIR/regions-bound-missing-bound-in-impl.rs:49:26
diff --git a/tests/ui/cast/cast-alias-of-array-to-element.rs b/tests/ui/cast/cast-alias-of-array-to-element.rs
new file mode 100644
index 00000000000..124d0e0346f
--- /dev/null
+++ b/tests/ui/cast/cast-alias-of-array-to-element.rs
@@ -0,0 +1,22 @@
+//@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/203>.
+// Test that we structually normalize in the hacky `&[T; N] -> *const T` in cast.
+
+trait Mirror {
+    type Assoc: ?Sized;
+}
+impl<T: ?Sized> Mirror for T {
+    type Assoc = T;
+}
+
+struct W<'a>(&'a <[f32; 0] as Mirror>::Assoc);
+
+fn foo(x: W<'_>) -> *const f32 {
+    x.0 as *const f32
+}
+
+fn main() {}
diff --git a/tests/ui/cfg/cfg_false_no_std-2.rs b/tests/ui/cfg/cfg_false_no_std-2.rs
index 18b2c699fd7..666c90deaf0 100644
--- a/tests/ui/cfg/cfg_false_no_std-2.rs
+++ b/tests/ui/cfg/cfg_false_no_std-2.rs
@@ -1,7 +1,11 @@
 // Error, the linked empty library is `no_std` and doesn't provide a panic handler.
 
-//@ dont-require-annotations: ERROR
 //@ dont-check-compiler-stderr
+
+// NOTE: fix a panic strategy to prevent differing errors subject to target's default panic strategy
+// which changes between targets. The specific panic strategy doesn't matter for test intention.
+//@ compile-flags: -Cpanic=abort
+
 //@ aux-build: cfg_false_lib_no_std_before.rs
 
 #![no_std]
@@ -11,6 +15,3 @@ extern crate cfg_false_lib_no_std_before as _;
 fn main() {}
 
 //~? ERROR `#[panic_handler]` function required, but not found
-// FIXME: This error is target-dependent, could be served by some "optional error" annotation
-// instead of `dont-require-annotations`.
-//FIXME~? ERROR unwinding panics are not supported without std
diff --git a/tests/ui/check-cfg/and-more-diagnostic.rs b/tests/ui/check-cfg/and-more-diagnostic.rs
index 977f55e8a6d..5422829c5b3 100644
--- a/tests/ui/check-cfg/and-more-diagnostic.rs
+++ b/tests/ui/check-cfg/and-more-diagnostic.rs
@@ -5,7 +5,7 @@
 //@ no-auto-check-cfg
 //@ compile-flags: --check-cfg=cfg()
 //@ normalize-stderr: "and \d+ more" -> "and X more"
-//@ normalize-stderr: "`[a-zA-Z0-9_-]+`" -> "`xxx`"
+//@ normalize-stderr: "`[a-zA-Z0-9_\.-]+`" -> "`xxx`"
 
 fn main() {
     cfg!(target_feature = "zebra");
diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr
index 712ce941c54..eb66633f9dd 100644
--- a/tests/ui/check-cfg/target_feature.stderr
+++ b/tests/ui/check-cfg/target_feature.stderr
@@ -27,8 +27,11 @@ LL |     cfg!(target_feature = "_UNEXPECTED_VALUE");
 `amx-tf32`
 `amx-tile`
 `amx-transpose`
+`apxf`
 `atomics`
 `avx`
+`avx10.1`
+`avx10.2`
 `avx2`
 `avx512bf16`
 `avx512bitalg`
diff --git a/tests/ui/closures/opaque-upvar.rs b/tests/ui/closures/opaque-upvar.rs
new file mode 100644
index 00000000000..90e7c9ccb46
--- /dev/null
+++ b/tests/ui/closures/opaque-upvar.rs
@@ -0,0 +1,19 @@
+//@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/197>.
+// This is only an issue in the new solver, but I'm testing it in both solvers for now.
+// This has to do with the fact that the recursive `walk_dir` is a revealing use, which has not
+// yet been constrained from the defining use by the time that closure signature inference is
+// performed. We don't really care, though, since anywhere we structurally match on a type in
+// upvar analysis, we already call `structurally_resolve_type` right before `.kind()`.
+
+fn walk_dir(cb: &()) -> impl Sized {
+    || {
+        let fut = walk_dir(cb);
+    };
+}
+
+fn main() {}
diff --git a/tests/ui/closures/print/closure-print-generic-trim-off-verbose-2.stderr b/tests/ui/closures/print/closure-print-generic-trim-off-verbose-2.stderr
index b71cfc50333..bcf5759a194 100644
--- a/tests/ui/closures/print/closure-print-generic-trim-off-verbose-2.stderr
+++ b/tests/ui/closures/print/closure-print-generic-trim-off-verbose-2.stderr
@@ -9,7 +9,7 @@ LL |         let c1 : () = c;
    |                  expected due to this
    |
    = note: expected unit type `()`
-                found closure `{mod1::f<T>::{closure#0} closure_kind_ty=?8t closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=?7t}`
+                found closure `{mod1::f<T>::{closure#0} closure_kind_ty=?7t closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=?6t}`
 help: use parentheses to call this closure
    |
 LL |         let c1 : () = c();
diff --git a/tests/ui/closures/print/closure-print-generic-verbose-2.stderr b/tests/ui/closures/print/closure-print-generic-verbose-2.stderr
index 88f4dc9b92a..a8d2b07a00d 100644
--- a/tests/ui/closures/print/closure-print-generic-verbose-2.stderr
+++ b/tests/ui/closures/print/closure-print-generic-verbose-2.stderr
@@ -9,7 +9,7 @@ LL |         let c1 : () = c;
    |                  expected due to this
    |
    = note: expected unit type `()`
-                found closure `{f<T>::{closure#0} closure_kind_ty=?8t closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=?7t}`
+                found closure `{f<T>::{closure#0} closure_kind_ty=?7t closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=?6t}`
 help: use parentheses to call this closure
    |
 LL |         let c1 : () = c();
diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs b/tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs
deleted file mode 100644
index e2a00ce173d..00000000000
--- a/tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-//@ known-bug: #107975
-//@ compile-flags: -Copt-level=2
-//@ run-pass
-
-fn main() {
-    let a: usize = {
-        let v = 0u8;
-        &v as *const _ as usize
-    };
-    let b: usize = {
-        let v = 0u8;
-        &v as *const _ as usize
-    };
-
-    // `a` and `b` are not equal.
-    assert_ne!(a, b);
-    // But they are the same number.
-    assert_eq!(format!("{a}"), format!("{b}"));
-    // And they are equal.
-    assert_eq!(a, b);
-}
diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs b/tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs
deleted file mode 100644
index 15434de50f7..00000000000
--- a/tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-//@ known-bug: #107975
-//@ compile-flags: -Copt-level=2
-//@ run-pass
-
-// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1434203908
-
-fn f() -> usize {
-    let v = 0;
-    &v as *const _ as usize
-}
-
-fn main() {
-    let a = f();
-    let b = f();
-
-    // `a` and `b` are not equal.
-    assert_ne!(a, b);
-    // But they are the same number.
-    assert_eq!(format!("{a}"), format!("{b}"));
-    // And they are equal.
-    assert_eq!(a, b);
-}
diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs b/tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs
deleted file mode 100644
index f33a9e511b6..00000000000
--- a/tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-//@ known-bug: #107975
-//@ compile-flags: -Copt-level=2
-//@ run-pass
-
-// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499
-
-fn main() {
-    let a = {
-        let v = 0;
-        &v as *const _ as usize
-    };
-    let b = {
-        let v = 0;
-        &v as *const _ as usize
-    };
-
-    assert_ne!(a, b);
-    println!("{a}"); // or b
-    assert_eq!(a, b);
-}
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs
deleted file mode 100644
index b2b4934aa5f..00000000000
--- a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-//@ known-bug: #107975
-//@ compile-flags: -Copt-level=2
-//@ run-pass
-
-use std::ptr;
-
-fn main() {
-    let a: usize = {
-        let v = 0u8;
-        ptr::from_ref(&v).expose_provenance()
-    };
-    let b: usize = {
-        let v = 0u8;
-        ptr::from_ref(&v).expose_provenance()
-    };
-
-    // `a` and `b` are not equal.
-    assert_ne!(a, b);
-    // But they are the same number.
-    assert_eq!(format!("{a}"), format!("{b}"));
-    // And they are equal.
-    assert_eq!(a, b);
-}
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs
deleted file mode 100644
index bf130c9f759..00000000000
--- a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-//@ known-bug: #107975
-//@ compile-flags: -Copt-level=2
-//@ run-pass
-
-// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1434203908
-
-use std::ptr;
-
-fn f() -> usize {
-    let v = 0;
-    ptr::from_ref(&v).expose_provenance()
-}
-
-fn main() {
-    let a = f();
-    let b = f();
-
-    // `a` and `b` are not equal.
-    assert_ne!(a, b);
-    // But they are the same number.
-    assert_eq!(format!("{a}"), format!("{b}"));
-    // And they are equal.
-    assert_eq!(a, b);
-}
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs
deleted file mode 100644
index 0baf8886395..00000000000
--- a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-//@ known-bug: #107975
-//@ compile-flags: -Copt-level=2
-//@ run-pass
-
-// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499
-
-use std::ptr;
-
-fn main() {
-    let a: usize = {
-        let v = 0;
-        ptr::from_ref(&v).expose_provenance()
-    };
-    let b: usize = {
-        let v = 0;
-        ptr::from_ref(&v).expose_provenance()
-    };
-
-    assert_ne!(a, b);
-    println!("{a}"); // or b
-    assert_eq!(a, b);
-}
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs
deleted file mode 100644
index 4602ec654d1..00000000000
--- a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-//@ known-bug: #107975
-//@ compile-flags: -Copt-level=2
-//@ run-pass
-
-use std::ptr;
-
-fn main() {
-    let a: usize = {
-        let v = 0u8;
-        ptr::from_ref(&v).addr()
-    };
-    let b: usize = {
-        let v = 0u8;
-        ptr::from_ref(&v).addr()
-    };
-
-    // `a` and `b` are not equal.
-    assert_ne!(a, b);
-    // But they are the same number.
-    assert_eq!(format!("{a}"), format!("{b}"));
-    // And they are equal.
-    assert_eq!(a, b);
-}
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs
deleted file mode 100644
index 789a78c15b4..00000000000
--- a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-//@ known-bug: #107975
-//@ compile-flags: -Copt-level=2
-//@ run-pass
-
-// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1434203908
-
-use std::ptr;
-
-fn f() -> usize {
-    let v = 0;
-    ptr::from_ref(&v).addr()
-}
-
-fn main() {
-    let a = f();
-    let b = f();
-
-    // `a` and `b` are not equal.
-    assert_ne!(a, b);
-    // But they are the same number.
-    assert_eq!(format!("{a}"), format!("{b}"));
-    // And they are equal.
-    assert_eq!(a, b);
-}
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs
deleted file mode 100644
index b7165ce1e5c..00000000000
--- a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-//@ known-bug: #107975
-//@ compile-flags: -Copt-level=2
-//@ run-pass
-
-// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499
-
-use std::ptr;
-
-fn main() {
-    let a: usize = {
-        let v = 0;
-        ptr::from_ref(&v).addr()
-    };
-    let b: usize = {
-        let v = 0;
-        ptr::from_ref(&v).addr()
-    };
-
-    assert_ne!(a, b);
-    println!("{a}"); // or b
-    assert_eq!(a, b);
-}
diff --git a/tests/ui/compiletest-self-test/compile-flags-last.rs b/tests/ui/compiletest-self-test/compile-flags-last.rs
index b78a64394b8..e0743d2aea5 100644
--- a/tests/ui/compiletest-self-test/compile-flags-last.rs
+++ b/tests/ui/compiletest-self-test/compile-flags-last.rs
@@ -4,4 +4,5 @@
 // next flag as the argument of this flag.
 //
 //@ compile-flags: --cap-lints
-//@ error-pattern: Argument to option 'cap-lints' missing
+
+//~? RAW Argument to option 'cap-lints' missing
diff --git a/tests/ui/conditional-compilation/cfg-arg-invalid-7.rs b/tests/ui/conditional-compilation/cfg-arg-invalid-7.rs
index b4344f1bca5..f05adc7bf7a 100644
--- a/tests/ui/conditional-compilation/cfg-arg-invalid-7.rs
+++ b/tests/ui/conditional-compilation/cfg-arg-invalid-7.rs
@@ -1,5 +1,6 @@
 // Regression test for issue #89358.
 
 //@ compile-flags: --cfg a"
-//@ error-pattern: unterminated double quote string
-//@ error-pattern: this error occurred on the command line
+
+//~? RAW unterminated double quote string
+//~? RAW this error occurred on the command line
diff --git a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr
index 06a6a5f59d6..16512cb69e2 100644
--- a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr
+++ b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr
@@ -240,41 +240,6 @@ note: the late bound lifetime parameter is introduced here
 LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
    |              ^^
 
-error[E0747]: unresolved item provided when a constant was expected
-  --> $DIR/const-arg-in-const-arg.rs:36:24
-   |
-LL |     let _: Foo<{ bar::<N>() }>;
-   |                        ^
-   |
-help: if this generic argument was intended as a const parameter, surround it with braces
-   |
-LL |     let _: Foo<{ bar::<{ N }>() }>;
-   |                        +   +
-
-error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
-  --> $DIR/const-arg-in-const-arg.rs:38:24
-   |
-LL |     let _: Foo<{ faz::<'a>(&()) }>;
-   |                        ^^
-   |
-note: the late bound lifetime parameter is introduced here
-  --> $DIR/const-arg-in-const-arg.rs:10:14
-   |
-LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
-   |              ^^
-
-error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
-  --> $DIR/const-arg-in-const-arg.rs:41:24
-   |
-LL |     let _: Foo<{ faz::<'b>(&()) }>;
-   |                        ^^
-   |
-note: the late bound lifetime parameter is introduced here
-  --> $DIR/const-arg-in-const-arg.rs:10:14
-   |
-LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
-   |              ^^
-
 error: constant expression depends on a generic parameter
   --> $DIR/const-arg-in-const-arg.rs:25:17
    |
@@ -327,6 +292,41 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
    |              ^^
 
 error[E0747]: unresolved item provided when a constant was expected
+  --> $DIR/const-arg-in-const-arg.rs:36:24
+   |
+LL |     let _: Foo<{ bar::<N>() }>;
+   |                        ^
+   |
+help: if this generic argument was intended as a const parameter, surround it with braces
+   |
+LL |     let _: Foo<{ bar::<{ N }>() }>;
+   |                        +   +
+
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+  --> $DIR/const-arg-in-const-arg.rs:38:24
+   |
+LL |     let _: Foo<{ faz::<'a>(&()) }>;
+   |                        ^^
+   |
+note: the late bound lifetime parameter is introduced here
+  --> $DIR/const-arg-in-const-arg.rs:10:14
+   |
+LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
+   |              ^^
+
+error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+  --> $DIR/const-arg-in-const-arg.rs:41:24
+   |
+LL |     let _: Foo<{ faz::<'b>(&()) }>;
+   |                        ^^
+   |
+note: the late bound lifetime parameter is introduced here
+  --> $DIR/const-arg-in-const-arg.rs:10:14
+   |
+LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
+   |              ^^
+
+error[E0747]: unresolved item provided when a constant was expected
   --> $DIR/const-arg-in-const-arg.rs:45:27
    |
 LL |     let _ = Foo::<{ bar::<N>() }>;
diff --git a/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr b/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr
index a05aaf2af64..1aac357d60e 100644
--- a/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr
@@ -39,14 +39,6 @@ error: unconstrained generic constant
 LL |     let _ = const_evaluatable_lib::test1::<T>();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: required by a bound in `test1`
-  --> $DIR/auxiliary/const_evaluatable_lib.rs:5:10
-   |
-LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
-   |        ----- required by a bound in this function
-LL | where
-LL |     [u8; std::mem::size_of::<T>() - 1]: Sized,
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
 help: try adding a `where` bound
    |
 LL | fn user<T>() where [(); std::mem::size_of::<T>() - 1]: {
@@ -59,10 +51,13 @@ LL |     let _ = const_evaluatable_lib::test1::<T>();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: required by a bound in `test1`
-  --> $DIR/auxiliary/const_evaluatable_lib.rs:3:27
+  --> $DIR/auxiliary/const_evaluatable_lib.rs:5:10
    |
 LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
+   |        ----- required by a bound in this function
+LL | where
+LL |     [u8; std::mem::size_of::<T>() - 1]: Sized,
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
 help: try adding a `where` bound
    |
 LL | fn user<T>() where [(); std::mem::size_of::<T>() - 1]: {
diff --git a/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr b/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr
index 7e318f8786f..f6119c17bf4 100644
--- a/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr
@@ -1,27 +1,27 @@
-error: overly complex generic constant
-  --> $DIR/dependence_lint.rs:21:17
-   |
-LL |     let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable, error with gce
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
-   |
-   = help: consider moving this anonymous constant into a `const` function
-
 error: unconstrained generic constant
-  --> $DIR/dependence_lint.rs:14:12
+  --> $DIR/dependence_lint.rs:10:9
    |
-LL |     let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs`
+   |         ^^^^^^^^^^^^^^^^^^^
    |
 help: try adding a `where` bound
    |
 LL | fn foo<T>() where [(); size_of::<*mut T>()]: {
    |             ++++++++++++++++++++++++++++++++
 
+error: overly complex generic constant
+  --> $DIR/dependence_lint.rs:17:9
+   |
+LL |     [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error with gce
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
+   |
+   = help: consider moving this anonymous constant into a `const` function
+
 error: unconstrained generic constant
-  --> $DIR/dependence_lint.rs:10:9
+  --> $DIR/dependence_lint.rs:14:12
    |
-LL |     [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs`
-   |         ^^^^^^^^^^^^^^^^^^^
+LL |     let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: try adding a `where` bound
    |
@@ -29,10 +29,10 @@ LL | fn foo<T>() where [(); size_of::<*mut T>()]: {
    |             ++++++++++++++++++++++++++++++++
 
 error: overly complex generic constant
-  --> $DIR/dependence_lint.rs:17:9
+  --> $DIR/dependence_lint.rs:21:17
    |
-LL |     [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error with gce
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
+LL |     let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable, error with gce
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
    |
    = help: consider moving this anonymous constant into a `const` function
 
diff --git a/tests/ui/const-generics/invalid-enum.stderr b/tests/ui/const-generics/invalid-enum.stderr
index 7e8a632b34f..f588ff0bc8e 100644
--- a/tests/ui/const-generics/invalid-enum.stderr
+++ b/tests/ui/const-generics/invalid-enum.stderr
@@ -26,28 +26,6 @@ LL |   let _: Example<CompileFlag::A, _> = Example { x: 0 };
    |                  help: try using the variant's enum: `CompileFlag`
 
 error[E0747]: unresolved item provided when a constant was expected
-  --> $DIR/invalid-enum.rs:31:18
-   |
-LL |   let _: Example<CompileFlag::A, _> = Example { x: 0 };
-   |                  ^^^^^^^^^^^^^^
-   |
-help: if this generic argument was intended as a const parameter, surround it with braces
-   |
-LL |   let _: Example<{ CompileFlag::A }, _> = Example { x: 0 };
-   |                  +                +
-
-error[E0747]: type provided when a constant was expected
-  --> $DIR/invalid-enum.rs:35:18
-   |
-LL |   let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
-   |                  ^^^^^^^^^^^^^^^^^^^
-   |
-help: if this generic argument was intended as a const parameter, surround it with braces
-   |
-LL |   let _: Example<{ Example::ASSOC_FLAG }, _> = Example { x: 0 };
-   |                  +                     +
-
-error[E0747]: unresolved item provided when a constant was expected
   --> $DIR/invalid-enum.rs:23:12
    |
 LL |   test_1::<CompileFlag::A>();
@@ -69,6 +47,28 @@ help: if this generic argument was intended as a const parameter, surround it wi
 LL |   test_2::<_, { CompileFlag::A }>(0);
    |               +                +
 
+error[E0747]: unresolved item provided when a constant was expected
+  --> $DIR/invalid-enum.rs:31:18
+   |
+LL |   let _: Example<CompileFlag::A, _> = Example { x: 0 };
+   |                  ^^^^^^^^^^^^^^
+   |
+help: if this generic argument was intended as a const parameter, surround it with braces
+   |
+LL |   let _: Example<{ CompileFlag::A }, _> = Example { x: 0 };
+   |                  +                +
+
+error[E0747]: type provided when a constant was expected
+  --> $DIR/invalid-enum.rs:35:18
+   |
+LL |   let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
+   |                  ^^^^^^^^^^^^^^^^^^^
+   |
+help: if this generic argument was intended as a const parameter, surround it with braces
+   |
+LL |   let _: Example<{ Example::ASSOC_FLAG }, _> = Example { x: 0 };
+   |                  +                     +
+
 error: aborting due to 7 previous errors
 
 Some errors have detailed explanations: E0573, E0747.
diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.rs b/tests/ui/consts/const_in_pattern/reject_non_structural.rs
index 6478bf9c6ee..39e5f732a89 100644
--- a/tests/ui/consts/const_in_pattern/reject_non_structural.rs
+++ b/tests/ui/consts/const_in_pattern/reject_non_structural.rs
@@ -93,7 +93,6 @@ fn main() {
     //~| NOTE constant of non-structural type
 
     trait Trait: Sized { const ASSOC: Option<Self>; } //~ NOTE constant defined here
-                                                      //~^ NOTE
     impl Trait for NoDerive { const ASSOC: Option<NoDerive> = Some(NoDerive); }
     match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), };
     //~^ ERROR constant of non-structural type `NoDerive` in a pattern
diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr
index bf54d3d76ae..fa16d0b06a7 100644
--- a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr
+++ b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr
@@ -118,14 +118,14 @@ LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: constant of non-structural type `NoDerive` in a pattern
-  --> $DIR/reject_non_structural.rs:98:28
+  --> $DIR/reject_non_structural.rs:97:28
    |
 LL | struct NoDerive;
    | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
 ...
 LL |     trait Trait: Sized { const ASSOC: Option<Self>; }
    |     ------------------   ------------------------- constant defined here
-...
+LL |     impl Trait for NoDerive { const ASSOC: Option<NoDerive> = Some(NoDerive); }
 LL |     match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), };
    |                            ^^^^^^^^^^^^^^^ constant of non-structural type
    |
@@ -136,7 +136,7 @@ LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: constant of non-structural type `NoDerive` in a pattern
-  --> $DIR/reject_non_structural.rs:103:28
+  --> $DIR/reject_non_structural.rs:102:28
    |
 LL | struct NoDerive;
    | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
@@ -153,7 +153,7 @@ LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: constant of non-structural type `NoDerive` in a pattern
-  --> $DIR/reject_non_structural.rs:108:29
+  --> $DIR/reject_non_structural.rs:107:29
    |
 LL | struct NoDerive;
    | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
diff --git a/tests/ui/consts/missing_span_in_backtrace.rs b/tests/ui/consts/missing_span_in_backtrace.rs
index c8c7453daa1..490eb57c24d 100644
--- a/tests/ui/consts/missing_span_in_backtrace.rs
+++ b/tests/ui/consts/missing_span_in_backtrace.rs
@@ -1,7 +1,5 @@
 //@ compile-flags: -Z ui-testing=no
 
-
-#![feature(const_swap_nonoverlapping)]
 use std::{
     mem::{self, MaybeUninit},
     ptr,
diff --git a/tests/ui/consts/missing_span_in_backtrace.stderr b/tests/ui/consts/missing_span_in_backtrace.stderr
index aad3d76dd26..88b3e37bb84 100644
--- a/tests/ui/consts/missing_span_in_backtrace.stderr
+++ b/tests/ui/consts/missing_span_in_backtrace.stderr
@@ -1,11 +1,11 @@
 error[E0080]: evaluation of constant value failed
-  --> $DIR/missing_span_in_backtrace.rs:16:9
+  --> $DIR/missing_span_in_backtrace.rs:14:9
    |
-16 | /         ptr::swap_nonoverlapping(
-17 | |             &mut ptr1 as *mut _ as *mut MaybeUninit<u8>,
-18 | |             &mut ptr2 as *mut _ as *mut MaybeUninit<u8>,
-19 | |             mem::size_of::<&i32>(),
-20 | |         );
+14 | /         ptr::swap_nonoverlapping(
+15 | |             &mut ptr1 as *mut _ as *mut MaybeUninit<u8>,
+16 | |             &mut ptr2 as *mut _ as *mut MaybeUninit<u8>,
+17 | |             mem::size_of::<&i32>(),
+18 | |         );
    | |_________^ unable to copy parts of a pointer from memory at ALLOC0
    |
 note: inside `swap_nonoverlapping::<MaybeUninit<u8>>`
diff --git a/tests/ui/auxiliary/issue-18502.rs b/tests/ui/cross-crate/auxiliary/inline-cross-crate.rs
index 4d4230607aa..4d4230607aa 100644
--- a/tests/ui/auxiliary/issue-18502.rs
+++ b/tests/ui/cross-crate/auxiliary/inline-cross-crate.rs
diff --git a/tests/ui/auxiliary/issue-76387.rs b/tests/ui/cross-crate/auxiliary/llvm-miscompile-MarkValue-MaybeLive.rs
index d540bceff93..d540bceff93 100644
--- a/tests/ui/auxiliary/issue-76387.rs
+++ b/tests/ui/cross-crate/auxiliary/llvm-miscompile-MarkValue-MaybeLive.rs
diff --git a/tests/ui/cross-crate/inline-cross-crate.rs b/tests/ui/cross-crate/inline-cross-crate.rs
new file mode 100644
index 00000000000..273aa8f8f0d
--- /dev/null
+++ b/tests/ui/cross-crate/inline-cross-crate.rs
@@ -0,0 +1,12 @@
+//! Dpn't ice on using an inlined function from another crate
+//! See <https://github.com/rust-lang/rust/issues/18502> and
+//! <https://github.com/rust-lang/rust/issues/18501>
+
+//@ run-pass
+//@ aux-build:inline-cross-crate.rs
+
+extern crate inline_cross_crate as fmt;
+
+fn main() {
+    ::fmt::baz();
+}
diff --git a/tests/ui/cross-crate/llvm-miscompile-MarkValue-MaybeLive.rs b/tests/ui/cross-crate/llvm-miscompile-MarkValue-MaybeLive.rs
new file mode 100644
index 00000000000..95d022ddd96
--- /dev/null
+++ b/tests/ui/cross-crate/llvm-miscompile-MarkValue-MaybeLive.rs
@@ -0,0 +1,22 @@
+//! Regression test for <https://github.com/rust-lang/rust/issues/76387>
+//! Tests that LLVM doesn't miscompile this
+//! See upstream fix: <https://reviews.llvm.org/D88529>.
+
+//@ compile-flags: -C opt-level=3
+//@ aux-build: llvm-miscompile-MarkValue-MaybeLive.rs
+//@ run-pass
+
+extern crate llvm_miscompile_MarkValue_MaybeLive;
+
+use llvm_miscompile_MarkValue_MaybeLive::FatPtr;
+
+fn print(data: &[u8]) {
+    println!("{:#?}", data);
+}
+
+fn main() {
+    let ptr = FatPtr::new(20);
+    let data = unsafe { std::slice::from_raw_parts(ptr.as_ptr(), ptr.len()) };
+
+    print(data);
+}
diff --git a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs
index b79b5ff6fdb..35210e78dcd 100644
--- a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs
+++ b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs
@@ -1,4 +1,3 @@
-//FIXME~ ERROR values of the type `[u8; usize::MAX]` are too big for the target architecture
 // Make sure the compiler does not ICE when trying to generate the debuginfo name of a type that
 // causes a layout error.
 // This version of the test already ICE'd before the commit that introduce the ICE described in
@@ -6,7 +5,6 @@
 
 //@ compile-flags:-C debuginfo=2 --error-format=human
 //@ build-fail
-//@ error-pattern: values of the type `[u8; usize::MAX]` are too big for the target architecture
 
 #![crate_type = "rlib"]
 
@@ -18,5 +16,5 @@ pub fn foo() -> usize {
     std::mem::size_of::<Foo<u8>>()
 }
 
-// FIXME: the error is reported on different lines on different targets
-//FIXME~? ERROR values of the type `[u8; usize::MAX]` are too big for the target architecture
+// FIXME(#140620): the error is reported on different lines on different targets
+//~? RAW values of the type `[u8; usize::MAX]` are too big for the target architecture
diff --git a/tests/ui/delegation/unsupported.stderr b/tests/ui/delegation/unsupported.stderr
index cb14d9f459a..53d05c3db8c 100644
--- a/tests/ui/delegation/unsupported.stderr
+++ b/tests/ui/delegation/unsupported.stderr
@@ -1,4 +1,4 @@
-error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:21:5: 21:24>::{anon_assoc#0}`
+error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:21:5: 21:24>::opaque_ret::{anon_assoc#0}`
   --> $DIR/unsupported.rs:22:25
    |
 LL |         reuse to_reuse::opaque_ret;
@@ -9,7 +9,7 @@ note: ...which requires comparing an impl and trait method signature, inferring
    |
 LL |         reuse to_reuse::opaque_ret;
    |                         ^^^^^^^^^^
-   = note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:21:5: 21:24>::{anon_assoc#0}`, completing the cycle
+   = note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:21:5: 21:24>::opaque_ret::{anon_assoc#0}`, completing the cycle
 note: cycle used when checking that `opaque::<impl at $DIR/unsupported.rs:21:5: 21:24>` is well-formed
   --> $DIR/unsupported.rs:21:5
    |
@@ -17,7 +17,7 @@ LL |     impl ToReuse for u8 {
    |     ^^^^^^^^^^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
-error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:24:5: 24:25>::{anon_assoc#0}`
+error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:24:5: 24:25>::opaque_ret::{anon_assoc#0}`
   --> $DIR/unsupported.rs:25:24
    |
 LL |         reuse ToReuse::opaque_ret;
@@ -28,7 +28,7 @@ note: ...which requires comparing an impl and trait method signature, inferring
    |
 LL |         reuse ToReuse::opaque_ret;
    |                        ^^^^^^^^^^
-   = note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:24:5: 24:25>::{anon_assoc#0}`, completing the cycle
+   = note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:24:5: 24:25>::opaque_ret::{anon_assoc#0}`, completing the cycle
 note: cycle used when checking that `opaque::<impl at $DIR/unsupported.rs:24:5: 24:25>` is well-formed
   --> $DIR/unsupported.rs:24:5
    |
diff --git a/tests/ui/derives/deriving-with-repr-packed-move-errors.rs b/tests/ui/derives/deriving-with-repr-packed-move-errors.rs
index ffeb02d78b8..17aa750332c 100644
--- a/tests/ui/derives/deriving-with-repr-packed-move-errors.rs
+++ b/tests/ui/derives/deriving-with-repr-packed-move-errors.rs
@@ -11,15 +11,15 @@ use std::cmp::Ordering;
 #[repr(packed)]
 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
 struct StructA(String);
-//~^ ERROR: cannot move out of `self` which is behind a shared reference
-//~| ERROR: cannot move out of `self` which is behind a shared reference
-//~| ERROR: cannot move out of `other` which is behind a shared reference
-//~| ERROR: cannot move out of `self` which is behind a shared reference
-//~| ERROR: cannot move out of `other` which is behind a shared reference
-//~| ERROR: cannot move out of `self` which is behind a shared reference
-//~| ERROR: cannot move out of `other` which is behind a shared reference
-//~| ERROR: cannot move out of `self` which is behind a shared reference
-//~| ERROR: cannot move out of `self` which is behind a shared reference
+//~^ ERROR: cannot move out of a shared reference [E0507]
+//~| ERROR: cannot move out of a shared reference [E0507]
+//~| ERROR: cannot move out of a shared reference [E0507]
+//~| ERROR: cannot move out of a shared reference [E0507]
+//~| ERROR: cannot move out of a shared reference [E0507]
+//~| ERROR: cannot move out of a shared reference [E0507]
+//~| ERROR: cannot move out of a shared reference [E0507]
+//~| ERROR: cannot move out of a shared reference [E0507]
+//~| ERROR: cannot move out of a shared reference [E0507]
 
 
 // Unrelated impl: additinal diagnostic should NOT be emitted
diff --git a/tests/ui/derives/deriving-with-repr-packed-move-errors.stderr b/tests/ui/derives/deriving-with-repr-packed-move-errors.stderr
index 68c3c8ae9ea..4b085425033 100644
--- a/tests/ui/derives/deriving-with-repr-packed-move-errors.stderr
+++ b/tests/ui/derives/deriving-with-repr-packed-move-errors.stderr
@@ -1,10 +1,10 @@
-error[E0507]: cannot move out of `self` which is behind a shared reference
+error[E0507]: cannot move out of a shared reference
   --> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
    |
 LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
    |          ----- in this derive macro expansion
 LL | struct StructA(String);
-   |                ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
+   |                ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
    |
    = note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
 help: consider cloning the value if the performance cost is acceptable
@@ -12,13 +12,13 @@ help: consider cloning the value if the performance cost is acceptable
 LL | struct StructA(String.clone());
    |                      ++++++++
 
-error[E0507]: cannot move out of `self` which is behind a shared reference
+error[E0507]: cannot move out of a shared reference
   --> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
    |
 LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
    |                 --------- in this derive macro expansion
 LL | struct StructA(String);
-   |                ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
+   |                ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
    |
    = note: `#[derive(PartialEq)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
 help: consider cloning the value if the performance cost is acceptable
@@ -26,27 +26,28 @@ help: consider cloning the value if the performance cost is acceptable
 LL | struct StructA(String.clone());
    |                      ++++++++
 
-error[E0507]: cannot move out of `other` which is behind a shared reference
+error[E0507]: cannot move out of a shared reference
   --> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
    |
 LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
    |                 --------- in this derive macro expansion
 LL | struct StructA(String);
-   |                ^^^^^^ move occurs because `other.0` has type `String`, which does not implement the `Copy` trait
+   |                ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
    |
    = note: `#[derive(PartialEq)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 help: consider cloning the value if the performance cost is acceptable
    |
 LL | struct StructA(String.clone());
    |                      ++++++++
 
-error[E0507]: cannot move out of `self` which is behind a shared reference
+error[E0507]: cannot move out of a shared reference
   --> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
    |
 LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
    |                                ---------- in this derive macro expansion
 LL | struct StructA(String);
-   |                ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
+   |                ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
    |
    = note: `#[derive(PartialOrd)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
 help: consider cloning the value if the performance cost is acceptable
@@ -54,27 +55,28 @@ help: consider cloning the value if the performance cost is acceptable
 LL | struct StructA(String.clone());
    |                      ++++++++
 
-error[E0507]: cannot move out of `other` which is behind a shared reference
+error[E0507]: cannot move out of a shared reference
   --> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
    |
 LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
    |                                ---------- in this derive macro expansion
 LL | struct StructA(String);
-   |                ^^^^^^ move occurs because `other.0` has type `String`, which does not implement the `Copy` trait
+   |                ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
    |
    = note: `#[derive(PartialOrd)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 help: consider cloning the value if the performance cost is acceptable
    |
 LL | struct StructA(String.clone());
    |                      ++++++++
 
-error[E0507]: cannot move out of `self` which is behind a shared reference
+error[E0507]: cannot move out of a shared reference
   --> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
    |
 LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
    |                                            --- in this derive macro expansion
 LL | struct StructA(String);
-   |                ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
+   |                ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
    |
    = note: `#[derive(Ord)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
 help: consider cloning the value if the performance cost is acceptable
@@ -82,27 +84,28 @@ help: consider cloning the value if the performance cost is acceptable
 LL | struct StructA(String.clone());
    |                      ++++++++
 
-error[E0507]: cannot move out of `other` which is behind a shared reference
+error[E0507]: cannot move out of a shared reference
   --> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
    |
 LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
    |                                            --- in this derive macro expansion
 LL | struct StructA(String);
-   |                ^^^^^^ move occurs because `other.0` has type `String`, which does not implement the `Copy` trait
+   |                ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
    |
    = note: `#[derive(Ord)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 help: consider cloning the value if the performance cost is acceptable
    |
 LL | struct StructA(String.clone());
    |                      ++++++++
 
-error[E0507]: cannot move out of `self` which is behind a shared reference
+error[E0507]: cannot move out of a shared reference
   --> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
    |
 LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
    |                                                 ---- in this derive macro expansion
 LL | struct StructA(String);
-   |                ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
+   |                ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
    |
    = note: `#[derive(Hash)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
 help: consider cloning the value if the performance cost is acceptable
@@ -110,13 +113,13 @@ help: consider cloning the value if the performance cost is acceptable
 LL | struct StructA(String.clone());
    |                      ++++++++
 
-error[E0507]: cannot move out of `self` which is behind a shared reference
+error[E0507]: cannot move out of a shared reference
   --> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
    |
 LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
    |                                                       ----- in this derive macro expansion
 LL | struct StructA(String);
-   |                ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
+   |                ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
    |
    = note: `#[derive(Clone)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
 help: consider cloning the value if the performance cost is acceptable
diff --git a/tests/ui/derives/deriving-with-repr-packed.rs b/tests/ui/derives/deriving-with-repr-packed.rs
index d17b52842ce..cba0413c992 100644
--- a/tests/ui/derives/deriving-with-repr-packed.rs
+++ b/tests/ui/derives/deriving-with-repr-packed.rs
@@ -20,7 +20,7 @@ struct Y(usize);
 #[derive(Debug, Default)]
 #[repr(packed)]
 struct X(Y);
-//~^ ERROR cannot move out of `self` which is behind a shared reference
+//~^ ERROR cannot move out of a shared reference [E0507]
 
 #[derive(Debug)]
 #[repr(packed)]
diff --git a/tests/ui/derives/deriving-with-repr-packed.stderr b/tests/ui/derives/deriving-with-repr-packed.stderr
index 5117f8d1112..9cfc4abdc0c 100644
--- a/tests/ui/derives/deriving-with-repr-packed.stderr
+++ b/tests/ui/derives/deriving-with-repr-packed.stderr
@@ -1,11 +1,11 @@
-error[E0507]: cannot move out of `self` which is behind a shared reference
+error[E0507]: cannot move out of a shared reference
   --> $DIR/deriving-with-repr-packed.rs:22:10
    |
 LL | #[derive(Debug, Default)]
    |          ----- in this derive macro expansion
 LL | #[repr(packed)]
 LL | struct X(Y);
-   |          ^ move occurs because `self.0` has type `Y`, which does not implement the `Copy` trait
+   |          ^ move occurs because value has type `Y`, which does not implement the `Copy` trait
    |
 note: if `Y` implemented `Clone`, you could clone the value
   --> $DIR/deriving-with-repr-packed.rs:16:1
@@ -23,14 +23,14 @@ error[E0161]: cannot move a value of type `[u8]`
 LL |     data: [u8],
    |     ^^^^^^^^^^ the size of `[u8]` cannot be statically determined
 
-error[E0507]: cannot move out of `self.data` which is behind a shared reference
+error[E0507]: cannot move out of a shared reference
   --> $DIR/deriving-with-repr-packed.rs:29:5
    |
 LL | #[derive(Debug)]
    |          ----- in this derive macro expansion
 ...
 LL |     data: [u8],
-   |     ^^^^^^^^^^ move occurs because `self.data` has type `[u8]`, which does not implement the `Copy` trait
+   |     ^^^^^^^^^^ move occurs because value has type `[u8]`, which does not implement the `Copy` trait
    |
    = note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
 
@@ -40,14 +40,14 @@ error[E0161]: cannot move a value of type `str`
 LL |     data: str,
    |     ^^^^^^^^^ the size of `str` cannot be statically determined
 
-error[E0507]: cannot move out of `self.data` which is behind a shared reference
+error[E0507]: cannot move out of a shared reference
   --> $DIR/deriving-with-repr-packed.rs:38:5
    |
 LL | #[derive(Debug)]
    |          ----- in this derive macro expansion
 ...
 LL |     data: str,
-   |     ^^^^^^^^^ move occurs because `self.data` has type `str`, which does not implement the `Copy` trait
+   |     ^^^^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait
    |
    = note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
 
diff --git a/tests/ui/diagnostic-width/flag-json.rs b/tests/ui/diagnostic-width/flag-json.rs
index 00778872727..edc7d2e2a42 100644
--- a/tests/ui/diagnostic-width/flag-json.rs
+++ b/tests/ui/diagnostic-width/flag-json.rs
@@ -1,9 +1,10 @@
 //@ compile-flags: --diagnostic-width=20 --error-format=json
-//@ error-pattern:expected `()`, found integer
 
 // This test checks that `-Z output-width` effects the JSON error output by restricting it to an
 // arbitrarily low value so that the effect is visible.
 
 fn main() {
-    let _: () = 42;
+    let _: () = 42; //~ ERROR mismatched types
+                    //~| NOTE expected `()`, found integer
+                    //~| NOTE expected due to this
 }
diff --git a/tests/ui/diagnostic-width/flag-json.stderr b/tests/ui/diagnostic-width/flag-json.stderr
index 6a54f86dcee..cfc0364be76 100644
--- a/tests/ui/diagnostic-width/flag-json.stderr
+++ b/tests/ui/diagnostic-width/flag-json.stderr
@@ -24,10 +24,10 @@ This error occurs when an expression was used in a place where the compiler
 expected an expression of a different type. It can occur in several cases, the
 most common being when calling a function and passing an argument which has a
 different type than the matching type in the function declaration.
-"},"level":"error","spans":[{"file_name":"$DIR/flag-json.rs","byte_start":291,"byte_end":293,"line_start":8,"line_end":8,"column_start":17,"column_end":19,"is_primary":true,"text":[{"text":"    let _: () = 42;","highlight_start":17,"highlight_end":19}],"label":"expected `()`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/flag-json.rs","byte_start":286,"byte_end":288,"line_start":8,"line_end":8,"column_start":12,"column_end":14,"is_primary":false,"text":[{"text":"    let _: () = 42;","highlight_start":12,"highlight_end":14}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"error[E0308]: mismatched types
-  --> $DIR/flag-json.rs:8:17
+"},"level":"error","spans":[{"file_name":"$DIR/flag-json.rs","byte_start":244,"byte_end":246,"line_start":7,"line_end":7,"column_start":17,"column_end":19,"is_primary":true,"text":[{"text":"    let _: () = 42;
+  --> $DIR/flag-json.rs:7:17
    |
-LL | ..._: () = 42;
+LL | ..._: () = 42; /...
    |       --   ^^ expected `()`, found integer
    |       |
    |       expected due to this
diff --git a/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr b/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr
index bb3f7899bf1..c1e93ccb83c 100644
--- a/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr
+++ b/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr
@@ -1,8 +1,8 @@
 error[E0038]: the trait `Bar` is not dyn compatible
-  --> $DIR/mention-correct-dyn-incompatible-trait.rs:19:15
+  --> $DIR/mention-correct-dyn-incompatible-trait.rs:19:30
    |
 LL |     let test: &mut dyn Bar = &mut thing;
-   |               ^^^^^^^^^^^^ `Bar` is not dyn compatible
+   |                              ^^^^^^^^^^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
       for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
@@ -15,12 +15,13 @@ LL | trait Bar: Foo { }
    |       --- this trait is not dyn compatible...
    = help: consider moving `foo` to another trait
    = help: only type `Thing` implements `Bar`; consider using it directly instead.
+   = note: required for the cast from `&mut Thing` to `&mut dyn Bar`
 
 error[E0038]: the trait `Bar` is not dyn compatible
-  --> $DIR/mention-correct-dyn-incompatible-trait.rs:19:30
+  --> $DIR/mention-correct-dyn-incompatible-trait.rs:19:15
    |
 LL |     let test: &mut dyn Bar = &mut thing;
-   |                              ^^^^^^^^^^ `Bar` is not dyn compatible
+   |               ^^^^^^^^^^^^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
       for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
@@ -33,7 +34,6 @@ LL | trait Bar: Foo { }
    |       --- this trait is not dyn compatible...
    = help: consider moving `foo` to another trait
    = help: only type `Thing` implements `Bar`; consider using it directly instead.
-   = note: required for the cast from `&mut Thing` to `&mut dyn Bar`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/error-codes/E0195.rs b/tests/ui/error-codes/E0195.rs
index a7e51dff2f3..66968f70bd9 100644
--- a/tests/ui/error-codes/E0195.rs
+++ b/tests/ui/error-codes/E0195.rs
@@ -1,13 +1,25 @@
 trait Trait {
+//~^ NOTE in this trait...
+//~| NOTE in this trait...
     fn bar<'a,'b:'a>(x: &'a str, y: &'b str);
-    //~^ NOTE lifetimes in impl do not match this associated function in trait
+    //~^ NOTE `'a` is early-bound
+    //~| NOTE this lifetime bound makes `'a` early-bound
+    //~| NOTE `'b` is early-bound
+    //~| NOTE this lifetime bound makes `'b` early-bound
 }
 
 struct Foo;
 
 impl Trait for Foo {
-    fn bar<'a,'b>(x: &'a str, y: &'b str) { //~ ERROR E0195
-    //~^ NOTE lifetimes do not match associated function in trait
+//~^ NOTE in this impl...
+//~| NOTE in this impl...
+    fn bar<'a,'b>(x: &'a str, y: &'b str) {
+    //~^ ERROR E0195
+    //~| NOTE `'a` differs between the trait and impl
+    //~| NOTE `'a` is late-bound
+    //~| NOTE `'b` differs between the trait and impl
+    //~| NOTE `'b` is late-bound
+    //~| NOTE lifetime parameters differ in whether they are early- or late-bound
     }
 }
 
diff --git a/tests/ui/error-codes/E0195.stderr b/tests/ui/error-codes/E0195.stderr
index 9767dee9aec..d0295b36434 100644
--- a/tests/ui/error-codes/E0195.stderr
+++ b/tests/ui/error-codes/E0195.stderr
@@ -1,11 +1,42 @@
-error[E0195]: lifetime parameters or bounds on associated function `bar` do not match the trait declaration
-  --> $DIR/E0195.rs:9:11
+error[E0195]: lifetime parameters do not match the trait definition
+  --> $DIR/E0195.rs:16:12
    |
+LL |     fn bar<'a,'b>(x: &'a str, y: &'b str) {
+   |            ^^ ^^
+   |
+   = note: lifetime parameters differ in whether they are early- or late-bound
+note: `'a` differs between the trait and impl
+  --> $DIR/E0195.rs:4:12
+   |
+LL | trait Trait {
+   | ----------- in this trait...
+...
 LL |     fn bar<'a,'b:'a>(x: &'a str, y: &'b str);
-   |           ---------- lifetimes in impl do not match this associated function in trait
+   |            ^^    -- this lifetime bound makes `'a` early-bound
+   |            |
+   |            `'a` is early-bound
+...
+LL | impl Trait for Foo {
+   | ------------------ in this impl...
+...
+LL |     fn bar<'a,'b>(x: &'a str, y: &'b str) {
+   |            ^^ `'a` is late-bound
+note: `'b` differs between the trait and impl
+  --> $DIR/E0195.rs:4:15
+   |
+LL | trait Trait {
+   | ----------- in this trait...
+...
+LL |     fn bar<'a,'b:'a>(x: &'a str, y: &'b str);
+   |               ^^ -- this lifetime bound makes `'b` early-bound
+   |               |
+   |               `'b` is early-bound
+...
+LL | impl Trait for Foo {
+   | ------------------ in this impl...
 ...
 LL |     fn bar<'a,'b>(x: &'a str, y: &'b str) {
-   |           ^^^^^^^ lifetimes do not match associated function in trait
+   |               ^^ `'b` is late-bound
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/error-codes/E0253.rs b/tests/ui/error-codes/E0253.rs
deleted file mode 100644
index 8284f791c64..00000000000
--- a/tests/ui/error-codes/E0253.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-mod foo {
-    pub trait MyTrait {
-        type SomeType;
-    }
-}
-
-use foo::MyTrait::SomeType;
-    //~^ ERROR E0253
-
-fn main() {}
diff --git a/tests/ui/error-codes/E0253.stderr b/tests/ui/error-codes/E0253.stderr
deleted file mode 100644
index 954dbc81693..00000000000
--- a/tests/ui/error-codes/E0253.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0253]: `SomeType` is not directly importable
-  --> $DIR/E0253.rs:7:5
-   |
-LL | use foo::MyTrait::SomeType;
-   |     ^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0253`.
diff --git a/tests/ui/error-emitter/highlighting.rs b/tests/ui/error-emitter/highlighting.rs
index b3c1acbd342..d7a0c9d2246 100644
--- a/tests/ui/error-emitter/highlighting.rs
+++ b/tests/ui/error-emitter/highlighting.rs
@@ -1,7 +1,6 @@
 // Make sure "highlighted" code is colored purple
 
 //@ compile-flags: --error-format=human --color=always
-//@ error-pattern:for<'a> 
 //@ edition:2018
 
 use core::pin::Pin;
@@ -21,3 +20,5 @@ fn wrapped_fn<'a>(_: Box<(dyn Any + Send)>) -> Pin<Box<(
 fn main() {
     query(wrapped_fn);
 }
+
+//~? RAW for<'a> 
diff --git a/tests/ui/error-emitter/highlighting.svg b/tests/ui/error-emitter/highlighting.svg
index 68fc118f1a6..19818ab6146 100644
--- a/tests/ui/error-emitter/highlighting.svg
+++ b/tests/ui/error-emitter/highlighting.svg
@@ -23,7 +23,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">: mismatched types</tspan>
 </tspan>
-    <tspan x="10px" y="46px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/highlighting.rs:22:11</tspan>
+    <tspan x="10px" y="46px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/highlighting.rs:21:11</tspan>
 </tspan>
     <tspan x="10px" y="64px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
@@ -43,7 +43,7 @@
 </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">--&gt; </tspan><tspan>$DIR/highlighting.rs:11:4</tspan>
+    <tspan x="10px" y="226px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/highlighting.rs:10:4</tspan>
 </tspan>
     <tspan x="10px" y="244px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
diff --git a/tests/ui/error-emitter/highlighting.windows.svg b/tests/ui/error-emitter/highlighting.windows.svg
index c7dd001434e..f891bc1d2a6 100644
--- a/tests/ui/error-emitter/highlighting.windows.svg
+++ b/tests/ui/error-emitter/highlighting.windows.svg
@@ -24,7 +24,7 @@
   <text xml:space="preserve" class="container fg">
     <tspan x="10px" y="28px"><tspan class="fg-ansi256-009 bold">error[E0308]</tspan><tspan class="fg-ansi256-015 bold">: mismatched types</tspan>
 </tspan>
-    <tspan x="10px" y="46px"><tspan>  </tspan><tspan class="fg-ansi256-014 bold">--&gt; </tspan><tspan>$DIR/highlighting.rs:22:11</tspan>
+    <tspan x="10px" y="46px"><tspan>  </tspan><tspan class="fg-ansi256-014 bold">--&gt; </tspan><tspan>$DIR/highlighting.rs:21:11</tspan>
 </tspan>
     <tspan x="10px" y="64px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan>
 </tspan>
@@ -44,7 +44,7 @@
 </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-014 bold">--&gt; </tspan><tspan>$DIR/highlighting.rs:11:4</tspan>
+    <tspan x="10px" y="226px"><tspan>  </tspan><tspan class="fg-ansi256-014 bold">--&gt; </tspan><tspan>$DIR/highlighting.rs:10:4</tspan>
 </tspan>
     <tspan x="10px" y="244px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan>
 </tspan>
diff --git a/tests/ui/error-emitter/multiline-multipart-suggestion.rs b/tests/ui/error-emitter/multiline-multipart-suggestion.rs
index a938b280ca2..92dede1b5d8 100644
--- a/tests/ui/error-emitter/multiline-multipart-suggestion.rs
+++ b/tests/ui/error-emitter/multiline-multipart-suggestion.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: --error-format=human --color=always
-//@ error-pattern: missing lifetime specifier
 
 fn short(foo_bar: &Vec<&i32>) -> &i32 {
     &12
@@ -17,3 +16,5 @@ fn long2(
     &12
 }
 fn main() {}
+
+//~? RAW missing lifetime specifier
diff --git a/tests/ui/error-emitter/multiline-multipart-suggestion.svg b/tests/ui/error-emitter/multiline-multipart-suggestion.svg
index c0fb98555ad..dd84234236d 100644
--- a/tests/ui/error-emitter/multiline-multipart-suggestion.svg
+++ b/tests/ui/error-emitter/multiline-multipart-suggestion.svg
@@ -23,7 +23,7 @@
   <text xml:space="preserve" class="container fg">
     <tspan x="10px" y="28px"><tspan class="fg-ansi256-009 bold">error[E0106]</tspan><tspan class="bold">: missing lifetime specifier</tspan>
 </tspan>
-    <tspan x="10px" y="46px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/multiline-multipart-suggestion.rs:4:34</tspan>
+    <tspan x="10px" y="46px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/multiline-multipart-suggestion.rs:3:34</tspan>
 </tspan>
     <tspan x="10px" y="64px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
@@ -47,7 +47,7 @@
 </tspan>
     <tspan x="10px" y="244px"><tspan class="fg-ansi256-009 bold">error[E0106]</tspan><tspan class="bold">: missing lifetime specifier</tspan>
 </tspan>
-    <tspan x="10px" y="262px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/multiline-multipart-suggestion.rs:11:6</tspan>
+    <tspan x="10px" y="262px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/multiline-multipart-suggestion.rs:10:6</tspan>
 </tspan>
     <tspan x="10px" y="280px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
@@ -83,7 +83,7 @@
 </tspan>
     <tspan x="10px" y="568px"><tspan class="fg-ansi256-009 bold">error[E0106]</tspan><tspan class="bold">: missing lifetime specifier</tspan>
 </tspan>
-    <tspan x="10px" y="586px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/multiline-multipart-suggestion.rs:16:29</tspan>
+    <tspan x="10px" y="586px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/multiline-multipart-suggestion.rs:15:29</tspan>
 </tspan>
     <tspan x="10px" y="604px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
diff --git a/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg b/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg
index 61b544001f0..144e57165da 100644
--- a/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg
+++ b/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg
@@ -23,7 +23,7 @@
   <text xml:space="preserve" class="container fg">
     <tspan x="10px" y="28px"><tspan class="fg-ansi256-009 bold">error[E0106]</tspan><tspan class="fg-ansi256-015 bold">: missing lifetime specifier</tspan>
 </tspan>
-    <tspan x="10px" y="46px"><tspan>  </tspan><tspan class="fg-ansi256-014 bold">--&gt; </tspan><tspan>$DIR/multiline-multipart-suggestion.rs:4:34</tspan>
+    <tspan x="10px" y="46px"><tspan>  </tspan><tspan class="fg-ansi256-014 bold">--&gt; </tspan><tspan>$DIR/multiline-multipart-suggestion.rs:3:34</tspan>
 </tspan>
     <tspan x="10px" y="64px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan>
 </tspan>
@@ -47,7 +47,7 @@
 </tspan>
     <tspan x="10px" y="244px"><tspan class="fg-ansi256-009 bold">error[E0106]</tspan><tspan class="fg-ansi256-015 bold">: missing lifetime specifier</tspan>
 </tspan>
-    <tspan x="10px" y="262px"><tspan>  </tspan><tspan class="fg-ansi256-014 bold">--&gt; </tspan><tspan>$DIR/multiline-multipart-suggestion.rs:11:6</tspan>
+    <tspan x="10px" y="262px"><tspan>  </tspan><tspan class="fg-ansi256-014 bold">--&gt; </tspan><tspan>$DIR/multiline-multipart-suggestion.rs:10:6</tspan>
 </tspan>
     <tspan x="10px" y="280px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan>
 </tspan>
@@ -83,7 +83,7 @@
 </tspan>
     <tspan x="10px" y="568px"><tspan class="fg-ansi256-009 bold">error[E0106]</tspan><tspan class="fg-ansi256-015 bold">: missing lifetime specifier</tspan>
 </tspan>
-    <tspan x="10px" y="586px"><tspan>  </tspan><tspan class="fg-ansi256-014 bold">--&gt; </tspan><tspan>$DIR/multiline-multipart-suggestion.rs:16:29</tspan>
+    <tspan x="10px" y="586px"><tspan>  </tspan><tspan class="fg-ansi256-014 bold">--&gt; </tspan><tspan>$DIR/multiline-multipart-suggestion.rs:15:29</tspan>
 </tspan>
     <tspan x="10px" y="604px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan>
 </tspan>
diff --git a/tests/ui/errors/auxiliary/file-debuginfo.rs b/tests/ui/errors/auxiliary/file-debuginfo.rs
new file mode 100644
index 00000000000..08113ec26bf
--- /dev/null
+++ b/tests/ui/errors/auxiliary/file-debuginfo.rs
@@ -0,0 +1,11 @@
+//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@ compile-flags: -Zremap-path-scope=debuginfo
+
+#[macro_export]
+macro_rules! my_file {
+    () => { file!() }
+}
+
+pub fn file() -> &'static str {
+    file!()
+}
diff --git a/tests/ui/errors/auxiliary/file-diag.rs b/tests/ui/errors/auxiliary/file-diag.rs
new file mode 100644
index 00000000000..f29c349f703
--- /dev/null
+++ b/tests/ui/errors/auxiliary/file-diag.rs
@@ -0,0 +1,11 @@
+//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@ compile-flags: -Zremap-path-scope=diagnostics
+
+#[macro_export]
+macro_rules! my_file {
+    () => { file!() }
+}
+
+pub fn file() -> &'static str {
+    file!()
+}
diff --git a/tests/ui/errors/auxiliary/file-macro.rs b/tests/ui/errors/auxiliary/file-macro.rs
new file mode 100644
index 00000000000..11abc0549a7
--- /dev/null
+++ b/tests/ui/errors/auxiliary/file-macro.rs
@@ -0,0 +1,11 @@
+//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@ compile-flags: -Zremap-path-scope=macro
+
+#[macro_export]
+macro_rules! my_file {
+    () => { file!() }
+}
+
+pub fn file() -> &'static str {
+    file!()
+}
diff --git a/tests/ui/errors/auxiliary/file.rs b/tests/ui/errors/auxiliary/file.rs
new file mode 100644
index 00000000000..63a7b3b58f0
--- /dev/null
+++ b/tests/ui/errors/auxiliary/file.rs
@@ -0,0 +1,8 @@
+#[macro_export]
+macro_rules! my_file {
+    () => { file!() }
+}
+
+pub fn file() -> &'static str {
+    file!()
+}
diff --git a/tests/ui/errors/auxiliary/trait-debuginfo.rs b/tests/ui/errors/auxiliary/trait-debuginfo.rs
new file mode 100644
index 00000000000..d5a0825fe6d
--- /dev/null
+++ b/tests/ui/errors/auxiliary/trait-debuginfo.rs
@@ -0,0 +1,4 @@
+//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@ compile-flags: -Zremap-path-scope=debuginfo
+
+pub trait Trait: std::fmt::Display {}
diff --git a/tests/ui/errors/auxiliary/trait-diag.rs b/tests/ui/errors/auxiliary/trait-diag.rs
new file mode 100644
index 00000000000..e07961a276a
--- /dev/null
+++ b/tests/ui/errors/auxiliary/trait-diag.rs
@@ -0,0 +1,4 @@
+//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@ compile-flags: -Zremap-path-scope=diagnostics
+
+pub trait Trait: std::fmt::Display {}
diff --git a/tests/ui/errors/auxiliary/trait-macro.rs b/tests/ui/errors/auxiliary/trait-macro.rs
new file mode 100644
index 00000000000..48673d04ee1
--- /dev/null
+++ b/tests/ui/errors/auxiliary/trait-macro.rs
@@ -0,0 +1,4 @@
+//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@ compile-flags: -Zremap-path-scope=macro
+
+pub trait Trait: std::fmt::Display {}
diff --git a/tests/ui/errors/auxiliary/trait.rs b/tests/ui/errors/auxiliary/trait.rs
new file mode 100644
index 00000000000..0e7e5400aac
--- /dev/null
+++ b/tests/ui/errors/auxiliary/trait.rs
@@ -0,0 +1 @@
+pub trait Trait: std::fmt::Display {}
diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.not-diag-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.not-diag-in-deps.stderr
new file mode 100644
index 00000000000..3ddff11798d
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-diagnostics.not-diag-in-deps.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `A` doesn't implement `std::fmt::Display`
+  --> remapped/errors/remap-path-prefix-diagnostics.rs:LL:COL
+   |
+LL | impl r#trait::Trait for A {}
+   |                         ^ `A` cannot be formatted with the default formatter
+   |
+   = help: the trait `std::fmt::Display` is not implemented for `A`
+   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `Trait`
+  --> $DIR/auxiliary/trait.rs:LL:COL
+   |
+LL | pub trait Trait: std::fmt::Display {}
+   |                  ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.only-debuginfo-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.only-debuginfo-in-deps.stderr
new file mode 100644
index 00000000000..85c781425b1
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-diagnostics.only-debuginfo-in-deps.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `A` doesn't implement `std::fmt::Display`
+  --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
+   |
+LL | impl r#trait::Trait for A {}
+   |                         ^ `A` cannot be formatted with the default formatter
+   |
+   = help: the trait `std::fmt::Display` is not implemented for `A`
+   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `Trait`
+  --> $DIR/auxiliary/trait-debuginfo.rs:LL:COL
+   |
+LL | pub trait Trait: std::fmt::Display {}
+   |                  ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.only-diag-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.only-diag-in-deps.stderr
new file mode 100644
index 00000000000..792ea7925ad
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-diagnostics.only-diag-in-deps.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `A` doesn't implement `std::fmt::Display`
+  --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
+   |
+LL | impl r#trait::Trait for A {}
+   |                         ^ `A` cannot be formatted with the default formatter
+   |
+   = help: the trait `std::fmt::Display` is not implemented for `A`
+   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `Trait`
+  --> $DIR/auxiliary/trait-diag.rs:LL:COL
+   |
+LL | pub trait Trait: std::fmt::Display {}
+   |                  ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.only-macro-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.only-macro-in-deps.stderr
new file mode 100644
index 00000000000..d13333d2e48
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-diagnostics.only-macro-in-deps.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `A` doesn't implement `std::fmt::Display`
+  --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
+   |
+LL | impl r#trait::Trait for A {}
+   |                         ^ `A` cannot be formatted with the default formatter
+   |
+   = help: the trait `std::fmt::Display` is not implemented for `A`
+   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `Trait`
+  --> $DIR/auxiliary/trait-macro.rs:LL:COL
+   |
+LL | pub trait Trait: std::fmt::Display {}
+   |                  ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.rs b/tests/ui/errors/remap-path-prefix-diagnostics.rs
new file mode 100644
index 00000000000..fac7e937cb0
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-diagnostics.rs
@@ -0,0 +1,57 @@
+// This test exercises `-Zremap-path-scope`, diagnostics printing paths and dependency.
+//
+// We test different combinations with/without remap in deps, with/without remap in this
+// crate but always in deps and always here but never in deps.
+
+//@ revisions: with-diag-in-deps with-macro-in-deps with-debuginfo-in-deps
+//@ revisions: only-diag-in-deps only-macro-in-deps only-debuginfo-in-deps
+//@ revisions: not-diag-in-deps
+
+//@[with-diag-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@[with-macro-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@[with-debuginfo-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@[not-diag-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
+
+//@[with-diag-in-deps] compile-flags: -Zremap-path-scope=diagnostics
+//@[with-macro-in-deps] compile-flags: -Zremap-path-scope=macro
+//@[with-debuginfo-in-deps] compile-flags: -Zremap-path-scope=debuginfo
+//@[not-diag-in-deps] compile-flags: -Zremap-path-scope=diagnostics
+
+//@[with-diag-in-deps] aux-build:trait-diag.rs
+//@[with-macro-in-deps] aux-build:trait-macro.rs
+//@[with-debuginfo-in-deps] aux-build:trait-debuginfo.rs
+//@[only-diag-in-deps] aux-build:trait-diag.rs
+//@[only-macro-in-deps] aux-build:trait-macro.rs
+//@[only-debuginfo-in-deps] aux-build:trait-debuginfo.rs
+//@[not-diag-in-deps] aux-build:trait.rs
+
+// The $SRC_DIR*.rs:LL:COL normalisation doesn't kick in automatically
+// as the remapped revision will not begin with $SRC_DIR_REAL,
+// so we have to do it ourselves.
+//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:COL"
+
+#[cfg(any(with_diag_in_deps, only_diag_in_deps))]
+extern crate trait_diag as r#trait;
+
+#[cfg(any(with_macro_in_deps, only_macro_in_deps))]
+extern crate trait_macro as r#trait;
+
+#[cfg(any(with_debuginfo_in_deps, only_debuginfo_in_deps))]
+extern crate trait_debuginfo as r#trait;
+
+#[cfg(not_diag_in_deps)]
+extern crate r#trait as r#trait;
+
+struct A;
+
+impl r#trait::Trait for A {}
+//[with-macro-in-deps]~^ ERROR `A` doesn't implement `std::fmt::Display`
+//[with-debuginfo-in-deps]~^^ ERROR `A` doesn't implement `std::fmt::Display`
+//[only-diag-in-deps]~^^^ ERROR `A` doesn't implement `std::fmt::Display`
+//[only-macro-in-deps]~^^^^ ERROR `A` doesn't implement `std::fmt::Display`
+//[only-debuginfo-in-deps]~^^^^^ ERROR `A` doesn't implement `std::fmt::Display`
+
+//[with-diag-in-deps]~? ERROR `A` doesn't implement `std::fmt::Display`
+//[not-diag-in-deps]~? ERROR `A` doesn't implement `std::fmt::Display`
+
+fn main() {}
diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.with-debuginfo-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.with-debuginfo-in-deps.stderr
new file mode 100644
index 00000000000..85c781425b1
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-diagnostics.with-debuginfo-in-deps.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `A` doesn't implement `std::fmt::Display`
+  --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
+   |
+LL | impl r#trait::Trait for A {}
+   |                         ^ `A` cannot be formatted with the default formatter
+   |
+   = help: the trait `std::fmt::Display` is not implemented for `A`
+   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `Trait`
+  --> $DIR/auxiliary/trait-debuginfo.rs:LL:COL
+   |
+LL | pub trait Trait: std::fmt::Display {}
+   |                  ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.with-diag-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.with-diag-in-deps.stderr
new file mode 100644
index 00000000000..08f7fb2c736
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-diagnostics.with-diag-in-deps.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `A` doesn't implement `std::fmt::Display`
+  --> remapped/errors/remap-path-prefix-diagnostics.rs:LL:COL
+   |
+LL | impl r#trait::Trait for A {}
+   |                         ^ `A` cannot be formatted with the default formatter
+   |
+   = help: the trait `std::fmt::Display` is not implemented for `A`
+   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `Trait`
+  --> remapped/errors/auxiliary/trait-diag.rs:LL:COL
+   |
+LL | pub trait Trait: std::fmt::Display {}
+   |                  ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.with-macro-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.with-macro-in-deps.stderr
new file mode 100644
index 00000000000..d13333d2e48
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-diagnostics.with-macro-in-deps.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `A` doesn't implement `std::fmt::Display`
+  --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
+   |
+LL | impl r#trait::Trait for A {}
+   |                         ^ `A` cannot be formatted with the default formatter
+   |
+   = help: the trait `std::fmt::Display` is not implemented for `A`
+   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `Trait`
+  --> $DIR/auxiliary/trait-macro.rs:LL:COL
+   |
+LL | pub trait Trait: std::fmt::Display {}
+   |                  ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/errors/remap-path-prefix-macro.normal.run.stdout b/tests/ui/errors/remap-path-prefix-macro.normal.run.stdout
deleted file mode 100644
index 3bbdcbb8655..00000000000
--- a/tests/ui/errors/remap-path-prefix-macro.normal.run.stdout
+++ /dev/null
@@ -1 +0,0 @@
-remapped/errors/remap-path-prefix-macro.rs
diff --git a/tests/ui/errors/remap-path-prefix-macro.not-macro-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.not-macro-in-deps.run.stdout
new file mode 100644
index 00000000000..13d4611ae54
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-macro.not-macro-in-deps.run.stdout
@@ -0,0 +1,3 @@
+file::my_file!() = remapped/errors/remap-path-prefix-macro.rs
+file::file() = $DIR/auxiliary/file.rs
+file!() = remapped/errors/remap-path-prefix-macro.rs
diff --git a/tests/ui/errors/remap-path-prefix-macro.only-debuginfo-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.only-debuginfo-in-deps.run.stdout
new file mode 100644
index 00000000000..b2c62ac88c0
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-macro.only-debuginfo-in-deps.run.stdout
@@ -0,0 +1,3 @@
+file::my_file!() = $DIR/remap-path-prefix-macro.rs
+file::file() = $DIR/auxiliary/file-debuginfo.rs
+file!() = $DIR/remap-path-prefix-macro.rs
diff --git a/tests/ui/errors/remap-path-prefix-macro.only-diag-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.only-diag-in-deps.run.stdout
new file mode 100644
index 00000000000..e64cc072361
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-macro.only-diag-in-deps.run.stdout
@@ -0,0 +1,3 @@
+file::my_file!() = $DIR/remap-path-prefix-macro.rs
+file::file() = $DIR/auxiliary/file-diag.rs
+file!() = $DIR/remap-path-prefix-macro.rs
diff --git a/tests/ui/errors/remap-path-prefix-macro.only-macro-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.only-macro-in-deps.run.stdout
new file mode 100644
index 00000000000..b1a93a5bc1e
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-macro.only-macro-in-deps.run.stdout
@@ -0,0 +1,3 @@
+file::my_file!() = $DIR/remap-path-prefix-macro.rs
+file::file() = remapped/errors/auxiliary/file-macro.rs
+file!() = $DIR/remap-path-prefix-macro.rs
diff --git a/tests/ui/errors/remap-path-prefix-macro.rs b/tests/ui/errors/remap-path-prefix-macro.rs
index 665156027c9..3e93843f916 100644
--- a/tests/ui/errors/remap-path-prefix-macro.rs
+++ b/tests/ui/errors/remap-path-prefix-macro.rs
@@ -1,12 +1,47 @@
+// This test exercises `-Zremap-path-scope`, macros (like file!()) and dependency.
+//
+// We test different combinations with/without remap in deps, with/without remap in
+// this crate but always in deps and always here but never in deps.
+
 //@ run-pass
 //@ check-run-results
 
-//@ revisions: normal with-macro-scope without-macro-scope
-//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
-//@ [with-macro-scope]compile-flags: -Zremap-path-scope=macro,diagnostics
-//@ [without-macro-scope]compile-flags: -Zremap-path-scope=diagnostics
-// no-remap-src-base: Manually remap, so the remapped path remains in .stderr file.
+//@ revisions: with-diag-in-deps with-macro-in-deps with-debuginfo-in-deps
+//@ revisions: only-diag-in-deps only-macro-in-deps only-debuginfo-in-deps
+//@ revisions: not-macro-in-deps
+
+//@[with-diag-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@[with-macro-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@[with-debuginfo-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
+//@[not-macro-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
+
+//@[with-diag-in-deps] compile-flags: -Zremap-path-scope=diagnostics
+//@[with-macro-in-deps] compile-flags: -Zremap-path-scope=macro
+//@[with-debuginfo-in-deps] compile-flags: -Zremap-path-scope=debuginfo
+//@[not-macro-in-deps] compile-flags: -Zremap-path-scope=macro
+
+//@[with-diag-in-deps] aux-build:file-diag.rs
+//@[with-macro-in-deps] aux-build:file-macro.rs
+//@[with-debuginfo-in-deps] aux-build:file-debuginfo.rs
+//@[only-diag-in-deps] aux-build:file-diag.rs
+//@[only-macro-in-deps] aux-build:file-macro.rs
+//@[only-debuginfo-in-deps] aux-build:file-debuginfo.rs
+//@[not-macro-in-deps] aux-build:file.rs
+
+#[cfg(any(with_diag_in_deps, only_diag_in_deps))]
+extern crate file_diag as file;
+
+#[cfg(any(with_macro_in_deps, only_macro_in_deps))]
+extern crate file_macro as file;
+
+#[cfg(any(with_debuginfo_in_deps, only_debuginfo_in_deps))]
+extern crate file_debuginfo as file;
+
+#[cfg(not_macro_in_deps)]
+extern crate file;
 
 fn main() {
-    println!("{}", file!());
+    println!("file::my_file!() = {}", file::my_file!());
+    println!("file::file() = {}", file::file());
+    println!("file!() = {}", file!());
 }
diff --git a/tests/ui/errors/remap-path-prefix-macro.with-debuginfo-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.with-debuginfo-in-deps.run.stdout
new file mode 100644
index 00000000000..b2c62ac88c0
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-macro.with-debuginfo-in-deps.run.stdout
@@ -0,0 +1,3 @@
+file::my_file!() = $DIR/remap-path-prefix-macro.rs
+file::file() = $DIR/auxiliary/file-debuginfo.rs
+file!() = $DIR/remap-path-prefix-macro.rs
diff --git a/tests/ui/errors/remap-path-prefix-macro.with-diag-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.with-diag-in-deps.run.stdout
new file mode 100644
index 00000000000..e64cc072361
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-macro.with-diag-in-deps.run.stdout
@@ -0,0 +1,3 @@
+file::my_file!() = $DIR/remap-path-prefix-macro.rs
+file::file() = $DIR/auxiliary/file-diag.rs
+file!() = $DIR/remap-path-prefix-macro.rs
diff --git a/tests/ui/errors/remap-path-prefix-macro.with-macro-in-deps.run.stdout b/tests/ui/errors/remap-path-prefix-macro.with-macro-in-deps.run.stdout
new file mode 100644
index 00000000000..5c1781dda16
--- /dev/null
+++ b/tests/ui/errors/remap-path-prefix-macro.with-macro-in-deps.run.stdout
@@ -0,0 +1,3 @@
+file::my_file!() = remapped/errors/remap-path-prefix-macro.rs
+file::file() = remapped/errors/auxiliary/file-macro.rs
+file!() = remapped/errors/remap-path-prefix-macro.rs
diff --git a/tests/ui/errors/remap-path-prefix-macro.with-macro-scope.run.stdout b/tests/ui/errors/remap-path-prefix-macro.with-macro-scope.run.stdout
deleted file mode 100644
index 3bbdcbb8655..00000000000
--- a/tests/ui/errors/remap-path-prefix-macro.with-macro-scope.run.stdout
+++ /dev/null
@@ -1 +0,0 @@
-remapped/errors/remap-path-prefix-macro.rs
diff --git a/tests/ui/errors/remap-path-prefix-macro.without-macro-scope.run.stdout b/tests/ui/errors/remap-path-prefix-macro.without-macro-scope.run.stdout
deleted file mode 100644
index 642823fec86..00000000000
--- a/tests/ui/errors/remap-path-prefix-macro.without-macro-scope.run.stdout
+++ /dev/null
@@ -1 +0,0 @@
-$DIR/remap-path-prefix-macro.rs
diff --git a/tests/ui/explain.rs b/tests/ui/explain/basic.rs
index 1206c4f95eb..1206c4f95eb 100644
--- a/tests/ui/explain.rs
+++ b/tests/ui/explain/basic.rs
diff --git a/tests/ui/explain.stdout b/tests/ui/explain/basic.stdout
index ef1d866c3ff..ef1d866c3ff 100644
--- a/tests/ui/explain.stdout
+++ b/tests/ui/explain/basic.stdout
diff --git a/tests/ui/explain/error-with-no-explanation.rs b/tests/ui/explain/error-with-no-explanation.rs
new file mode 100644
index 00000000000..383820eb458
--- /dev/null
+++ b/tests/ui/explain/error-with-no-explanation.rs
@@ -0,0 +1,3 @@
+// It's a valid error with no added explanation
+//@ compile-flags: --explain E9999
+//~? ERROR: E9999 is not a valid error code
diff --git a/tests/ui/explain/error-with-no-explanation.stderr b/tests/ui/explain/error-with-no-explanation.stderr
new file mode 100644
index 00000000000..afb738cfecb
--- /dev/null
+++ b/tests/ui/explain/error-with-no-explanation.stderr
@@ -0,0 +1,2 @@
+error: E9999 is not a valid error code
+
diff --git a/tests/ui/explain/invalid-error-code.rs b/tests/ui/explain/invalid-error-code.rs
new file mode 100644
index 00000000000..114118d5196
--- /dev/null
+++ b/tests/ui/explain/invalid-error-code.rs
@@ -0,0 +1,2 @@
+//@ compile-flags: --explain error_code
+//~? ERROR: error_code is not a valid error code
diff --git a/tests/ui/explain/invalid-error-code.stderr b/tests/ui/explain/invalid-error-code.stderr
new file mode 100644
index 00000000000..c33122ea88c
--- /dev/null
+++ b/tests/ui/explain/invalid-error-code.stderr
@@ -0,0 +1,2 @@
+error: error_code is not a valid error code
+
diff --git a/tests/ui/explain/no-E-prefix.rs b/tests/ui/explain/no-E-prefix.rs
new file mode 100644
index 00000000000..39c9122bfe1
--- /dev/null
+++ b/tests/ui/explain/no-E-prefix.rs
@@ -0,0 +1,2 @@
+//@ compile-flags: --explain 425
+//@ check-pass
diff --git a/tests/ui/explain/no-E-prefix.stdout b/tests/ui/explain/no-E-prefix.stdout
new file mode 100644
index 00000000000..756b970aa7e
--- /dev/null
+++ b/tests/ui/explain/no-E-prefix.stdout
@@ -0,0 +1,57 @@
+An unresolved name was used.
+
+Erroneous code examples:
+
+```
+something_that_doesnt_exist::foo;
+// error: unresolved name `something_that_doesnt_exist::foo`
+
+// or:
+
+trait Foo {
+    fn bar() {
+        Self; // error: unresolved name `Self`
+    }
+}
+
+// or:
+
+let x = unknown_variable;  // error: unresolved name `unknown_variable`
+```
+
+Please verify that the name wasn't misspelled and ensure that the
+identifier being referred to is valid for the given situation. Example:
+
+```
+enum something_that_does_exist {
+    Foo,
+}
+```
+
+Or:
+
+```
+mod something_that_does_exist {
+    pub static foo : i32 = 0i32;
+}
+
+something_that_does_exist::foo; // ok!
+```
+
+Or:
+
+```
+let unknown_variable = 12u32;
+let x = unknown_variable; // ok!
+```
+
+If the item is not defined in the current module, it must be imported using a
+`use` statement, like so:
+
+```
+use foo::bar;
+bar();
+```
+
+If the item you are importing is not defined in some super-module of the
+current module, then it must also be declared as public (e.g., `pub fn`).
diff --git a/tests/ui/explain/overflow-error-code.rs b/tests/ui/explain/overflow-error-code.rs
new file mode 100644
index 00000000000..284d5cddb35
--- /dev/null
+++ b/tests/ui/explain/overflow-error-code.rs
@@ -0,0 +1,4 @@
+// Check that we don't crash on error codes exceeding our internal limit.
+// issue: <https://github.com/rust-lang/rust/issues/140647>
+//@ compile-flags: --explain E10000
+//~? ERROR: E10000 is not a valid error code
diff --git a/tests/ui/explain/overflow-error-code.stderr b/tests/ui/explain/overflow-error-code.stderr
new file mode 100644
index 00000000000..67e584ea32e
--- /dev/null
+++ b/tests/ui/explain/overflow-error-code.stderr
@@ -0,0 +1,2 @@
+error: E10000 is not a valid error code
+
diff --git a/tests/ui/feature-gates/bench.rs b/tests/ui/feature-gates/bench.rs
index 12e646f7a32..94c8992a8fe 100644
--- a/tests/ui/feature-gates/bench.rs
+++ b/tests/ui/feature-gates/bench.rs
@@ -1,9 +1,7 @@
 //@ edition:2018
 
 #[bench] //~ ERROR use of unstable library feature `test`
-         //~| WARN this was previously accepted
 fn bench() {}
 
 use bench as _; //~ ERROR use of unstable library feature `test`
-                //~| WARN this was previously accepted
 fn main() {}
diff --git a/tests/ui/feature-gates/bench.stderr b/tests/ui/feature-gates/bench.stderr
index de78e863012..f5fc579b23b 100644
--- a/tests/ui/feature-gates/bench.stderr
+++ b/tests/ui/feature-gates/bench.stderr
@@ -1,43 +1,23 @@
-error: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable
+error[E0658]: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable
   --> $DIR/bench.rs:3:3
    |
 LL | #[bench]
    |   ^^^^^
    |
-   = 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 #64266 <https://github.com/rust-lang/rust/issues/64266>
-   = note: `#[deny(soft_unstable)]` on by default
+   = note: see issue #50297 <https://github.com/rust-lang/rust/issues/50297> for more information
+   = help: add `#![feature(test)]` 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: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable
-  --> $DIR/bench.rs:7:5
+error[E0658]: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable
+  --> $DIR/bench.rs:6:5
    |
 LL | use bench as _;
    |     ^^^^^
    |
-   = 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 #64266 <https://github.com/rust-lang/rust/issues/64266>
+   = note: see issue #50297 <https://github.com/rust-lang/rust/issues/50297> for more information
+   = help: add `#![feature(test)]` 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
 
-Future incompatibility report: Future breakage diagnostic:
-error: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable
-  --> $DIR/bench.rs:3:3
-   |
-LL | #[bench]
-   |   ^^^^^
-   |
-   = 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 #64266 <https://github.com/rust-lang/rust/issues/64266>
-   = note: `#[deny(soft_unstable)]` on by default
-
-Future breakage diagnostic:
-error: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable
-  --> $DIR/bench.rs:7:5
-   |
-LL | use bench as _;
-   |     ^^^^^
-   |
-   = 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 #64266 <https://github.com/rust-lang/rust/issues/64266>
-   = note: `#[deny(soft_unstable)]` on by default
-
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-apx-target-feature.rs b/tests/ui/feature-gates/feature-gate-apx-target-feature.rs
new file mode 100644
index 00000000000..a2ac4ac86ac
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-apx-target-feature.rs
@@ -0,0 +1,6 @@
+//@ only-x86_64
+#[target_feature(enable = "apxf")]
+//~^ ERROR: currently unstable
+unsafe fn foo() {}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-apx-target-feature.stderr b/tests/ui/feature-gates/feature-gate-apx-target-feature.stderr
new file mode 100644
index 00000000000..1999ab53537
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-apx-target-feature.stderr
@@ -0,0 +1,13 @@
+error[E0658]: the target feature `apxf` is currently unstable
+  --> $DIR/feature-gate-apx-target-feature.rs:2:18
+   |
+LL | #[target_feature(enable = "apxf")]
+   |                  ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #139284 <https://github.com/rust-lang/rust/issues/139284> for more information
+   = help: add `#![feature(apx_target_feature)]` 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 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-avx10_target_feature.rs b/tests/ui/feature-gates/feature-gate-avx10_target_feature.rs
new file mode 100644
index 00000000000..8557e67d1f4
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-avx10_target_feature.rs
@@ -0,0 +1,6 @@
+//@ only-x86_64
+#[target_feature(enable = "avx10.1")]
+//~^ ERROR: currently unstable
+unsafe fn foo() {}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-avx10_target_feature.stderr b/tests/ui/feature-gates/feature-gate-avx10_target_feature.stderr
new file mode 100644
index 00000000000..e45ea3524ca
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-avx10_target_feature.stderr
@@ -0,0 +1,13 @@
+error[E0658]: the target feature `avx10.1` is currently unstable
+  --> $DIR/feature-gate-avx10_target_feature.rs:2:18
+   |
+LL | #[target_feature(enable = "avx10.1")]
+   |                  ^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #138843 <https://github.com/rust-lang/rust/issues/138843> for more information
+   = help: add `#![feature(avx10_target_feature)]` 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 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-export_stable.rs b/tests/ui/feature-gates/feature-gate-export_stable.rs
new file mode 100644
index 00000000000..5d05fee059b
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-export_stable.rs
@@ -0,0 +1,5 @@
+#![crate_type="lib"]
+
+#[export_stable]
+//~^ ERROR the `#[export_stable]` attribute is an experimental feature
+pub mod a {}
diff --git a/tests/ui/feature-gates/feature-gate-export_stable.stderr b/tests/ui/feature-gates/feature-gate-export_stable.stderr
new file mode 100644
index 00000000000..6beb52a77e5
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-export_stable.stderr
@@ -0,0 +1,13 @@
+error[E0658]: the `#[export_stable]` attribute is an experimental feature
+  --> $DIR/feature-gate-export_stable.rs:3:1
+   |
+LL | #[export_stable]
+   | ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #139939 <https://github.com/rust-lang/rust/issues/139939> for more information
+   = help: add `#![feature(export_stable)]` 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 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-frontmatter.rs b/tests/ui/feature-gates/feature-gate-frontmatter.rs
new file mode 100644
index 00000000000..58e1f57eec0
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-frontmatter.rs
@@ -0,0 +1,5 @@
+---cargo
+//~^ ERROR: frontmatters are experimental
+---
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-frontmatter.stderr b/tests/ui/feature-gates/feature-gate-frontmatter.stderr
new file mode 100644
index 00000000000..57d38db8e76
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-frontmatter.stderr
@@ -0,0 +1,15 @@
+error[E0658]: frontmatters are experimental
+  --> $DIR/feature-gate-frontmatter.rs:1:1
+   |
+LL | / ---cargo
+LL | |
+LL | | ---
+   | |___^
+   |
+   = note: see issue #136889 <https://github.com/rust-lang/rust/issues/136889> for more information
+   = help: add `#![feature(frontmatter)]` 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 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs
index aec13fb0202..c2c010eaba6 100644
--- a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs
+++ b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs
@@ -60,4 +60,7 @@ fn f() {
     let t: Option<S> = DEFAULT;
 }
 
+trait Glob {}
+use Glob::*; //~ ERROR `use` associated items of traits is unstable
+
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr
index d342f5bd551..fca3cef3e20 100644
--- a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr
+++ b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr
@@ -48,6 +48,16 @@ LL |     use super::A::{self, DEFAULT, new};
    = help: add `#![feature(import_trait_associated_functions)]` 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 5 previous errors
+error[E0658]: `use` associated items of traits is unstable
+  --> $DIR/feature-gate-import-trait-associated-functions.rs:64:5
+   |
+LL | use Glob::*;
+   |     ^^^^^^^
+   |
+   = note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
+   = help: add `#![feature(import_trait_associated_functions)]` 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 6 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/fn/fn-trait-use-named-params-issue-140169.rs b/tests/ui/fn/fn-trait-use-named-params-issue-140169.rs
new file mode 100644
index 00000000000..218450abd49
--- /dev/null
+++ b/tests/ui/fn/fn-trait-use-named-params-issue-140169.rs
@@ -0,0 +1,12 @@
+fn f1(_: fn(a: u8)) {}
+fn f2(_: impl Fn(u8, vvvv: u8)) {} //~ ERROR `Trait(...)` syntax does not support named parameters
+fn f3(_: impl Fn(aaaa: u8, u8)) {} //~ ERROR `Trait(...)` syntax does not support named parameters
+fn f4(_: impl Fn(aaaa: u8, vvvv: u8)) {}
+//~^ ERROR `Trait(...)` syntax does not support named parameters
+//~| ERROR `Trait(...)` syntax does not support named parameters
+fn f5(_: impl Fn(u8, ...)) {}
+//~^ ERROR `Trait(...)` syntax does not support c_variadic parameters
+fn f6(_: impl Fn(u8, #[allow(unused_attributes)] u8)) {}
+//~^ ERROR `Trait(...)` syntax does not support attributes in parameters
+
+fn main(){}
diff --git a/tests/ui/fn/fn-trait-use-named-params-issue-140169.stderr b/tests/ui/fn/fn-trait-use-named-params-issue-140169.stderr
new file mode 100644
index 00000000000..b72d5b7b3bc
--- /dev/null
+++ b/tests/ui/fn/fn-trait-use-named-params-issue-140169.stderr
@@ -0,0 +1,38 @@
+error: `Trait(...)` syntax does not support named parameters
+  --> $DIR/fn-trait-use-named-params-issue-140169.rs:2:22
+   |
+LL | fn f2(_: impl Fn(u8, vvvv: u8)) {}
+   |                      ^^^^ help: remove the parameter name
+
+error: `Trait(...)` syntax does not support named parameters
+  --> $DIR/fn-trait-use-named-params-issue-140169.rs:3:18
+   |
+LL | fn f3(_: impl Fn(aaaa: u8, u8)) {}
+   |                  ^^^^ help: remove the parameter name
+
+error: `Trait(...)` syntax does not support named parameters
+  --> $DIR/fn-trait-use-named-params-issue-140169.rs:4:18
+   |
+LL | fn f4(_: impl Fn(aaaa: u8, vvvv: u8)) {}
+   |                  ^^^^ help: remove the parameter name
+
+error: `Trait(...)` syntax does not support named parameters
+  --> $DIR/fn-trait-use-named-params-issue-140169.rs:4:28
+   |
+LL | fn f4(_: impl Fn(aaaa: u8, vvvv: u8)) {}
+   |                            ^^^^ help: remove the parameter name
+
+error: `Trait(...)` syntax does not support c_variadic parameters
+  --> $DIR/fn-trait-use-named-params-issue-140169.rs:7:22
+   |
+LL | fn f5(_: impl Fn(u8, ...)) {}
+   |                      ^^^ help: remove the `...`
+
+error: `Trait(...)` syntax does not support attributes in parameters
+  --> $DIR/fn-trait-use-named-params-issue-140169.rs:9:22
+   |
+LL | fn f6(_: impl Fn(u8, #[allow(unused_attributes)] u8)) {}
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the attributes
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/fn/param-mismatch-foreign.rs b/tests/ui/fn/param-mismatch-foreign.rs
index eebca29d6c9..2ab2bf95448 100644
--- a/tests/ui/fn/param-mismatch-foreign.rs
+++ b/tests/ui/fn/param-mismatch-foreign.rs
@@ -1,7 +1,6 @@
 extern "C" {
     fn foo(x: i32, y: u32, z: i32);
     //~^ NOTE function defined here
-    //~| NOTE
 }
 
 fn main() {
diff --git a/tests/ui/fn/param-mismatch-foreign.stderr b/tests/ui/fn/param-mismatch-foreign.stderr
index fff3283cbb6..835e0a3343e 100644
--- a/tests/ui/fn/param-mismatch-foreign.stderr
+++ b/tests/ui/fn/param-mismatch-foreign.stderr
@@ -1,5 +1,5 @@
 error[E0061]: this function takes 3 arguments but 2 arguments were supplied
-  --> $DIR/param-mismatch-foreign.rs:8:5
+  --> $DIR/param-mismatch-foreign.rs:7:5
    |
 LL |     foo(1i32, 2i32);
    |     ^^^       ---- argument #2 of type `u32` is missing
diff --git a/tests/ui/fn/signature-error-reporting-under-verbose.rs b/tests/ui/fn/signature-error-reporting-under-verbose.rs
index 4a72da78978..0047d452b7a 100644
--- a/tests/ui/fn/signature-error-reporting-under-verbose.rs
+++ b/tests/ui/fn/signature-error-reporting-under-verbose.rs
@@ -4,7 +4,6 @@ fn foo(_: i32, _: i32) {}
 
 fn needs_ptr(_: fn(i32, u32)) {}
 //~^ NOTE function defined here
-//~| NOTE
 
 fn main() {
     needs_ptr(foo);
diff --git a/tests/ui/fn/signature-error-reporting-under-verbose.stderr b/tests/ui/fn/signature-error-reporting-under-verbose.stderr
index 6c6a313c4df..d9ccec23fcb 100644
--- a/tests/ui/fn/signature-error-reporting-under-verbose.stderr
+++ b/tests/ui/fn/signature-error-reporting-under-verbose.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/signature-error-reporting-under-verbose.rs:10:15
+  --> $DIR/signature-error-reporting-under-verbose.rs:9:15
    |
 LL |     needs_ptr(foo);
    |     --------- ^^^ expected fn pointer, found fn item
diff --git a/tests/ui/frontmatter/auxiliary/lib.rs b/tests/ui/frontmatter/auxiliary/lib.rs
new file mode 100644
index 00000000000..ff7094f410f
--- /dev/null
+++ b/tests/ui/frontmatter/auxiliary/lib.rs
@@ -0,0 +1,6 @@
+---something
+---
+
+pub fn foo(x: i32) -> i32 {
+    -x
+}
diff --git a/tests/ui/frontmatter/auxiliary/makro.rs b/tests/ui/frontmatter/auxiliary/makro.rs
new file mode 100644
index 00000000000..78e7417afb5
--- /dev/null
+++ b/tests/ui/frontmatter/auxiliary/makro.rs
@@ -0,0 +1,8 @@
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+#[proc_macro]
+pub fn check(_: TokenStream) -> TokenStream {
+    assert!("---\n---".parse::<TokenStream>().unwrap().is_empty());
+    Default::default()
+}
diff --git a/tests/ui/frontmatter/dot-in-infostring-leading.rs b/tests/ui/frontmatter/dot-in-infostring-leading.rs
new file mode 100644
index 00000000000..0d3d699644e
--- /dev/null
+++ b/tests/ui/frontmatter/dot-in-infostring-leading.rs
@@ -0,0 +1,9 @@
+---.toml
+//~^ ERROR: invalid infostring for frontmatter
+---
+
+// infostrings cannot have leading dots
+
+#![feature(frontmatter)]
+
+fn main() {}
diff --git a/tests/ui/frontmatter/dot-in-infostring-leading.stderr b/tests/ui/frontmatter/dot-in-infostring-leading.stderr
new file mode 100644
index 00000000000..bc86bd80eec
--- /dev/null
+++ b/tests/ui/frontmatter/dot-in-infostring-leading.stderr
@@ -0,0 +1,10 @@
+error: invalid infostring for frontmatter
+  --> $DIR/dot-in-infostring-leading.rs:1:4
+   |
+LL | ---.toml
+   |    ^^^^^
+   |
+   = note: frontmatter infostrings must be a single identifier immediately following the opening
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/frontmatter/dot-in-infostring-non-leading.rs b/tests/ui/frontmatter/dot-in-infostring-non-leading.rs
new file mode 100644
index 00000000000..a4d17bb6e81
--- /dev/null
+++ b/tests/ui/frontmatter/dot-in-infostring-non-leading.rs
@@ -0,0 +1,9 @@
+---Cargo.toml
+---
+
+// infostrings can contain dots as long as a dot isn't the first character.
+//@ check-pass
+
+#![feature(frontmatter)]
+
+fn main() {}
diff --git a/tests/ui/frontmatter/escape.rs b/tests/ui/frontmatter/escape.rs
new file mode 100644
index 00000000000..0e6f064607e
--- /dev/null
+++ b/tests/ui/frontmatter/escape.rs
@@ -0,0 +1,14 @@
+----
+
+---
+
+----
+
+//@ check-pass
+
+// This test checks that longer dashes for opening and closing can be used to
+// escape sequences such as three dashes inside the frontmatter block.
+
+#![feature(frontmatter)]
+
+fn main() {}
diff --git a/tests/ui/frontmatter/extra-after-end.rs b/tests/ui/frontmatter/extra-after-end.rs
new file mode 100644
index 00000000000..de2cf4cc85e
--- /dev/null
+++ b/tests/ui/frontmatter/extra-after-end.rs
@@ -0,0 +1,7 @@
+---
+---cargo
+//~^ ERROR: extra characters after frontmatter close are not allowed
+
+#![feature(frontmatter)]
+
+fn main() {}
diff --git a/tests/ui/frontmatter/extra-after-end.stderr b/tests/ui/frontmatter/extra-after-end.stderr
new file mode 100644
index 00000000000..c2770fdfd41
--- /dev/null
+++ b/tests/ui/frontmatter/extra-after-end.stderr
@@ -0,0 +1,8 @@
+error: extra characters after frontmatter close are not allowed
+  --> $DIR/extra-after-end.rs:2:1
+   |
+LL | ---cargo
+   | ^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/frontmatter/frontmatter-after-tokens.rs b/tests/ui/frontmatter/frontmatter-after-tokens.rs
new file mode 100644
index 00000000000..6683991dc4a
--- /dev/null
+++ b/tests/ui/frontmatter/frontmatter-after-tokens.rs
@@ -0,0 +1,10 @@
+#![feature(frontmatter)]
+
+---
+//~^ ERROR: expected item, found `-`
+// FIXME(frontmatter): make this diagnostic better
+---
+
+// frontmatters must be at the start of a file. This test ensures that.
+
+fn main() {}
diff --git a/tests/ui/frontmatter/frontmatter-after-tokens.stderr b/tests/ui/frontmatter/frontmatter-after-tokens.stderr
new file mode 100644
index 00000000000..919456924d0
--- /dev/null
+++ b/tests/ui/frontmatter/frontmatter-after-tokens.stderr
@@ -0,0 +1,10 @@
+error: expected item, found `-`
+  --> $DIR/frontmatter-after-tokens.rs:3:1
+   |
+LL | ---
+   | ^ expected item
+   |
+   = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/frontmatter/frontmatter-non-lexible-tokens.rs b/tests/ui/frontmatter/frontmatter-non-lexible-tokens.rs
new file mode 100644
index 00000000000..ea042edef06
--- /dev/null
+++ b/tests/ui/frontmatter/frontmatter-non-lexible-tokens.rs
@@ -0,0 +1,12 @@
+---uwu
+🏳️‍⚧️
+---
+
+//@ check-pass
+
+#![feature(frontmatter)]
+
+// check that frontmatter blocks can have tokens that are otherwise not accepted by
+// the lexer as Rust code.
+
+fn main() {}
diff --git a/tests/ui/frontmatter/frontmatter-whitespace-1.rs b/tests/ui/frontmatter/frontmatter-whitespace-1.rs
new file mode 100644
index 00000000000..8b6e2d1af84
--- /dev/null
+++ b/tests/ui/frontmatter/frontmatter-whitespace-1.rs
@@ -0,0 +1,10 @@
+  ---
+//~^ ERROR: invalid preceding whitespace for frontmatter opening
+  ---
+//~^ ERROR: invalid preceding whitespace for frontmatter close
+
+#![feature(frontmatter)]
+
+// check that whitespaces should not precede the frontmatter opening or close.
+
+fn main() {}
diff --git a/tests/ui/frontmatter/frontmatter-whitespace-1.stderr b/tests/ui/frontmatter/frontmatter-whitespace-1.stderr
new file mode 100644
index 00000000000..37ece27acb2
--- /dev/null
+++ b/tests/ui/frontmatter/frontmatter-whitespace-1.stderr
@@ -0,0 +1,26 @@
+error: invalid preceding whitespace for frontmatter opening
+  --> $DIR/frontmatter-whitespace-1.rs:1:1
+   |
+LL |   ---
+   | ^^^^^
+   |
+note: frontmatter opening should not be preceded by whitespace
+  --> $DIR/frontmatter-whitespace-1.rs:1:1
+   |
+LL |   ---
+   | ^^
+
+error: invalid preceding whitespace for frontmatter close
+  --> $DIR/frontmatter-whitespace-1.rs:3:1
+   |
+LL |   ---
+   | ^^^^^
+   |
+note: frontmatter close should not be preceded by whitespace
+  --> $DIR/frontmatter-whitespace-1.rs:3:1
+   |
+LL |   ---
+   | ^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/frontmatter/frontmatter-whitespace-2.rs b/tests/ui/frontmatter/frontmatter-whitespace-2.rs
new file mode 100644
index 00000000000..e8c100849b4
--- /dev/null
+++ b/tests/ui/frontmatter/frontmatter-whitespace-2.rs
@@ -0,0 +1,15 @@
+---cargo
+
+//@ compile-flags: --crate-type lib
+
+#![feature(frontmatter)]
+
+fn foo(x: i32) -> i32 {
+    ---x
+    //~^ ERROR: invalid preceding whitespace for frontmatter close
+    //~| ERROR: extra characters after frontmatter close are not allowed
+}
+//~^ ERROR: unexpected closing delimiter: `}`
+
+// this test is for the weird case that valid Rust code can have three dashes
+// within them and get treated as a frontmatter close.
diff --git a/tests/ui/frontmatter/frontmatter-whitespace-2.stderr b/tests/ui/frontmatter/frontmatter-whitespace-2.stderr
new file mode 100644
index 00000000000..ada6af0ec04
--- /dev/null
+++ b/tests/ui/frontmatter/frontmatter-whitespace-2.stderr
@@ -0,0 +1,26 @@
+error: invalid preceding whitespace for frontmatter close
+  --> $DIR/frontmatter-whitespace-2.rs:8:1
+   |
+LL |     ---x
+   | ^^^^^^^^
+   |
+note: frontmatter close should not be preceded by whitespace
+  --> $DIR/frontmatter-whitespace-2.rs:8:1
+   |
+LL |     ---x
+   | ^^^^
+
+error: extra characters after frontmatter close are not allowed
+  --> $DIR/frontmatter-whitespace-2.rs:8:1
+   |
+LL |     ---x
+   | ^^^^^^^^
+
+error: unexpected closing delimiter: `}`
+  --> $DIR/frontmatter-whitespace-2.rs:11:1
+   |
+LL | }
+   | ^ unexpected closing delimiter
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/frontmatter/frontmatter-whitespace-3.rs b/tests/ui/frontmatter/frontmatter-whitespace-3.rs
new file mode 100644
index 00000000000..95e0981e2ae
--- /dev/null
+++ b/tests/ui/frontmatter/frontmatter-whitespace-3.rs
@@ -0,0 +1,16 @@
+
+
+---cargo   
+---   
+
+// please note the whitespace characters after the first four lines.
+// This ensures that we accept whitespaces before the frontmatter, after
+// the frontmatter opening and the frontmatter close.
+
+//@ check-pass
+// ignore-tidy-end-whitespace
+// ignore-tidy-leading-newlines
+
+#![feature(frontmatter)]
+
+fn main() {}
diff --git a/tests/ui/frontmatter/frontmatter-whitespace-4.rs b/tests/ui/frontmatter/frontmatter-whitespace-4.rs
new file mode 100644
index 00000000000..3bda3227838
--- /dev/null
+++ b/tests/ui/frontmatter/frontmatter-whitespace-4.rs
@@ -0,0 +1,9 @@
+--- cargo
+---
+
+//@ check-pass
+// A frontmatter infostring can have leading whitespace.
+
+#![feature(frontmatter)]
+
+fn main() {}
diff --git a/tests/ui/frontmatter/included-frontmatter.rs b/tests/ui/frontmatter/included-frontmatter.rs
new file mode 100644
index 00000000000..57616cd1228
--- /dev/null
+++ b/tests/ui/frontmatter/included-frontmatter.rs
@@ -0,0 +1,12 @@
+#![feature(frontmatter)]
+
+//@ check-pass
+
+include!("auxiliary/lib.rs");
+
+// auxiliary/lib.rs contains a frontmatter. Ensure that we can use them in an
+// `include!` macro.
+
+fn main() {
+    foo(1);
+}
diff --git a/tests/ui/frontmatter/infostring-fail.rs b/tests/ui/frontmatter/infostring-fail.rs
new file mode 100644
index 00000000000..91542f62f1a
--- /dev/null
+++ b/tests/ui/frontmatter/infostring-fail.rs
@@ -0,0 +1,9 @@
+---cargo,clippy
+//~^ ERROR: invalid infostring for frontmatter
+---
+
+// infostrings can only be a single identifier.
+
+#![feature(frontmatter)]
+
+fn main() {}
diff --git a/tests/ui/frontmatter/infostring-fail.stderr b/tests/ui/frontmatter/infostring-fail.stderr
new file mode 100644
index 00000000000..6b264abc90f
--- /dev/null
+++ b/tests/ui/frontmatter/infostring-fail.stderr
@@ -0,0 +1,10 @@
+error: invalid infostring for frontmatter
+  --> $DIR/infostring-fail.rs:1:4
+   |
+LL | ---cargo,clippy
+   |    ^^^^^^^^^^^^
+   |
+   = note: frontmatter infostrings must be a single identifier immediately following the opening
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/frontmatter/mismatch-1.rs b/tests/ui/frontmatter/mismatch-1.rs
new file mode 100644
index 00000000000..37e2b0af6b1
--- /dev/null
+++ b/tests/ui/frontmatter/mismatch-1.rs
@@ -0,0 +1,10 @@
+---cargo
+//~^ ERROR: frontmatter close does not match the opening
+----
+
+// there must be the same number of dashes for both the opening and the close
+// of the frontmatter.
+
+#![feature(frontmatter)]
+
+fn main() {}
diff --git a/tests/ui/frontmatter/mismatch-1.stderr b/tests/ui/frontmatter/mismatch-1.stderr
new file mode 100644
index 00000000000..b6e29294d9e
--- /dev/null
+++ b/tests/ui/frontmatter/mismatch-1.stderr
@@ -0,0 +1,16 @@
+error: frontmatter close does not match the opening
+  --> $DIR/mismatch-1.rs:1:1
+   |
+LL |   ---cargo
+   |   ^--
+   |   |
+   |  _the opening here has 3 dashes...
+   | |
+LL | |
+LL | | ----
+   | |_---^
+   |   |
+   |   ...while the close has 4 dashes
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/frontmatter/mismatch-2.rs b/tests/ui/frontmatter/mismatch-2.rs
new file mode 100644
index 00000000000..422abe1d6bc
--- /dev/null
+++ b/tests/ui/frontmatter/mismatch-2.rs
@@ -0,0 +1,8 @@
+----cargo
+//~^ ERROR: frontmatter close does not match the opening
+---cargo
+//~^ ERROR: extra characters after frontmatter close are not allowed
+
+#![feature(frontmatter)]
+
+fn main() {}
diff --git a/tests/ui/frontmatter/mismatch-2.stderr b/tests/ui/frontmatter/mismatch-2.stderr
new file mode 100644
index 00000000000..90bb7b80bce
--- /dev/null
+++ b/tests/ui/frontmatter/mismatch-2.stderr
@@ -0,0 +1,22 @@
+error: frontmatter close does not match the opening
+  --> $DIR/mismatch-2.rs:1:1
+   |
+LL |   ----cargo
+   |   ^---
+   |   |
+   |  _the opening here has 4 dashes...
+   | |
+LL | |
+LL | | ---cargo
+   | |_---____^
+   |   |
+   |   ...while the close has 3 dashes
+
+error: extra characters after frontmatter close are not allowed
+  --> $DIR/mismatch-2.rs:3:1
+   |
+LL | ---cargo
+   | ^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/frontmatter/multifrontmatter-2.rs b/tests/ui/frontmatter/multifrontmatter-2.rs
new file mode 100644
index 00000000000..33cc30cb465
--- /dev/null
+++ b/tests/ui/frontmatter/multifrontmatter-2.rs
@@ -0,0 +1,12 @@
+---
+ ---
+//~^ ERROR: invalid preceding whitespace for frontmatter close
+
+ ---
+//~^ ERROR: expected item, found `-`
+// FIXME(frontmatter): make this diagnostic better
+---
+
+#![feature(frontmatter)]
+
+fn main() {}
diff --git a/tests/ui/frontmatter/multifrontmatter-2.stderr b/tests/ui/frontmatter/multifrontmatter-2.stderr
new file mode 100644
index 00000000000..ed9ac4029e2
--- /dev/null
+++ b/tests/ui/frontmatter/multifrontmatter-2.stderr
@@ -0,0 +1,22 @@
+error: invalid preceding whitespace for frontmatter close
+  --> $DIR/multifrontmatter-2.rs:2:1
+   |
+LL |  ---
+   | ^^^^
+   |
+note: frontmatter close should not be preceded by whitespace
+  --> $DIR/multifrontmatter-2.rs:2:1
+   |
+LL |  ---
+   | ^
+
+error: expected item, found `-`
+  --> $DIR/multifrontmatter-2.rs:5:2
+   |
+LL |  ---
+   |  ^ expected item
+   |
+   = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/frontmatter/multifrontmatter.rs b/tests/ui/frontmatter/multifrontmatter.rs
new file mode 100644
index 00000000000..f3afa47bd38
--- /dev/null
+++ b/tests/ui/frontmatter/multifrontmatter.rs
@@ -0,0 +1,13 @@
+---
+---
+
+---
+//~^ ERROR: expected item, found `-`
+// FIXME(frontmatter): make this diagnostic better
+---
+
+// test that we do not parse another frontmatter block after the first one.
+
+#![feature(frontmatter)]
+
+fn main() {}
diff --git a/tests/ui/frontmatter/multifrontmatter.stderr b/tests/ui/frontmatter/multifrontmatter.stderr
new file mode 100644
index 00000000000..2e9d1cee9dd
--- /dev/null
+++ b/tests/ui/frontmatter/multifrontmatter.stderr
@@ -0,0 +1,10 @@
+error: expected item, found `-`
+  --> $DIR/multifrontmatter.rs:4:1
+   |
+LL | ---
+   | ^ expected item
+   |
+   = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/frontmatter/proc-macro-observer.rs b/tests/ui/frontmatter/proc-macro-observer.rs
new file mode 100644
index 00000000000..bafbe912032
--- /dev/null
+++ b/tests/ui/frontmatter/proc-macro-observer.rs
@@ -0,0 +1,12 @@
+//@ check-pass
+//@ proc-macro: makro.rs
+//@ edition: 2021
+
+#![feature(frontmatter)]
+
+makro::check!();
+
+// checks that a proc-macro cannot observe frontmatter tokens.
+// see auxiliary/makro.rs for how it is tested.
+
+fn main() {}
diff --git a/tests/ui/frontmatter/shebang.rs b/tests/ui/frontmatter/shebang.rs
new file mode 100644
index 00000000000..abd983f219b
--- /dev/null
+++ b/tests/ui/frontmatter/shebang.rs
@@ -0,0 +1,13 @@
+#!/usr/bin/env -S cargo -Zscript
+---
+[dependencies]
+clap = "4"
+---
+
+//@ check-pass
+
+// Shebangs on a file can precede a frontmatter.
+
+#![feature(frontmatter)]
+
+fn main () {}
diff --git a/tests/ui/frontmatter/unclosed-1.rs b/tests/ui/frontmatter/unclosed-1.rs
new file mode 100644
index 00000000000..d8b52b3e69c
--- /dev/null
+++ b/tests/ui/frontmatter/unclosed-1.rs
@@ -0,0 +1,10 @@
+----cargo
+//~^ ERROR: unclosed frontmatter
+
+// This test checks that the #! characters can help us recover a frontmatter
+// close. There should not be a "missing `main` function" error as the rest
+// are properly parsed.
+
+#![feature(frontmatter)]
+
+fn main() {}
diff --git a/tests/ui/frontmatter/unclosed-1.stderr b/tests/ui/frontmatter/unclosed-1.stderr
new file mode 100644
index 00000000000..04031d12839
--- /dev/null
+++ b/tests/ui/frontmatter/unclosed-1.stderr
@@ -0,0 +1,16 @@
+error: unclosed frontmatter
+  --> $DIR/unclosed-1.rs:1:1
+   |
+LL | / ----cargo
+...  |
+LL | |
+   | |_^
+   |
+note: frontmatter opening here was not closed
+  --> $DIR/unclosed-1.rs:1:1
+   |
+LL | ----cargo
+   | ^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/frontmatter/unclosed-2.rs b/tests/ui/frontmatter/unclosed-2.rs
new file mode 100644
index 00000000000..add266dce5b
--- /dev/null
+++ b/tests/ui/frontmatter/unclosed-2.rs
@@ -0,0 +1,15 @@
+----cargo
+//~^ ERROR: unclosed frontmatter
+//~| ERROR: frontmatters are experimental
+
+//@ compile-flags: --crate-type lib
+
+// Leading whitespace on the feature line prevents recovery. However
+// the dashes quoted will not be used for recovery and the entire file
+// should be treated as within the frontmatter block.
+
+ #![feature(frontmatter)]
+
+fn foo() -> &str {
+    "----"
+}
diff --git a/tests/ui/frontmatter/unclosed-2.stderr b/tests/ui/frontmatter/unclosed-2.stderr
new file mode 100644
index 00000000000..0a4022c1557
--- /dev/null
+++ b/tests/ui/frontmatter/unclosed-2.stderr
@@ -0,0 +1,31 @@
+error: unclosed frontmatter
+  --> $DIR/unclosed-2.rs:1:1
+   |
+LL | / ----cargo
+...  |
+LL | |     "----"
+LL | | }
+   | |__^
+   |
+note: frontmatter opening here was not closed
+  --> $DIR/unclosed-2.rs:1:1
+   |
+LL | ----cargo
+   | ^^^^
+
+error[E0658]: frontmatters are experimental
+  --> $DIR/unclosed-2.rs:1:1
+   |
+LL | / ----cargo
+...  |
+LL | |     "----"
+LL | | }
+   | |__^
+   |
+   = note: see issue #136889 <https://github.com/rust-lang/rust/issues/136889> for more information
+   = help: add `#![feature(frontmatter)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/frontmatter/unclosed-3.rs b/tests/ui/frontmatter/unclosed-3.rs
new file mode 100644
index 00000000000..75f3fbda675
--- /dev/null
+++ b/tests/ui/frontmatter/unclosed-3.rs
@@ -0,0 +1,16 @@
+----cargo
+//~^ ERROR: frontmatter close does not match the opening
+
+//@ compile-flags: --crate-type lib
+
+// Unfortunate recovery situation. Not really preventable with improving the
+// recovery strategy, but this type of code is rare enough already.
+
+ #![feature(frontmatter)]
+
+fn foo(x: i32) -> i32 {
+    ---x
+    //~^ ERROR: invalid preceding whitespace for frontmatter close
+    //~| ERROR: extra characters after frontmatter close are not allowed
+}
+//~^ ERROR: unexpected closing delimiter: `}`
diff --git a/tests/ui/frontmatter/unclosed-3.stderr b/tests/ui/frontmatter/unclosed-3.stderr
new file mode 100644
index 00000000000..cd69cb00040
--- /dev/null
+++ b/tests/ui/frontmatter/unclosed-3.stderr
@@ -0,0 +1,41 @@
+error: invalid preceding whitespace for frontmatter close
+  --> $DIR/unclosed-3.rs:12:1
+   |
+LL |     ---x
+   | ^^^^^^^^
+   |
+note: frontmatter close should not be preceded by whitespace
+  --> $DIR/unclosed-3.rs:12:1
+   |
+LL |     ---x
+   | ^^^^
+
+error: frontmatter close does not match the opening
+  --> $DIR/unclosed-3.rs:1:1
+   |
+LL |   ----cargo
+   |   ^---
+   |   |
+   |  _the opening here has 4 dashes...
+   | |
+...  |
+LL | | fn foo(x: i32) -> i32 {
+LL | |     ---x
+   | |_---____^
+   |   |
+   |   ...while the close has 3 dashes
+
+error: extra characters after frontmatter close are not allowed
+  --> $DIR/unclosed-3.rs:12:1
+   |
+LL |     ---x
+   | ^^^^^^^^
+
+error: unexpected closing delimiter: `}`
+  --> $DIR/unclosed-3.rs:15:1
+   |
+LL | }
+   | ^ unexpected closing delimiter
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/frontmatter/unclosed-4.rs b/tests/ui/frontmatter/unclosed-4.rs
new file mode 100644
index 00000000000..41f6461db63
--- /dev/null
+++ b/tests/ui/frontmatter/unclosed-4.rs
@@ -0,0 +1,9 @@
+----cargo
+//~^ ERROR: unclosed frontmatter
+
+//! Similarly, a module-level content should allow for recovery as well (as
+//! per unclosed-1.rs)
+
+#![feature(frontmatter)]
+
+fn main() {}
diff --git a/tests/ui/frontmatter/unclosed-4.stderr b/tests/ui/frontmatter/unclosed-4.stderr
new file mode 100644
index 00000000000..b3ba56937bb
--- /dev/null
+++ b/tests/ui/frontmatter/unclosed-4.stderr
@@ -0,0 +1,16 @@
+error: unclosed frontmatter
+  --> $DIR/unclosed-4.rs:1:1
+   |
+LL | / ----cargo
+LL | |
+LL | |
+   | |_^
+   |
+note: frontmatter opening here was not closed
+  --> $DIR/unclosed-4.rs:1:1
+   |
+LL | ----cargo
+   | ^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/frontmatter/unclosed-5.rs b/tests/ui/frontmatter/unclosed-5.rs
new file mode 100644
index 00000000000..9abbcfff94c
--- /dev/null
+++ b/tests/ui/frontmatter/unclosed-5.rs
@@ -0,0 +1,10 @@
+----cargo
+//~^ ERROR: unclosed frontmatter
+//~| ERROR: frontmatters are experimental
+
+// Similarly, a use statement should allow for recovery as well (as
+// per unclosed-1.rs)
+
+use std::env;
+
+fn main() {}
diff --git a/tests/ui/frontmatter/unclosed-5.stderr b/tests/ui/frontmatter/unclosed-5.stderr
new file mode 100644
index 00000000000..e904014a175
--- /dev/null
+++ b/tests/ui/frontmatter/unclosed-5.stderr
@@ -0,0 +1,29 @@
+error: unclosed frontmatter
+  --> $DIR/unclosed-5.rs:1:1
+   |
+LL | / ----cargo
+...  |
+LL | |
+   | |_^
+   |
+note: frontmatter opening here was not closed
+  --> $DIR/unclosed-5.rs:1:1
+   |
+LL | ----cargo
+   | ^^^^
+
+error[E0658]: frontmatters are experimental
+  --> $DIR/unclosed-5.rs:1:1
+   |
+LL | / ----cargo
+...  |
+LL | |
+   | |_^
+   |
+   = note: see issue #136889 <https://github.com/rust-lang/rust/issues/136889> for more information
+   = help: add `#![feature(frontmatter)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/generic-const-items/user_type_annotations_pattern.rs b/tests/ui/generic-const-items/user_type_annotations_pattern.rs
new file mode 100644
index 00000000000..aa3846df2bc
--- /dev/null
+++ b/tests/ui/generic-const-items/user_type_annotations_pattern.rs
@@ -0,0 +1,14 @@
+#![feature(generic_const_items)]
+#![expect(incomplete_features)]
+
+const FOO<'a: 'static>: usize = 10;
+
+fn bar<'a>() {
+    match 10_usize {
+        FOO::<'a> => todo!(),
+        //~^ ERROR: lifetime may not live long enough
+        _ => todo!(),
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-const-items/user_type_annotations_pattern.stderr b/tests/ui/generic-const-items/user_type_annotations_pattern.stderr
new file mode 100644
index 00000000000..e15be275d29
--- /dev/null
+++ b/tests/ui/generic-const-items/user_type_annotations_pattern.stderr
@@ -0,0 +1,11 @@
+error: lifetime may not live long enough
+  --> $DIR/user_type_annotations_pattern.rs:8:9
+   |
+LL | fn bar<'a>() {
+   |        -- lifetime `'a` defined here
+LL |     match 10_usize {
+LL |         FOO::<'a> => todo!(),
+   |         ^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/impl-privacy-xc-1.rs b/tests/ui/impl-privacy-xc-1.rs
deleted file mode 100644
index 6a10986739c..00000000000
--- a/tests/ui/impl-privacy-xc-1.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ run-pass
-//@ aux-build:impl_privacy_xc_1.rs
-
-
-extern crate impl_privacy_xc_1;
-
-pub fn main() {
-    let fish = impl_privacy_xc_1::Fish { x: 1 };
-    fish.swim();
-}
diff --git a/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.rs b/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.rs
index f1c196a154d..ffb7a1008e0 100644
--- a/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.rs
+++ b/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.rs
@@ -1,6 +1,5 @@
 //@ only-linux
 //@ compile-flags: --error-format=human --color=always
-//@ error-pattern: the trait bound
 
 trait Foo<T>: Bar<T> {}
 
@@ -18,3 +17,5 @@ fn foo() -> impl Foo<i32> {
 }
 
 fn main() {}
+
+//~? RAW the trait bound
diff --git a/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg b/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg
index 1a79a9d7efa..9832e28e008 100644
--- a/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg
+++ b/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg
@@ -1,4 +1,4 @@
-<svg width="1104px" height="398px" xmlns="http://www.w3.org/2000/svg">
+<svg width="1028px" height="398px" xmlns="http://www.w3.org/2000/svg">
   <style>
     .fg { fill: #AAAAAA }
     .bg { background: #000000 }
@@ -23,7 +23,7 @@
   <text xml:space="preserve" class="container fg">
     <tspan x="10px" y="28px"><tspan class="fg-ansi256-009 bold">error[E0277]</tspan><tspan class="bold">: the trait bound `Struct: Foo&lt;i32&gt;` is not satisfied</tspan>
 </tspan>
-    <tspan x="10px" y="46px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/highlight-difference-between-expected-trait-and-found-trait.rs:16:13</tspan>
+    <tspan x="10px" y="46px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/highlight-difference-between-expected-trait-and-found-trait.rs:15:13</tspan>
 </tspan>
     <tspan x="10px" y="64px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
@@ -45,7 +45,7 @@
 </tspan>
     <tspan x="10px" y="226px"><tspan class="fg-ansi256-010 bold">note</tspan><tspan>: required for `Struct` to implement `Foo&lt;i32&gt;`</tspan>
 </tspan>
-    <tspan x="10px" y="244px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/highlight-difference-between-expected-trait-and-found-trait.rs:11:12</tspan>
+    <tspan x="10px" y="244px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/highlight-difference-between-expected-trait-and-found-trait.rs:10:12</tspan>
 </tspan>
     <tspan x="10px" y="262px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
diff --git a/tests/ui/impl-trait/in-trait/doesnt-satisfy.stderr b/tests/ui/impl-trait/in-trait/doesnt-satisfy.stderr
index a9dfac274d5..119195f17ff 100644
--- a/tests/ui/impl-trait/in-trait/doesnt-satisfy.stderr
+++ b/tests/ui/impl-trait/in-trait/doesnt-satisfy.stderr
@@ -6,11 +6,11 @@ LL |     fn bar() -> () {}
    |
    = help: the trait `std::fmt::Display` is not implemented for `()`
    = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
-note: required by a bound in `Foo::{anon_assoc#0}`
+note: required by a bound in `Foo::bar::{anon_assoc#0}`
   --> $DIR/doesnt-satisfy.rs:2:22
    |
 LL |     fn bar() -> impl std::fmt::Display;
-   |                      ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::{anon_assoc#0}`
+   |                      ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::bar::{anon_assoc#0}`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/in-trait/dump.rs b/tests/ui/impl-trait/in-trait/dump.rs
index da3cfd099b5..0a951b4fd99 100644
--- a/tests/ui/impl-trait/in-trait/dump.rs
+++ b/tests/ui/impl-trait/in-trait/dump.rs
@@ -8,7 +8,7 @@ trait Foo {
 }
 
 fn hello<'s, T: Foo>(x: &'s T) -> impl Sized + use<'s, T> {
-//~^ ERROR <T as Foo>::{anon_assoc#0}<'s/#1>
+    //~^ ERROR <T as Foo>::hello::{anon_assoc#0}<'s/#1>
     x.hello()
 }
 
diff --git a/tests/ui/impl-trait/in-trait/dump.stderr b/tests/ui/impl-trait/in-trait/dump.stderr
index 15b6f186ced..35ed21bde11 100644
--- a/tests/ui/impl-trait/in-trait/dump.stderr
+++ b/tests/ui/impl-trait/in-trait/dump.stderr
@@ -1,4 +1,4 @@
-error: <T as Foo>::{anon_assoc#0}<'s/#1>
+error: <T as Foo>::hello::{anon_assoc#0}<'s/#1>
   --> $DIR/dump.rs:10:35
    |
 LL | fn hello<'s, T: Foo>(x: &'s T) -> impl Sized + use<'s, T> {
diff --git a/tests/ui/impl-trait/in-trait/method-compatability-via-leakage-cycle.current.stderr b/tests/ui/impl-trait/in-trait/method-compatability-via-leakage-cycle.current.stderr
index bf598d62709..5d651245746 100644
--- a/tests/ui/impl-trait/in-trait/method-compatability-via-leakage-cycle.current.stderr
+++ b/tests/ui/impl-trait/in-trait/method-compatability-via-leakage-cycle.current.stderr
@@ -1,4 +1,4 @@
-error[E0391]: cycle detected when computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::{anon_assoc#0}`
+error[E0391]: cycle detected when computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::foo::{anon_assoc#0}`
   --> $DIR/method-compatability-via-leakage-cycle.rs:21:24
    |
 LL |     fn foo(b: bool) -> impl Sized {
@@ -45,7 +45,7 @@ note: ...which requires type-checking `<impl at $DIR/method-compatability-via-le
    |
 LL |     fn foo(b: bool) -> impl Sized {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: ...which again requires computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::{anon_assoc#0}`, completing the cycle
+   = note: ...which again requires computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::foo::{anon_assoc#0}`, completing the cycle
 note: cycle used when checking that `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>` is well-formed
   --> $DIR/method-compatability-via-leakage-cycle.rs:17:1
    |
diff --git a/tests/ui/impl-trait/in-trait/method-compatability-via-leakage-cycle.next.stderr b/tests/ui/impl-trait/in-trait/method-compatability-via-leakage-cycle.next.stderr
index 6bec5bbc063..4bbba62bd71 100644
--- a/tests/ui/impl-trait/in-trait/method-compatability-via-leakage-cycle.next.stderr
+++ b/tests/ui/impl-trait/in-trait/method-compatability-via-leakage-cycle.next.stderr
@@ -1,4 +1,4 @@
-error[E0391]: cycle detected when computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::{anon_assoc#0}`
+error[E0391]: cycle detected when computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::foo::{anon_assoc#0}`
   --> $DIR/method-compatability-via-leakage-cycle.rs:21:24
    |
 LL |     fn foo(b: bool) -> impl Sized {
@@ -49,7 +49,7 @@ note: ...which requires type-checking `<impl at $DIR/method-compatability-via-le
    |
 LL |     fn foo(b: bool) -> impl Sized {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: ...which again requires computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::{anon_assoc#0}`, completing the cycle
+   = note: ...which again requires computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::foo::{anon_assoc#0}`, completing the cycle
 note: cycle used when checking that `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>` is well-formed
   --> $DIR/method-compatability-via-leakage-cycle.rs:17:1
    |
@@ -57,7 +57,7 @@ LL | impl Trait for u32 {
    | ^^^^^^^^^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
-error[E0391]: cycle detected when computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::{anon_assoc#0}`
+error[E0391]: cycle detected when computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::foo::{anon_assoc#0}`
   --> $DIR/method-compatability-via-leakage-cycle.rs:21:24
    |
 LL |     fn foo(b: bool) -> impl Sized {
@@ -108,7 +108,7 @@ note: ...which requires type-checking `<impl at $DIR/method-compatability-via-le
    |
 LL |     fn foo(b: bool) -> impl Sized {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: ...which again requires computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::{anon_assoc#0}`, completing the cycle
+   = note: ...which again requires computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::foo::{anon_assoc#0}`, completing the cycle
 note: cycle used when checking that `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>` is well-formed
   --> $DIR/method-compatability-via-leakage-cycle.rs:17:1
    |
diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr
index 6571ce2d5f0..a16e0160223 100644
--- a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr
+++ b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr
@@ -14,11 +14,11 @@ LL |     fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> {
    |                                  ^^^^^^^^^^^^ the trait `Foo<char>` is not implemented for `impl Foo<u8>`
    |
    = help: the trait `Foo<char>` is implemented for `Bar`
-note: required by a bound in `Foo::{anon_assoc#0}`
+note: required by a bound in `Foo::foo::{anon_assoc#0}`
   --> $DIR/return-dont-satisfy-bounds.rs:2:30
    |
 LL |     fn foo<F2>(self) -> impl Foo<T>;
-   |                              ^^^^^^ required by this bound in `Foo::{anon_assoc#0}`
+   |                              ^^^^^^ required by this bound in `Foo::foo::{anon_assoc#0}`
 
 error[E0277]: the trait bound `Bar: Foo<u8>` is not satisfied
   --> $DIR/return-dont-satisfy-bounds.rs:8:34
diff --git a/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.rs b/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.rs
new file mode 100644
index 00000000000..339277fec37
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.rs
@@ -0,0 +1,12 @@
+// Regression test for ICE from issue #140545
+// The error message is confusing and wrong, but that's a different problem (#139350)
+//@ edition:2018
+
+trait Foo {}
+fn a(x: impl Foo) -> impl Foo {
+    if true { x } else { a(a(x)) }
+    //~^ ERROR: expected generic type parameter, found `impl Foo` [E0792]
+    //~| ERROR: type parameter `impl Foo` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+}
+
+fn main(){}
diff --git a/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.stderr b/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.stderr
new file mode 100644
index 00000000000..1b02811e31b
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.stderr
@@ -0,0 +1,17 @@
+error[E0792]: expected generic type parameter, found `impl Foo`
+  --> $DIR/double-wrap-with-defining-use.rs:7:26
+   |
+LL | fn a(x: impl Foo) -> impl Foo {
+   |         -------- this generic parameter must be used with a generic type parameter
+LL |     if true { x } else { a(a(x)) }
+   |                          ^^^^^^^
+
+error: type parameter `impl Foo` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+  --> $DIR/double-wrap-with-defining-use.rs:7:26
+   |
+LL |     if true { x } else { a(a(x)) }
+   |                          ^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/imports/issue-30560.rs b/tests/ui/imports/issue-30560.rs
index d8d4ca608f1..fe5d17c1873 100644
--- a/tests/ui/imports/issue-30560.rs
+++ b/tests/ui/imports/issue-30560.rs
@@ -3,7 +3,4 @@ use Alias::*; //~ ERROR unresolved import `Alias` [E0432]
 
 use std::io::Result::*; //~ ERROR unresolved import `std::io::Result` [E0432]
 
-trait T {}
-use T::*; //~ ERROR items in traits are not importable
-
 fn main() {}
diff --git a/tests/ui/imports/issue-30560.stderr b/tests/ui/imports/issue-30560.stderr
index 69cfd4c06a8..89492261cba 100644
--- a/tests/ui/imports/issue-30560.stderr
+++ b/tests/ui/imports/issue-30560.stderr
@@ -1,9 +1,3 @@
-error: items in traits are not importable
-  --> $DIR/issue-30560.rs:7:5
-   |
-LL | use T::*;
-   |     ^^^^
-
 error[E0432]: unresolved import `Alias`
   --> $DIR/issue-30560.rs:2:5
    |
@@ -16,6 +10,6 @@ error[E0432]: unresolved import `std::io::Result`
 LL | use std::io::Result::*;
    |              ^^^^^^ `Result` is a type alias, not a module
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0432`.
diff --git a/tests/ui/imports/reexports.stderr b/tests/ui/imports/reexports.stderr
index bf4ba474875..fa05c0c0f8e 100644
--- a/tests/ui/imports/reexports.stderr
+++ b/tests/ui/imports/reexports.stderr
@@ -62,7 +62,7 @@ warning: glob import doesn't reexport anything with visibility `pub` because no
 LL |         pub use super::*;
    |                 ^^^^^^^^
    |
-note: the most public imported item is `pub(a)`
+note: the most public imported item is `pub(in crate::a)`
   --> $DIR/reexports.rs:11:17
    |
 LL |         pub use super::*;
diff --git a/tests/ui/inference/detect-old-time-version-format_description-parse.rs b/tests/ui/inference/detect-old-time-version-format_description-parse.rs
deleted file mode 100644
index 386b2a3bf3c..00000000000
--- a/tests/ui/inference/detect-old-time-version-format_description-parse.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-#![crate_name = "time"]
-#![crate_type = "lib"]
-
-// This code compiled without error in Rust 1.79, but started failing in 1.80
-// after the addition of several `impl FromIterator<_> for Box<str>`.
-
-pub fn parse() -> Option<Vec<()>> {
-    let iter = std::iter::once(Some(())).map(|o| o.map(Into::into));
-    let items = iter.collect::<Option<Box<_>>>()?; //~ ERROR E0282
-    //~^ NOTE this is an inference error on crate `time` caused by an API change in Rust 1.80.0; update `time` to version `>=0.3.35`
-    Some(items.into())
-    //~^ NOTE type must be known at this point
-}
diff --git a/tests/ui/inference/detect-old-time-version-format_description-parse.stderr b/tests/ui/inference/detect-old-time-version-format_description-parse.stderr
deleted file mode 100644
index a70ce9dd268..00000000000
--- a/tests/ui/inference/detect-old-time-version-format_description-parse.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0282]: type annotations needed for `Box<_>`
-  --> $DIR/detect-old-time-version-format_description-parse.rs:9:9
-   |
-LL |     let items = iter.collect::<Option<Box<_>>>()?;
-   |         ^^^^^
-LL |
-LL |     Some(items.into())
-   |                ---- type must be known at this point
-   |
-   = note: this is an inference error on crate `time` caused by an API change in Rust 1.80.0; update `time` to version `>=0.3.35` by calling `cargo update`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/inner-static.rs b/tests/ui/inner-static.rs
deleted file mode 100644
index 9455ec5712f..00000000000
--- a/tests/ui/inner-static.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-//@ run-pass
-//@ aux-build:inner_static.rs
-
-
-extern crate inner_static;
-
-pub fn main() {
-    let a = inner_static::A::<()> { v: () };
-    let b = inner_static::B::<()> { v: () };
-    let c = inner_static::test::A::<()> { v: () };
-    assert_eq!(a.bar(), 2);
-    assert_eq!(b.bar(), 4);
-    assert_eq!(c.bar(), 6);
-}
diff --git a/tests/ui/invalid-compile-flags/emit-output-types-without-args.rs b/tests/ui/invalid-compile-flags/emit-output-types-without-args.rs
index a96eeb0a5ce..98d1fefbfb0 100644
--- a/tests/ui/invalid-compile-flags/emit-output-types-without-args.rs
+++ b/tests/ui/invalid-compile-flags/emit-output-types-without-args.rs
@@ -1,2 +1,3 @@
 //@ compile-flags: --emit
-//@ error-pattern: Argument to option 'emit' missing
+
+//~? RAW Argument to option 'emit' missing
diff --git a/tests/ui/issue-13560.rs b/tests/ui/issue-13560.rs
deleted file mode 100644
index 6174fa9324b..00000000000
--- a/tests/ui/issue-13560.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-//@ run-pass
-//@ ignore-cross-compile (needs dylibs and compiletest doesn't have a more specific header)
-//@ aux-build:issue-13560-1.rs
-//@ aux-build:issue-13560-2.rs
-//@ aux-build:issue-13560-3.rs
-
-// Regression test for issue #13560, the test itself is all in the dependent
-// libraries. The fail which previously failed to compile is the one numbered 3.
-
-extern crate issue_13560_2 as t2;
-extern crate issue_13560_3 as t3;
-
-fn main() {}
diff --git a/tests/ui/issue-18502.rs b/tests/ui/issue-18502.rs
deleted file mode 100644
index 3e2c37ee8aa..00000000000
--- a/tests/ui/issue-18502.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ run-pass
-//@ aux-build:issue-18502.rs
-
-extern crate issue_18502 as fmt;
-
-fn main() {
-    ::fmt::baz();
-}
diff --git a/tests/ui/issue-24106.rs b/tests/ui/issue-24106.rs
deleted file mode 100644
index 4f7b299b12f..00000000000
--- a/tests/ui/issue-24106.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ run-pass
-//@ aux-build:issue-24106.rs
-
-extern crate issue_24106;
-
-fn main() {
-    issue_24106::go::<()>();
-}
diff --git a/tests/ui/issue-76387-llvm-miscompile.rs b/tests/ui/issue-76387-llvm-miscompile.rs
deleted file mode 100644
index d674ebb5eaf..00000000000
--- a/tests/ui/issue-76387-llvm-miscompile.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-//@ compile-flags: -C opt-level=3
-//@ aux-build: issue-76387.rs
-//@ run-pass
-
-// Regression test for issue #76387
-// Tests that LLVM doesn't miscompile this
-
-extern crate issue_76387;
-
-use issue_76387::FatPtr;
-
-fn print(data: &[u8]) {
-    println!("{:#?}", data);
-}
-
-fn main() {
-    let ptr = FatPtr::new(20);
-    let data = unsafe { std::slice::from_raw_parts(ptr.as_ptr(), ptr.len()) };
-
-    print(data);
-}
diff --git a/tests/ui/issues/issue-18959.rs b/tests/ui/issues/issue-18959.rs
index f4cab630f2e..6aeb34879ea 100644
--- a/tests/ui/issues/issue-18959.rs
+++ b/tests/ui/issues/issue-18959.rs
@@ -20,5 +20,4 @@ fn main() {
     //~^ ERROR E0038
     //~| ERROR E0038
     foo(test);
-    //~^ ERROR E0038
 }
diff --git a/tests/ui/issues/issue-18959.stderr b/tests/ui/issues/issue-18959.stderr
index c37c4177bfc..1e050b115e5 100644
--- a/tests/ui/issues/issue-18959.stderr
+++ b/tests/ui/issues/issue-18959.stderr
@@ -31,22 +31,6 @@ LL | pub trait Bar: Foo { }
    = help: consider moving `foo` to another trait
 
 error[E0038]: the trait `Bar` is not dyn compatible
-  --> $DIR/issue-18959.rs:19:15
-   |
-LL |     let test: &dyn Bar = &mut thing;
-   |               ^^^^^^^^ `Bar` is not dyn compatible
-   |
-note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
-  --> $DIR/issue-18959.rs:1:20
-   |
-LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
-   |                    ^^^ ...because method `foo` has generic type parameters
-LL | pub trait Bar: Foo { }
-   |           --- this trait is not dyn compatible...
-   = help: consider moving `foo` to another trait
-
-error[E0038]: the trait `Bar` is not dyn compatible
   --> $DIR/issue-18959.rs:19:26
    |
 LL |     let test: &dyn Bar = &mut thing;
@@ -64,10 +48,10 @@ LL | pub trait Bar: Foo { }
    = note: required for the cast from `&mut Thing` to `&dyn Bar`
 
 error[E0038]: the trait `Bar` is not dyn compatible
-  --> $DIR/issue-18959.rs:22:9
+  --> $DIR/issue-18959.rs:19:15
    |
-LL |     foo(test);
-   |         ^^^^ `Bar` is not dyn compatible
+LL |     let test: &dyn Bar = &mut thing;
+   |               ^^^^^^^^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
       for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
@@ -79,6 +63,6 @@ LL | pub trait Bar: Foo { }
    |           --- this trait is not dyn compatible...
    = help: consider moving `foo` to another trait
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/issues/issue-48131.rs b/tests/ui/issues/issue-48131.rs
index 85664e62ead..a1084ea243b 100644
--- a/tests/ui/issues/issue-48131.rs
+++ b/tests/ui/issues/issue-48131.rs
@@ -1,13 +1,12 @@
 // This note is annotated because the purpose of the test
 // is to ensure that certain other notes are not generated.
-#![deny(unused_unsafe)] //~ NOTE
+#![deny(unused_unsafe)]
 
 
 // (test that no note is generated on this unsafe fn)
 pub unsafe fn a() {
     fn inner() {
         unsafe { /* unnecessary */ } //~ ERROR unnecessary `unsafe`
-                                     //~^ NOTE
     }
 
     inner()
@@ -18,7 +17,6 @@ pub fn b() {
     unsafe {
         fn inner() {
             unsafe { /* unnecessary */ } //~ ERROR unnecessary `unsafe`
-                                         //~^ NOTE
         }
         // `()` is fine to zero-initialize as it is zero sized and inhabited.
         let () = ::std::mem::zeroed();
diff --git a/tests/ui/issues/issue-48131.stderr b/tests/ui/issues/issue-48131.stderr
index 5acc4f16e9f..fe0cd4efae8 100644
--- a/tests/ui/issues/issue-48131.stderr
+++ b/tests/ui/issues/issue-48131.stderr
@@ -11,7 +11,7 @@ LL | #![deny(unused_unsafe)]
    |         ^^^^^^^^^^^^^
 
 error: unnecessary `unsafe` block
-  --> $DIR/issue-48131.rs:20:13
+  --> $DIR/issue-48131.rs:19:13
    |
 LL |             unsafe { /* unnecessary */ }
    |             ^^^^^^ unnecessary `unsafe` block
diff --git a/tests/ui/json/json-bom-plus-crlf-multifile.rs b/tests/ui/json/json-bom-plus-crlf-multifile.rs
index 79c4b2430e1..074a2583e82 100644
--- a/tests/ui/json/json-bom-plus-crlf-multifile.rs
+++ b/tests/ui/json/json-bom-plus-crlf-multifile.rs
@@ -11,3 +11,8 @@ mod json_bom_plus_crlf_multifile_aux;
 fn main() {

     json_bom_plus_crlf_multifile_aux::test();

 }

+

+//~? ERROR mismatched types

+//~? ERROR mismatched types

+//~? ERROR mismatched types

+//~? ERROR mismatched types

diff --git a/tests/ui/json/json-bom-plus-crlf.rs b/tests/ui/json/json-bom-plus-crlf.rs
index 9e250c256eb..900a92f3682 100644
--- a/tests/ui/json/json-bom-plus-crlf.rs
+++ b/tests/ui/json/json-bom-plus-crlf.rs
@@ -16,13 +16,17 @@
 fn main() {

 

     let s : String = 1;  // Error in the middle of line.

+    //~^ ERROR mismatched types

 

     let s : String = 1

     ;  // Error before the newline.

+    //~^^ ERROR mismatched types

 

     let s : String =

 1;  // Error after the newline.

+    //~^ ERROR mismatched types

 

     let s : String = (

     );  // Error spanning the newline.

+    //~^^ ERROR mismatched types

 }

diff --git a/tests/ui/json/json-bom-plus-crlf.stderr b/tests/ui/json/json-bom-plus-crlf.stderr
index fee70431bdf..59f0e8178f0 100644
--- a/tests/ui/json/json-bom-plus-crlf.stderr
+++ b/tests/ui/json/json-bom-plus-crlf.stderr
@@ -52,7 +52,7 @@ This error occurs when an expression was used in a place where the compiler
 expected an expression of a different type. It can occur in several cases, the
 most common being when calling a function and passing an argument which has a
 different type than the matching type in the function declaration.
-"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":732,"byte_end":733,"line_start":20,"line_end":20,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":723,"byte_end":729,"line_start":20,"line_end":20,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":733,"byte_end":733,"line_start":20,"line_end":20,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:20:22: error[E0308]: mismatched types: expected `String`, found integer
+"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":765,"byte_end":766,"line_start":21,"line_end":21,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":756,"byte_end":762,"line_start":21,"line_end":21,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":766,"byte_end":766,"line_start":21,"line_end":21,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:21:22: error[E0308]: mismatched types: expected `String`, found integer
 "}
 {"$message_type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
 
@@ -80,7 +80,7 @@ This error occurs when an expression was used in a place where the compiler
 expected an expression of a different type. It can occur in several cases, the
 most common being when calling a function and passing an argument which has a
 different type than the matching type in the function declaration.
-"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":796,"byte_end":797,"line_start":24,"line_end":24,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":786,"byte_end":792,"line_start":23,"line_end":23,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":797,"byte_end":797,"line_start":24,"line_end":24,"column_start":2,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":2,"highlight_end":2}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:24:1: error[E0308]: mismatched types: expected `String`, found integer
+"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":863,"byte_end":864,"line_start":26,"line_end":26,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":853,"byte_end":859,"line_start":25,"line_end":25,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":864,"byte_end":864,"line_start":26,"line_end":26,"column_start":2,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":2,"highlight_end":2}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:26:1: error[E0308]: mismatched types: expected `String`, found integer
 "}
 {"$message_type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
 
@@ -108,7 +108,7 @@ This error occurs when an expression was used in a place where the compiler
 expected an expression of a different type. It can occur in several cases, the
 most common being when calling a function and passing an argument which has a
 different type than the matching type in the function declaration.
-"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":852,"byte_end":860,"line_start":26,"line_end":27,"column_start":22,"column_end":6,"is_primary":true,"text":[{"text":"    let s : String = (","highlight_start":22,"highlight_end":23},{"text":"    );  // Error spanning the newline.","highlight_start":1,"highlight_end":6}],"label":"expected `String`, found `()`","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":843,"byte_end":849,"line_start":26,"line_end":26,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = (","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"$DIR/json-bom-plus-crlf.rs:26:22: error[E0308]: mismatched types: expected `String`, found `()`
+"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":952,"byte_end":960,"line_start":29,"line_end":30,"column_start":22,"column_end":6,"is_primary":true,"text":[{"text":"    let s : String = (","highlight_start":22,"highlight_end":23},{"text":"    );  // Error spanning the newline.","highlight_start":1,"highlight_end":6}],"label":"expected `String`, found `()`","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":943,"byte_end":949,"line_start":29,"line_end":29,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = (","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"$DIR/json-bom-plus-crlf.rs:29:22: error[E0308]: mismatched types: expected `String`, found `()`
 "}
 {"$message_type":"diagnostic","message":"aborting due to 4 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 4 previous errors
 "}
diff --git a/tests/ui/json/json-short.rs b/tests/ui/json/json-short.rs
index 1b8f0b46366..30b0bce9efa 100644
--- a/tests/ui/json/json-short.rs
+++ b/tests/ui/json/json-short.rs
@@ -1 +1,2 @@
+//~v ERROR `main` function not found in crate `json_short`
 //@ compile-flags: --json=diagnostic-short --error-format=json
diff --git a/tests/ui/json/json-short.stderr b/tests/ui/json/json-short.stderr
index 8a4a55edf68..e8aa7e5d087 100644
--- a/tests/ui/json/json-short.stderr
+++ b/tests/ui/json/json-short.stderr
@@ -13,7 +13,7 @@ If you don't know the basics of Rust, you can look at the
 [Rust Book][rust-book] to get started.
 
 [rust-book]: https://doc.rust-lang.org/book/
-"},"level":"error","spans":[{"file_name":"$DIR/json-short.rs","byte_start":63,"byte_end":63,"line_start":1,"line_end":1,"column_start":64,"column_end":64,"is_primary":true,"text":[{"text":"//@ compile-flags: --json=diagnostic-short --error-format=json","highlight_start":64,"highlight_end":64}],"label":"consider adding a `main` function to `$DIR/json-short.rs`","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"$DIR/json-short.rs:1:64: error[E0601]: `main` function not found in crate `json_short`: consider adding a `main` function to `$DIR/json-short.rs`
+"},"level":"error","spans":[{"file_name":"$DIR/json-short.rs","byte_start":122,"byte_end":122,"line_start":2,"line_end":2,"column_start":64,"column_end":64,"is_primary":true,"text":[{"text":"//@ compile-flags: --json=diagnostic-short --error-format=json","highlight_start":64,"highlight_end":64}],"label":"consider adding a `main` function to `$DIR/json-short.rs`","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"$DIR/json-short.rs:2:64: error[E0601]: `main` function not found in crate `json_short`: consider adding a `main` function to `$DIR/json-short.rs`
 "}
 {"$message_type":"diagnostic","message":"aborting due to 1 previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 1 previous error
 "}
diff --git a/tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr b/tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr
index 05f5449dbc8..85ac98f4050 100644
--- a/tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr
+++ b/tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr
@@ -7,7 +7,7 @@ LL | type Loop = Loop;
    = note: in case this is a recursive type alias, consider using a struct, enum, or union instead
 
 error[E0275]: overflow normalizing the type alias `Loop`
-  --> $DIR/inherent-impls-overflow.rs:10:1
+  --> $DIR/inherent-impls-overflow.rs:12:1
    |
 LL | impl Loop {}
    | ^^^^^^^^^^^^
@@ -15,7 +15,7 @@ LL | impl Loop {}
    = note: in case this is a recursive type alias, consider using a struct, enum, or union instead
 
 error[E0275]: overflow normalizing the type alias `Poly0<(((((((...,),),),),),),)>`
-  --> $DIR/inherent-impls-overflow.rs:14:17
+  --> $DIR/inherent-impls-overflow.rs:17:17
    |
 LL | type Poly0<T> = Poly1<(T,)>;
    |                 ^^^^^^^^^^^
@@ -23,7 +23,7 @@ LL | type Poly0<T> = Poly1<(T,)>;
    = note: in case this is a recursive type alias, consider using a struct, enum, or union instead
 
 error[E0275]: overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>`
-  --> $DIR/inherent-impls-overflow.rs:17:17
+  --> $DIR/inherent-impls-overflow.rs:21:17
    |
 LL | type Poly1<T> = Poly0<(T,)>;
    |                 ^^^^^^^^^^^
@@ -31,7 +31,7 @@ LL | type Poly1<T> = Poly0<(T,)>;
    = note: in case this is a recursive type alias, consider using a struct, enum, or union instead
 
 error[E0275]: overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>`
-  --> $DIR/inherent-impls-overflow.rs:21:1
+  --> $DIR/inherent-impls-overflow.rs:26:1
    |
 LL | impl Poly0<()> {}
    | ^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr b/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr
index 4f1d339bc99..e94f29de44f 100644
--- a/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr
+++ b/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr
@@ -1,11 +1,31 @@
 error[E0271]: type mismatch resolving `Loop normalizes-to _`
-  --> $DIR/inherent-impls-overflow.rs:10:6
+  --> $DIR/inherent-impls-overflow.rs:8:13
+   |
+LL | type Loop = Loop;
+   |             ^^^^ types differ
+
+error[E0271]: type mismatch resolving `Loop normalizes-to _`
+  --> $DIR/inherent-impls-overflow.rs:12:1
+   |
+LL | impl Loop {}
+   | ^^^^^^^^^^^^ types differ
+
+error[E0271]: type mismatch resolving `Loop normalizes-to _`
+  --> $DIR/inherent-impls-overflow.rs:12:6
    |
 LL | impl Loop {}
    |      ^^^^ types differ
 
+error[E0275]: overflow evaluating the requirement `Poly1<(T,)> == _`
+  --> $DIR/inherent-impls-overflow.rs:17:17
+   |
+LL | type Poly0<T> = Poly1<(T,)>;
+   |                 ^^^^^^^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
+
 error: type parameter `T` is only used recursively
-  --> $DIR/inherent-impls-overflow.rs:14:24
+  --> $DIR/inherent-impls-overflow.rs:17:24
    |
 LL | type Poly0<T> = Poly1<(T,)>;
    |            -           ^
@@ -15,8 +35,16 @@ LL | type Poly0<T> = Poly1<(T,)>;
    = help: consider removing `T` or referring to it in the body of the type alias
    = note: all type parameters must be used in a non-recursive way in order to constrain their variance
 
+error[E0275]: overflow evaluating the requirement `Poly0<(T,)> == _`
+  --> $DIR/inherent-impls-overflow.rs:21:17
+   |
+LL | type Poly1<T> = Poly0<(T,)>;
+   |                 ^^^^^^^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
+
 error: type parameter `T` is only used recursively
-  --> $DIR/inherent-impls-overflow.rs:17:24
+  --> $DIR/inherent-impls-overflow.rs:21:24
    |
 LL | type Poly1<T> = Poly0<(T,)>;
    |            -           ^
@@ -27,14 +55,22 @@ LL | type Poly1<T> = Poly0<(T,)>;
    = note: all type parameters must be used in a non-recursive way in order to constrain their variance
 
 error[E0275]: overflow evaluating the requirement `Poly0<()> == _`
-  --> $DIR/inherent-impls-overflow.rs:21:6
+  --> $DIR/inherent-impls-overflow.rs:26:1
+   |
+LL | impl Poly0<()> {}
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
+
+error[E0275]: overflow evaluating the requirement `Poly0<()> == _`
+  --> $DIR/inherent-impls-overflow.rs:26:6
    |
 LL | impl Poly0<()> {}
    |      ^^^^^^^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
 
-error: aborting due to 4 previous errors
+error: aborting due to 9 previous errors
 
 Some errors have detailed explanations: E0271, E0275.
 For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/lazy-type-alias/inherent-impls-overflow.rs b/tests/ui/lazy-type-alias/inherent-impls-overflow.rs
index 0d5ec7d1530..b4a347cb098 100644
--- a/tests/ui/lazy-type-alias/inherent-impls-overflow.rs
+++ b/tests/ui/lazy-type-alias/inherent-impls-overflow.rs
@@ -5,21 +5,27 @@
 #![feature(lazy_type_alias)]
 #![allow(incomplete_features)]
 
-type Loop = Loop; //[current]~ ERROR overflow normalizing the type alias `Loop`
+type Loop = Loop;
+//[current]~^ ERROR overflow normalizing the type alias `Loop`
+//[next]~^^ ERROR type mismatch resolving `Loop normalizes-to _`
 
 impl Loop {}
 //[current]~^ ERROR overflow normalizing the type alias `Loop`
 //[next]~^^ ERROR type mismatch resolving `Loop normalizes-to _`
+//[next]~| ERROR type mismatch resolving `Loop normalizes-to _`
 
 type Poly0<T> = Poly1<(T,)>;
 //[current]~^ ERROR overflow normalizing the type alias `Poly0<(((((((...,),),),),),),)>`
 //[next]~^^ ERROR type parameter `T` is only used recursively
+//[next]~| ERROR overflow evaluating the requirement
 type Poly1<T> = Poly0<(T,)>;
 //[current]~^ ERROR  overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>`
 //[next]~^^ ERROR type parameter `T` is only used recursively
+//[next]~| ERROR overflow evaluating the requirement
 
 impl Poly0<()> {}
 //[current]~^ ERROR overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>`
 //[next]~^^ ERROR overflow evaluating the requirement `Poly0<()> == _`
+//[next]~| ERROR overflow evaluating the requirement
 
 fn main() {}
diff --git a/tests/ui/link-native-libs/lib-defaults.rs b/tests/ui/link-native-libs/lib-defaults.rs
new file mode 100644
index 00000000000..4e38adb643d
--- /dev/null
+++ b/tests/ui/link-native-libs/lib-defaults.rs
@@ -0,0 +1,17 @@
+//! By default, `-l NAME` without an explicit kind will default to dylib. However, if there's also
+//! an `#[link(name = NAME, kind = KIND)]` attribute with an explicit `KIND`, it should override the
+//! CLI flag. In particular, this should not result in any duplicate flag warnings from the linker.
+
+//@ run-pass
+//@ compile-flags: -lrust_test_helpers
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern "C" {
+    pub fn rust_dbg_extern_identity_u32(x: u32) -> u32;
+}
+
+fn main() {
+    unsafe {
+        rust_dbg_extern_identity_u32(42);
+    }
+}
diff --git a/tests/ui/linking/weird-export-names.rs b/tests/ui/linking/weird-export-names.rs
new file mode 100644
index 00000000000..8fb2dc6bf5e
--- /dev/null
+++ b/tests/ui/linking/weird-export-names.rs
@@ -0,0 +1,10 @@
+//@ build-pass
+//@ needs-crate-type: cdylib
+
+#![crate_type = "cdylib"]
+
+#[export_name = "foo.0123"]
+pub extern "C" fn foo() {}
+
+#[export_name = "EXPORTS"]
+pub extern "C" fn bar() {}
diff --git a/tests/ui/lint/bare-trait-objects-path.stderr b/tests/ui/lint/bare-trait-objects-path.stderr
index d2d139dd025..fbb647c37c5 100644
--- a/tests/ui/lint/bare-trait-objects-path.stderr
+++ b/tests/ui/lint/bare-trait-objects-path.stderr
@@ -1,24 +1,4 @@
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/bare-trait-objects-path.rs:23:12
-   |
-LL |     let _: Dyn::Ty;
-   |            ^^^
-   |
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-   = note: `#[warn(bare_trait_objects)]` on by default
-help: if this is a dyn-compatible trait, use `dyn`
-   |
-LL |     let _: <dyn Dyn>::Ty;
-   |            ++++    +
-
-error[E0223]: ambiguous associated type
-  --> $DIR/bare-trait-objects-path.rs:23:12
-   |
-LL |     let _: Dyn::Ty;
-   |            ^^^^^^^ help: use fully-qualified syntax: `<dyn Dyn as Assoc>::Ty`
-
-warning: trait objects without an explicit `dyn` are deprecated
   --> $DIR/bare-trait-objects-path.rs:14:5
    |
 LL |     Dyn::func();
@@ -26,6 +6,7 @@ LL |     Dyn::func();
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `#[warn(bare_trait_objects)]` on by default
 help: if this is a dyn-compatible trait, use `dyn`
    |
 LL |     <dyn Dyn>::func();
@@ -57,6 +38,25 @@ help: if this is a dyn-compatible trait, use `dyn`
 LL |     <dyn Dyn>::CONST;
    |     ++++    +
 
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/bare-trait-objects-path.rs:23:12
+   |
+LL |     let _: Dyn::Ty;
+   |            ^^^
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: if this is a dyn-compatible trait, use `dyn`
+   |
+LL |     let _: <dyn Dyn>::Ty;
+   |            ++++    +
+
+error[E0223]: ambiguous associated type
+  --> $DIR/bare-trait-objects-path.rs:23:12
+   |
+LL |     let _: Dyn::Ty;
+   |            ^^^^^^^ help: use fully-qualified syntax: `<dyn Dyn as Assoc>::Ty`
+
 error: aborting due to 1 previous error; 4 warnings emitted
 
 For more information about this error, try `rustc --explain E0223`.
diff --git a/tests/ui/lint/expansion-time.rs b/tests/ui/lint/expansion-time.rs
index 3cb4b91ff2b..5ffb0c7881e 100644
--- a/tests/ui/lint/expansion-time.rs
+++ b/tests/ui/lint/expansion-time.rs
@@ -9,13 +9,6 @@ macro_rules! foo {
 macro_rules! m { ($i) => {} } //~ WARN missing fragment specifier
                               //~| WARN this was previously accepted
 
-#[warn(soft_unstable)]
-mod benches {
-    #[bench] //~ WARN use of unstable library feature `test`
-             //~| WARN this was previously accepted
-    fn foo() {}
-}
-
 #[deprecated = "reason"]
 macro_rules! deprecated {
     () => {}
diff --git a/tests/ui/lint/expansion-time.stderr b/tests/ui/lint/expansion-time.stderr
index f65627c2c08..f24d1b68a8d 100644
--- a/tests/ui/lint/expansion-time.stderr
+++ b/tests/ui/lint/expansion-time.stderr
@@ -26,20 +26,6 @@ note: the lint level is defined here
 LL | #[warn(missing_fragment_specifier)]
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable
-  --> $DIR/expansion-time.rs:14:7
-   |
-LL |     #[bench]
-   |       ^^^^^
-   |
-   = 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 #64266 <https://github.com/rust-lang/rust/issues/64266>
-note: the lint level is defined here
-  --> $DIR/expansion-time.rs:12:8
-   |
-LL | #[warn(soft_unstable)]
-   |        ^^^^^^^^^^^^^
-
 warning: include macro expected single expression in source
   --> $DIR/expansion-time-include.rs:4:1
    |
@@ -47,12 +33,12 @@ LL | 2
    | ^
    |
 note: the lint level is defined here
-  --> $DIR/expansion-time.rs:29:8
+  --> $DIR/expansion-time.rs:22:8
    |
 LL | #[warn(incomplete_include)]
    |        ^^^^^^^^^^^^^^^^^^
 
-warning: 4 warnings emitted
+warning: 3 warnings emitted
 
 Future incompatibility report: Future breakage diagnostic:
 warning: missing fragment specifier
@@ -69,18 +55,3 @@ note: the lint level is defined here
 LL | #[warn(missing_fragment_specifier)]
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Future breakage diagnostic:
-warning: use of unstable library feature `test`: `bench` is a part of custom test frameworks which are unstable
-  --> $DIR/expansion-time.rs:14:7
-   |
-LL |     #[bench]
-   |       ^^^^^
-   |
-   = 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 #64266 <https://github.com/rust-lang/rust/issues/64266>
-note: the lint level is defined here
-  --> $DIR/expansion-time.rs:12:8
-   |
-LL | #[warn(soft_unstable)]
-   |        ^^^^^^^^^^^^^
-
diff --git a/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs
new file mode 100644
index 00000000000..33a89ced963
--- /dev/null
+++ b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs
@@ -0,0 +1,10 @@
+#![forbid(for_loops_over_fallibles)]
+
+fn main() {
+    macro_rules! x {
+        () => {
+            None::<i32>
+        };
+    }
+    for _ in x! {} {} //~ ERROR for loop over an `Option`. This is more readably written as an `if let` statement [for_loops_over_fallibles]
+}
diff --git a/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr
new file mode 100644
index 00000000000..550d26045fb
--- /dev/null
+++ b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr
@@ -0,0 +1,24 @@
+error: for loop over an `Option`. This is more readably written as an `if let` statement
+  --> $DIR/macro-issue-140747.rs:9:14
+   |
+LL |     for _ in x! {} {}
+   |              ^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/macro-issue-140747.rs:1:11
+   |
+LL | #![forbid(for_loops_over_fallibles)]
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^
+help: to check pattern in a loop use `while let`
+   |
+LL -     for _ in x! {} {}
+LL +     while let Some(_) = x! {} {}
+   |
+help: consider using `if let` to clear intent
+   |
+LL -     for _ in x! {} {}
+LL +     if let Some(_) = x! {} {}
+   |
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/lint/unused_parens_json_suggestion.fixed b/tests/ui/lint/unused_parens_json_suggestion.fixed
index f26bedc3fd5..a26f292425c 100644
--- a/tests/ui/lint/unused_parens_json_suggestion.fixed
+++ b/tests/ui/lint/unused_parens_json_suggestion.fixed
@@ -1,5 +1,4 @@
 //@ compile-flags: --error-format json
-//@ error-pattern:unnecessary parentheses
 //@ run-rustfix
 
 // The output for humans should just highlight the whole span without showing
@@ -15,6 +14,7 @@ fn main() {
     // We want to suggest the properly-balanced expression `1 / (2 + 3)`, not
     // the malformed `1 / (2 + 3`
     let _a = 1 / (2 + 3);
+    //~^ ERROR unnecessary parentheses around assigned value
     f();
 }
 
diff --git a/tests/ui/lint/unused_parens_json_suggestion.rs b/tests/ui/lint/unused_parens_json_suggestion.rs
index af3d88f71bb..1ad85411fbf 100644
--- a/tests/ui/lint/unused_parens_json_suggestion.rs
+++ b/tests/ui/lint/unused_parens_json_suggestion.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: --error-format json
-//@ error-pattern:unnecessary parentheses
 //@ run-rustfix
 
 // The output for humans should just highlight the whole span without showing
@@ -15,6 +14,7 @@ fn main() {
     // We want to suggest the properly-balanced expression `1 / (2 + 3)`, not
     // the malformed `1 / (2 + 3`
     let _a = (1 / (2 + 3));
+    //~^ ERROR unnecessary parentheses around assigned value
     f();
 }
 
diff --git a/tests/ui/lint/unused_parens_json_suggestion.stderr b/tests/ui/lint/unused_parens_json_suggestion.stderr
index 2ce31817d29..9df3e918ac1 100644
--- a/tests/ui/lint/unused_parens_json_suggestion.stderr
+++ b/tests/ui/lint/unused_parens_json_suggestion.stderr
@@ -1,11 +1,11 @@
-{"$message_type":"diagnostic","message":"unnecessary parentheses around assigned value","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":636,"byte_end":637,"line_start":17,"line_end":17,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":648,"byte_end":649,"line_start":17,"line_end":17,"column_start":26,"column_end":27,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));","highlight_start":26,"highlight_end":27}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":439,"byte_end":452,"line_start":11,"line_end":11,"column_start":9,"column_end":22,"is_primary":true,"text":[{"text":"#![deny(unused_parens)]","highlight_start":9,"highlight_end":22}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":636,"byte_end":637,"line_start":17,"line_end":17,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":648,"byte_end":649,"line_start":17,"line_end":17,"column_start":26,"column_end":27,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));","highlight_start":26,"highlight_end":27}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around assigned value
-  --> $DIR/unused_parens_json_suggestion.rs:17:14
+{"$message_type":"diagnostic","message":"unnecessary parentheses around assigned value","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":594,"byte_end":595,"line_start":16,"line_end":16,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":606,"byte_end":607,"line_start":16,"line_end":16,"column_start":26,"column_end":27,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));","highlight_start":26,"highlight_end":27}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":397,"byte_end":410,"line_start":10,"line_end":10,"column_start":9,"column_end":22,"is_primary":true,"text":[{"text":"#![deny(unused_parens)]","highlight_start":9,"highlight_end":22}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":594,"byte_end":595,"line_start":16,"line_end":16,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":606,"byte_end":607,"line_start":16,"line_end":16,"column_start":26,"column_end":27,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));","highlight_start":26,"highlight_end":27}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around assigned value
+  --> $DIR/unused_parens_json_suggestion.rs:16:14
    |
 LL |     let _a = (1 / (2 + 3));
    |              ^           ^
    |
 note: the lint level is defined here
-  --> $DIR/unused_parens_json_suggestion.rs:11:9
+  --> $DIR/unused_parens_json_suggestion.rs:10:9
    |
 LL | #![deny(unused_parens)]
    |         ^^^^^^^^^^^^^
diff --git a/tests/ui/lint/unused_parens_remove_json_suggestion.fixed b/tests/ui/lint/unused_parens_remove_json_suggestion.fixed
index 899c24f83ed..4b08c3e51f6 100644
--- a/tests/ui/lint/unused_parens_remove_json_suggestion.fixed
+++ b/tests/ui/lint/unused_parens_remove_json_suggestion.fixed
@@ -1,5 +1,4 @@
 //@ compile-flags: --error-format json
-//@ error-pattern:unnecessary parentheses
 //@ run-rustfix
 
 // The output for humans should just highlight the whole span without showing
@@ -16,6 +15,7 @@ fn main() {
     let _b = false;
 
     if _b {
+    //~^ ERROR unnecessary parentheses around `if` condition
         println!("hello");
     }
 
@@ -27,28 +27,36 @@ fn f() -> bool {
     let c = false;
 
     if c {
+     //~^ ERROR unnecessary parentheses around `if` condition
         println!("next");
     }
 
     if c {
+     //~^ ERROR unnecessary parentheses around `if` condition
         println!("prev");
     }
 
     while false && true {
+    //~^ ERROR unnecessary parentheses around `while` condition
         if c {
+        //~^ ERROR unnecessary parentheses around `if` condition
             println!("norm");
         }
 
     }
 
     while true && false {
+    //~^ ERROR unnecessary parentheses around `while` condition
         for _ in 0 .. 3 {
+        //~^ ERROR unnecessary parentheses around `for` iterator expression
             println!("e~")
         }
     }
 
     for _ in 0 .. 3 {
+    //~^ ERROR unnecessary parentheses around `for` iterator expression
         while true && false {
+        //~^ ERROR unnecessary parentheses around `while` condition
             println!("e~")
         }
     }
diff --git a/tests/ui/lint/unused_parens_remove_json_suggestion.rs b/tests/ui/lint/unused_parens_remove_json_suggestion.rs
index 7f5d935c4ac..481e6a19d82 100644
--- a/tests/ui/lint/unused_parens_remove_json_suggestion.rs
+++ b/tests/ui/lint/unused_parens_remove_json_suggestion.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: --error-format json
-//@ error-pattern:unnecessary parentheses
 //@ run-rustfix
 
 // The output for humans should just highlight the whole span without showing
@@ -16,6 +15,7 @@ fn main() {
     let _b = false;
 
     if (_b) {
+    //~^ ERROR unnecessary parentheses around `if` condition
         println!("hello");
     }
 
@@ -27,28 +27,36 @@ fn f() -> bool {
     let c = false;
 
     if(c) {
+     //~^ ERROR unnecessary parentheses around `if` condition
         println!("next");
     }
 
     if (c){
+     //~^ ERROR unnecessary parentheses around `if` condition
         println!("prev");
     }
 
     while (false && true){
+    //~^ ERROR unnecessary parentheses around `while` condition
         if (c) {
+        //~^ ERROR unnecessary parentheses around `if` condition
             println!("norm");
         }
 
     }
 
     while(true && false) {
+    //~^ ERROR unnecessary parentheses around `while` condition
         for _ in (0 .. 3){
+        //~^ ERROR unnecessary parentheses around `for` iterator expression
             println!("e~")
         }
     }
 
     for _ in (0 .. 3) {
+    //~^ ERROR unnecessary parentheses around `for` iterator expression
         while (true && false) {
+        //~^ ERROR unnecessary parentheses around `while` condition
             println!("e~")
         }
     }
diff --git a/tests/ui/lint/unused_parens_remove_json_suggestion.stderr b/tests/ui/lint/unused_parens_remove_json_suggestion.stderr
index 975de4edfdf..1b28a4a2dc3 100644
--- a/tests/ui/lint/unused_parens_remove_json_suggestion.stderr
+++ b/tests/ui/lint/unused_parens_remove_json_suggestion.stderr
@@ -1,11 +1,11 @@
-{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":540,"byte_end":541,"line_start":18,"line_end":18,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (_b) {","highlight_start":8,"highlight_end":9}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":543,"byte_end":544,"line_start":18,"line_end":18,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    if (_b) {","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":439,"byte_end":452,"line_start":11,"line_end":11,"column_start":9,"column_end":22,"is_primary":true,"text":[{"text":"#![deny(unused_parens)]","highlight_start":9,"highlight_end":22}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":540,"byte_end":541,"line_start":18,"line_end":18,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (_b) {","highlight_start":8,"highlight_end":9}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":543,"byte_end":544,"line_start":18,"line_end":18,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    if (_b) {","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `if` condition
-  --> $DIR/unused_parens_remove_json_suggestion.rs:18:8
+{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":498,"byte_end":499,"line_start":17,"line_end":17,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (_b) {","highlight_start":8,"highlight_end":9}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":501,"byte_end":502,"line_start":17,"line_end":17,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    if (_b) {","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":397,"byte_end":410,"line_start":10,"line_end":10,"column_start":9,"column_end":22,"is_primary":true,"text":[{"text":"#![deny(unused_parens)]","highlight_start":9,"highlight_end":22}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":498,"byte_end":499,"line_start":17,"line_end":17,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (_b) {","highlight_start":8,"highlight_end":9}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":501,"byte_end":502,"line_start":17,"line_end":17,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    if (_b) {","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `if` condition
+  --> $DIR/unused_parens_remove_json_suggestion.rs:17:8
    |
 LL |     if (_b) {
    |        ^  ^
    |
 note: the lint level is defined here
-  --> $DIR/unused_parens_remove_json_suggestion.rs:11:9
+  --> $DIR/unused_parens_remove_json_suggestion.rs:10:9
    |
 LL | #![deny(unused_parens)]
    |         ^^^^^^^^^^^^^
@@ -16,7 +16,7 @@ LL +     if _b {
    |
 
 "}
-{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":637,"byte_end":638,"line_start":29,"line_end":29,"column_start":7,"column_end":8,"is_primary":true,"text":[{"text":"    if(c) {","highlight_start":7,"highlight_end":8}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":639,"byte_end":640,"line_start":29,"line_end":29,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":"    if(c) {","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":637,"byte_end":638,"line_start":29,"line_end":29,"column_start":7,"column_end":8,"is_primary":true,"text":[{"text":"    if(c) {","highlight_start":7,"highlight_end":8}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":639,"byte_end":640,"line_start":29,"line_end":29,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":"    if(c) {","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `if` condition
+{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":656,"byte_end":657,"line_start":29,"line_end":29,"column_start":7,"column_end":8,"is_primary":true,"text":[{"text":"    if(c) {","highlight_start":7,"highlight_end":8}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":658,"byte_end":659,"line_start":29,"line_end":29,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":"    if(c) {","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":656,"byte_end":657,"line_start":29,"line_end":29,"column_start":7,"column_end":8,"is_primary":true,"text":[{"text":"    if(c) {","highlight_start":7,"highlight_end":8}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":658,"byte_end":659,"line_start":29,"line_end":29,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":"    if(c) {","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `if` condition
   --> $DIR/unused_parens_remove_json_suggestion.rs:29:7
    |
 LL |     if(c) {
@@ -29,8 +29,8 @@ LL +     if c {
    |
 
 "}
-{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":683,"byte_end":684,"line_start":33,"line_end":33,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (c){","highlight_start":8,"highlight_end":9}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":685,"byte_end":686,"line_start":33,"line_end":33,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":"    if (c){","highlight_start":10,"highlight_end":11}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":683,"byte_end":684,"line_start":33,"line_end":33,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (c){","highlight_start":8,"highlight_end":9}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":685,"byte_end":686,"line_start":33,"line_end":33,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":"    if (c){","highlight_start":10,"highlight_end":11}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `if` condition
-  --> $DIR/unused_parens_remove_json_suggestion.rs:33:8
+{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":764,"byte_end":765,"line_start":34,"line_end":34,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (c){","highlight_start":8,"highlight_end":9}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":766,"byte_end":767,"line_start":34,"line_end":34,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":"    if (c){","highlight_start":10,"highlight_end":11}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":764,"byte_end":765,"line_start":34,"line_end":34,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (c){","highlight_start":8,"highlight_end":9}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":766,"byte_end":767,"line_start":34,"line_end":34,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":"    if (c){","highlight_start":10,"highlight_end":11}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `if` condition
+  --> $DIR/unused_parens_remove_json_suggestion.rs:34:8
    |
 LL |     if (c){
    |        ^ ^
@@ -42,8 +42,8 @@ LL +     if c {
    |
 
 "}
-{"$message_type":"diagnostic","message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":731,"byte_end":732,"line_start":37,"line_end":37,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":745,"byte_end":746,"line_start":37,"line_end":37,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":731,"byte_end":732,"line_start":37,"line_end":37,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":745,"byte_end":746,"line_start":37,"line_end":37,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition
-  --> $DIR/unused_parens_remove_json_suggestion.rs:37:11
+{"$message_type":"diagnostic","message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":874,"byte_end":875,"line_start":39,"line_end":39,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":888,"byte_end":889,"line_start":39,"line_end":39,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":874,"byte_end":875,"line_start":39,"line_end":39,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":888,"byte_end":889,"line_start":39,"line_end":39,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition
+  --> $DIR/unused_parens_remove_json_suggestion.rs:39:11
    |
 LL |     while (false && true){
    |           ^             ^
@@ -55,8 +55,8 @@ LL +     while false && true {
    |
 
 "}
-{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":759,"byte_end":760,"line_start":38,"line_end":38,"column_start":12,"column_end":13,"is_primary":true,"text":[{"text":"        if (c) {","highlight_start":12,"highlight_end":13}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":761,"byte_end":762,"line_start":38,"line_end":38,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"        if (c) {","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":759,"byte_end":760,"line_start":38,"line_end":38,"column_start":12,"column_end":13,"is_primary":true,"text":[{"text":"        if (c) {","highlight_start":12,"highlight_end":13}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":761,"byte_end":762,"line_start":38,"line_end":38,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"        if (c) {","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `if` condition
-  --> $DIR/unused_parens_remove_json_suggestion.rs:38:12
+{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":966,"byte_end":967,"line_start":41,"line_end":41,"column_start":12,"column_end":13,"is_primary":true,"text":[{"text":"        if (c) {","highlight_start":12,"highlight_end":13}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":968,"byte_end":969,"line_start":41,"line_end":41,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"        if (c) {","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":966,"byte_end":967,"line_start":41,"line_end":41,"column_start":12,"column_end":13,"is_primary":true,"text":[{"text":"        if (c) {","highlight_start":12,"highlight_end":13}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":968,"byte_end":969,"line_start":41,"line_end":41,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"        if (c) {","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `if` condition
+  --> $DIR/unused_parens_remove_json_suggestion.rs:41:12
    |
 LL |         if (c) {
    |            ^ ^
@@ -68,8 +68,8 @@ LL +         if c {
    |
 
 "}
-{"$message_type":"diagnostic","message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":822,"byte_end":823,"line_start":44,"line_end":44,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":"    while(true && false) {","highlight_start":10,"highlight_end":11}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":836,"byte_end":837,"line_start":44,"line_end":44,"column_start":24,"column_end":25,"is_primary":true,"text":[{"text":"    while(true && false) {","highlight_start":24,"highlight_end":25}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":822,"byte_end":823,"line_start":44,"line_end":44,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":"    while(true && false) {","highlight_start":10,"highlight_end":11}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":836,"byte_end":837,"line_start":44,"line_end":44,"column_start":24,"column_end":25,"is_primary":true,"text":[{"text":"    while(true && false) {","highlight_start":24,"highlight_end":25}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition
-  --> $DIR/unused_parens_remove_json_suggestion.rs:44:10
+{"$message_type":"diagnostic","message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1094,"byte_end":1095,"line_start":48,"line_end":48,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":"    while(true && false) {","highlight_start":10,"highlight_end":11}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1108,"byte_end":1109,"line_start":48,"line_end":48,"column_start":24,"column_end":25,"is_primary":true,"text":[{"text":"    while(true && false) {","highlight_start":24,"highlight_end":25}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1094,"byte_end":1095,"line_start":48,"line_end":48,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":"    while(true && false) {","highlight_start":10,"highlight_end":11}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1108,"byte_end":1109,"line_start":48,"line_end":48,"column_start":24,"column_end":25,"is_primary":true,"text":[{"text":"    while(true && false) {","highlight_start":24,"highlight_end":25}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition
+  --> $DIR/unused_parens_remove_json_suggestion.rs:48:10
    |
 LL |     while(true && false) {
    |          ^             ^
@@ -81,8 +81,8 @@ LL +     while true && false {
    |
 
 "}
-{"$message_type":"diagnostic","message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":857,"byte_end":858,"line_start":45,"line_end":45,"column_start":18,"column_end":19,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){","highlight_start":18,"highlight_end":19}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":864,"byte_end":865,"line_start":45,"line_end":45,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":857,"byte_end":858,"line_start":45,"line_end":45,"column_start":18,"column_end":19,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){","highlight_start":18,"highlight_end":19}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":864,"byte_end":865,"line_start":45,"line_end":45,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `for` iterator expression
-  --> $DIR/unused_parens_remove_json_suggestion.rs:45:18
+{"$message_type":"diagnostic","message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1193,"byte_end":1194,"line_start":50,"line_end":50,"column_start":18,"column_end":19,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){","highlight_start":18,"highlight_end":19}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1200,"byte_end":1201,"line_start":50,"line_end":50,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1193,"byte_end":1194,"line_start":50,"line_end":50,"column_start":18,"column_end":19,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){","highlight_start":18,"highlight_end":19}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1200,"byte_end":1201,"line_start":50,"line_end":50,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `for` iterator expression
+  --> $DIR/unused_parens_remove_json_suggestion.rs:50:18
    |
 LL |         for _ in (0 .. 3){
    |                  ^      ^
@@ -94,8 +94,8 @@ LL +         for _ in 0 .. 3 {
    |
 
 "}
-{"$message_type":"diagnostic","message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":924,"byte_end":925,"line_start":50,"line_end":50,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":931,"byte_end":932,"line_start":50,"line_end":50,"column_start":21,"column_end":22,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {","highlight_start":21,"highlight_end":22}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":924,"byte_end":925,"line_start":50,"line_end":50,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":931,"byte_end":932,"line_start":50,"line_end":50,"column_start":21,"column_end":22,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {","highlight_start":21,"highlight_end":22}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `for` iterator expression
-  --> $DIR/unused_parens_remove_json_suggestion.rs:50:14
+{"$message_type":"diagnostic","message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1336,"byte_end":1337,"line_start":56,"line_end":56,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1343,"byte_end":1344,"line_start":56,"line_end":56,"column_start":21,"column_end":22,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {","highlight_start":21,"highlight_end":22}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1336,"byte_end":1337,"line_start":56,"line_end":56,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1343,"byte_end":1344,"line_start":56,"line_end":56,"column_start":21,"column_end":22,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {","highlight_start":21,"highlight_end":22}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `for` iterator expression
+  --> $DIR/unused_parens_remove_json_suggestion.rs:56:14
    |
 LL |     for _ in (0 .. 3) {
    |              ^      ^
@@ -107,8 +107,8 @@ LL +     for _ in 0 .. 3 {
    |
 
 "}
-{"$message_type":"diagnostic","message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":949,"byte_end":950,"line_start":51,"line_end":51,"column_start":15,"column_end":16,"is_primary":true,"text":[{"text":"        while (true && false) {","highlight_start":15,"highlight_end":16}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":963,"byte_end":964,"line_start":51,"line_end":51,"column_start":29,"column_end":30,"is_primary":true,"text":[{"text":"        while (true && false) {","highlight_start":29,"highlight_end":30}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":949,"byte_end":950,"line_start":51,"line_end":51,"column_start":15,"column_end":16,"is_primary":true,"text":[{"text":"        while (true && false) {","highlight_start":15,"highlight_end":16}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":963,"byte_end":964,"line_start":51,"line_end":51,"column_start":29,"column_end":30,"is_primary":true,"text":[{"text":"        while (true && false) {","highlight_start":29,"highlight_end":30}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition
-  --> $DIR/unused_parens_remove_json_suggestion.rs:51:15
+{"$message_type":"diagnostic","message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1433,"byte_end":1434,"line_start":58,"line_end":58,"column_start":15,"column_end":16,"is_primary":true,"text":[{"text":"        while (true && false) {","highlight_start":15,"highlight_end":16}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1447,"byte_end":1448,"line_start":58,"line_end":58,"column_start":29,"column_end":30,"is_primary":true,"text":[{"text":"        while (true && false) {","highlight_start":29,"highlight_end":30}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1433,"byte_end":1434,"line_start":58,"line_end":58,"column_start":15,"column_end":16,"is_primary":true,"text":[{"text":"        while (true && false) {","highlight_start":15,"highlight_end":16}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1447,"byte_end":1448,"line_start":58,"line_end":58,"column_start":29,"column_end":30,"is_primary":true,"text":[{"text":"        while (true && false) {","highlight_start":29,"highlight_end":30}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition
+  --> $DIR/unused_parens_remove_json_suggestion.rs:58:15
    |
 LL |         while (true && false) {
    |               ^             ^
diff --git a/tests/ui/auxiliary/fancy-panic.rs b/tests/ui/macros/auxiliary/fancy-panic.rs
index 35be93b0590..35be93b0590 100644
--- a/tests/ui/auxiliary/fancy-panic.rs
+++ b/tests/ui/macros/auxiliary/fancy-panic.rs
diff --git a/tests/ui/macros/auxiliary/return_from_external_macro.rs b/tests/ui/macros/auxiliary/return_from_external_macro.rs
new file mode 100644
index 00000000000..df59d8bdcb0
--- /dev/null
+++ b/tests/ui/macros/auxiliary/return_from_external_macro.rs
@@ -0,0 +1,11 @@
+#![feature(super_let)]
+
+#[macro_export]
+macro_rules! foo {
+    () => {
+        {
+            super let args = 1;
+            &args
+        }
+    };
+}
diff --git a/tests/ui/non-fmt-panic.fixed b/tests/ui/macros/non-fmt-panic.fixed
index fa9a1ad89bd..b102dba1731 100644
--- a/tests/ui/non-fmt-panic.fixed
+++ b/tests/ui/macros/non-fmt-panic.fixed
@@ -1,3 +1,9 @@
+//! The non_fmt_panics lint detects panic!(..) invocations where
+//! the first argument is not a formatting string.
+//!
+//! Also, this test checks that this is not emitted if it originates
+//! in an external macro.
+
 //@ run-rustfix
 //@ rustfix-only-machine-applicable
 //@ build-pass (FIXME(62277): should be check-pass)
diff --git a/tests/ui/non-fmt-panic.rs b/tests/ui/macros/non-fmt-panic.rs
index 451a0c76018..9277529c6d4 100644
--- a/tests/ui/non-fmt-panic.rs
+++ b/tests/ui/macros/non-fmt-panic.rs
@@ -1,3 +1,9 @@
+//! The non_fmt_panics lint detects panic!(..) invocations where
+//! the first argument is not a formatting string.
+//!
+//! Also, this test checks that this is not emitted if it originates
+//! in an external macro.
+
 //@ run-rustfix
 //@ rustfix-only-machine-applicable
 //@ build-pass (FIXME(62277): should be check-pass)
diff --git a/tests/ui/non-fmt-panic.stderr b/tests/ui/macros/non-fmt-panic.stderr
index 0134a8ddf29..30b63cb46e2 100644
--- a/tests/ui/non-fmt-panic.stderr
+++ b/tests/ui/macros/non-fmt-panic.stderr
@@ -1,5 +1,5 @@
 warning: panic message contains a brace
-  --> $DIR/non-fmt-panic.rs:13:29
+  --> $DIR/non-fmt-panic.rs:19:29
    |
 LL |     panic!("here's a brace: {");
    |                             ^
@@ -12,7 +12,7 @@ LL |     panic!("{}", "here's a brace: {");
    |            +++++
 
 warning: panic message contains a brace
-  --> $DIR/non-fmt-panic.rs:14:35
+  --> $DIR/non-fmt-panic.rs:20:35
    |
 LL |     unreachable!("here's a brace: {");
    |                                   ^
@@ -24,7 +24,7 @@ LL |     unreachable!("{}", "here's a brace: {");
    |                  +++++
 
 warning: panic message contains a brace
-  --> $DIR/non-fmt-panic.rs:15:31
+  --> $DIR/non-fmt-panic.rs:21:31
    |
 LL |     std::panic!("another one: }");
    |                               ^
@@ -36,7 +36,7 @@ LL |     std::panic!("{}", "another one: }");
    |                 +++++
 
 warning: panic message contains an unused formatting placeholder
-  --> $DIR/non-fmt-panic.rs:16:25
+  --> $DIR/non-fmt-panic.rs:22:25
    |
 LL |     core::panic!("Hello {}");
    |                         ^^
@@ -52,7 +52,7 @@ LL |     core::panic!("{}", "Hello {}");
    |                  +++++
 
 warning: panic message contains unused formatting placeholders
-  --> $DIR/non-fmt-panic.rs:17:21
+  --> $DIR/non-fmt-panic.rs:23:21
    |
 LL |     assert!(false, "{:03x} {test} bla");
    |                     ^^^^^^ ^^^^^^
@@ -68,7 +68,7 @@ LL |     assert!(false, "{}", "{:03x} {test} bla");
    |                    +++++
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:19:20
+  --> $DIR/non-fmt-panic.rs:25:20
    |
 LL |     assert!(false, S);
    |                    ^
@@ -81,7 +81,7 @@ LL |     assert!(false, "{}", S);
    |                    +++++
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:21:20
+  --> $DIR/non-fmt-panic.rs:27:20
    |
 LL |     assert!(false, 123);
    |                    ^^^
@@ -94,7 +94,7 @@ LL |     assert!(false, "{}", 123);
    |                    +++++
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:23:20
+  --> $DIR/non-fmt-panic.rs:29:20
    |
 LL |     assert!(false, Some(123));
    |                    ^^^^^^^^^
@@ -107,7 +107,7 @@ LL |     assert!(false, "{:?}", Some(123));
    |                    +++++++
 
 warning: panic message contains braces
-  --> $DIR/non-fmt-panic.rs:25:27
+  --> $DIR/non-fmt-panic.rs:31:27
    |
 LL |     debug_assert!(false, "{{}} bla");
    |                           ^^^^
@@ -119,7 +119,7 @@ LL |     debug_assert!(false, "{}", "{{}} bla");
    |                          +++++
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:26:12
+  --> $DIR/non-fmt-panic.rs:32:12
    |
 LL |     panic!(C);
    |            ^
@@ -132,7 +132,7 @@ LL |     panic!("{}", C);
    |            +++++
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:27:12
+  --> $DIR/non-fmt-panic.rs:33:12
    |
 LL |     panic!(S);
    |            ^
@@ -145,7 +145,7 @@ LL |     panic!("{}", S);
    |            +++++
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:28:18
+  --> $DIR/non-fmt-panic.rs:34:18
    |
 LL |     unreachable!(S);
    |                  ^
@@ -158,7 +158,7 @@ LL |     unreachable!("{}", S);
    |                  +++++
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:29:18
+  --> $DIR/non-fmt-panic.rs:35:18
    |
 LL |     unreachable!(S);
    |                  ^
@@ -171,7 +171,7 @@ LL |     unreachable!("{}", S);
    |                  +++++
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:30:17
+  --> $DIR/non-fmt-panic.rs:36:17
    |
 LL |     std::panic!(123);
    |                 ^^^
@@ -189,7 +189,7 @@ LL +     std::panic::panic_any(123);
    |
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:31:18
+  --> $DIR/non-fmt-panic.rs:37:18
    |
 LL |     core::panic!(&*"abc");
    |                  ^^^^^^^
@@ -202,7 +202,7 @@ LL |     core::panic!("{}", &*"abc");
    |                  +++++
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:32:12
+  --> $DIR/non-fmt-panic.rs:38:12
    |
 LL |     panic!(Some(123));
    |            ^^^^^^^^^
@@ -220,7 +220,7 @@ LL +     std::panic::panic_any(Some(123));
    |
 
 warning: panic message contains an unused formatting placeholder
-  --> $DIR/non-fmt-panic.rs:33:12
+  --> $DIR/non-fmt-panic.rs:39:12
    |
 LL |     panic!(concat!("{", "}"));
    |            ^^^^^^^^^^^^^^^^^
@@ -236,7 +236,7 @@ LL |     panic!("{}", concat!("{", "}"));
    |            +++++
 
 warning: panic message contains braces
-  --> $DIR/non-fmt-panic.rs:34:5
+  --> $DIR/non-fmt-panic.rs:40:5
    |
 LL |     panic!(concat!("{", "{"));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -248,7 +248,7 @@ LL |     panic!("{}", concat!("{", "{"));
    |            +++++
 
 warning: panic message contains an unused formatting placeholder
-  --> $DIR/non-fmt-panic.rs:36:37
+  --> $DIR/non-fmt-panic.rs:42:37
    |
 LL |     fancy_panic::fancy_panic!("test {} 123");
    |                                     ^^
@@ -256,7 +256,7 @@ LL |     fancy_panic::fancy_panic!("test {} 123");
    = note: this message is not used as a format string when given without arguments, but will be in Rust 2021
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:46:12
+  --> $DIR/non-fmt-panic.rs:52:12
    |
 LL |     panic!(a!());
    |            ^^^^
@@ -274,7 +274,7 @@ LL +     std::panic::panic_any(a!());
    |
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:47:18
+  --> $DIR/non-fmt-panic.rs:53:18
    |
 LL |     unreachable!(a!());
    |                  ^^^^
@@ -287,7 +287,7 @@ LL |     unreachable!("{}", a!());
    |                  +++++
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:49:12
+  --> $DIR/non-fmt-panic.rs:55:12
    |
 LL |     panic!(format!("{}", 1));
    |            ^^^^^^^^^^^^^^^^
@@ -302,7 +302,7 @@ LL +     panic!("{}", 1);
    |
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:50:18
+  --> $DIR/non-fmt-panic.rs:56:18
    |
 LL |     unreachable!(format!("{}", 1));
    |                  ^^^^^^^^^^^^^^^^
@@ -317,7 +317,7 @@ LL +     unreachable!("{}", 1);
    |
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:51:20
+  --> $DIR/non-fmt-panic.rs:57:20
    |
 LL |     assert!(false, format!("{}", 1));
    |                    ^^^^^^^^^^^^^^^^
@@ -332,7 +332,7 @@ LL +     assert!(false, "{}", 1);
    |
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:52:26
+  --> $DIR/non-fmt-panic.rs:58:26
    |
 LL |     debug_assert!(false, format!("{}", 1));
    |                          ^^^^^^^^^^^^^^^^
@@ -347,7 +347,7 @@ LL +     debug_assert!(false, "{}", 1);
    |
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:54:12
+  --> $DIR/non-fmt-panic.rs:60:12
    |
 LL |     panic![123];
    |            ^^^
@@ -365,7 +365,7 @@ LL +     std::panic::panic_any(123);
    |
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:55:12
+  --> $DIR/non-fmt-panic.rs:61:12
    |
 LL |     panic!{123};
    |            ^^^
@@ -383,7 +383,7 @@ LL +     std::panic::panic_any(123);
    |
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:72:12
+  --> $DIR/non-fmt-panic.rs:78:12
    |
 LL |     panic!(v);
    |     ------ ^
@@ -394,7 +394,7 @@ LL |     panic!(v);
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:73:20
+  --> $DIR/non-fmt-panic.rs:79:20
    |
 LL |     assert!(false, v);
    |                    ^
@@ -403,7 +403,7 @@ LL |     assert!(false, v);
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:77:12
+  --> $DIR/non-fmt-panic.rs:83:12
    |
 LL |     panic!(v);
    |            ^
@@ -421,7 +421,7 @@ LL +     std::panic::panic_any(v);
    |
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:78:20
+  --> $DIR/non-fmt-panic.rs:84:20
    |
 LL |     assert!(false, v);
    |                    ^
@@ -434,7 +434,7 @@ LL |     assert!(false, "{:?}", v);
    |                    +++++++
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:82:12
+  --> $DIR/non-fmt-panic.rs:88:12
    |
 LL |     panic!(v);
    |            ^
@@ -452,7 +452,7 @@ LL +     std::panic::panic_any(v);
    |
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:83:20
+  --> $DIR/non-fmt-panic.rs:89:20
    |
 LL |     assert!(false, v);
    |                    ^
@@ -465,7 +465,7 @@ LL |     assert!(false, "{}", v);
    |                    +++++
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:87:12
+  --> $DIR/non-fmt-panic.rs:93:12
    |
 LL |     panic!(v);
    |            ^
@@ -483,7 +483,7 @@ LL +     std::panic::panic_any(v);
    |
 
 warning: panic message is not a string literal
-  --> $DIR/non-fmt-panic.rs:88:20
+  --> $DIR/non-fmt-panic.rs:94:20
    |
 LL |     assert!(false, v);
    |                    ^
diff --git a/tests/ui/macros/return_from_external_macro.rs b/tests/ui/macros/return_from_external_macro.rs
new file mode 100644
index 00000000000..43fe99e63ad
--- /dev/null
+++ b/tests/ui/macros/return_from_external_macro.rs
@@ -0,0 +1,17 @@
+//@ aux-crate: ret_from_ext=return_from_external_macro.rs
+
+#![feature(super_let)]
+extern crate ret_from_ext;
+
+fn foo() -> impl Sized {
+    drop(|| ret_from_ext::foo!());
+    //~^ ERROR cannot return reference to local binding
+
+    ret_from_ext::foo!()
+    //~^ ERROR temporary value dropped while borrowed
+}
+//~^ NOTE temporary value is freed at the end of this statement
+
+fn main() {
+    foo();
+}
diff --git a/tests/ui/macros/return_from_external_macro.stderr b/tests/ui/macros/return_from_external_macro.stderr
new file mode 100644
index 00000000000..b6010b8ec79
--- /dev/null
+++ b/tests/ui/macros/return_from_external_macro.stderr
@@ -0,0 +1,29 @@
+error[E0515]: cannot return reference to local binding
+  --> $DIR/return_from_external_macro.rs:7:13
+   |
+LL |     drop(|| ret_from_ext::foo!());
+   |             ^^^^^^^^^^^^^^^^^^^^
+   |             |
+   |             returns a reference to data owned by the current function
+   |             local binding introduced here
+   |
+   = note: this error originates in the macro `ret_from_ext::foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/return_from_external_macro.rs:10:5
+   |
+LL |     ret_from_ext::foo!()
+   |     ^^^^^^^^^^^^^^^^^^^^
+   |     |
+   |     creates a temporary value which is freed while still in use
+   |     opaque type requires that borrow lasts for `'static`
+LL |
+LL | }
+   | - temporary value is freed at the end of this statement
+   |
+   = note: this error originates in the macro `ret_from_ext::foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0515, E0716.
+For more information about an error, try `rustc --explain E0515`.
diff --git a/tests/ui/methods/disambiguate-multiple-blanket-impl.stderr b/tests/ui/methods/disambiguate-multiple-blanket-impl.stderr
index 1b81dc5aafb..ee698ed0e75 100644
--- a/tests/ui/methods/disambiguate-multiple-blanket-impl.stderr
+++ b/tests/ui/methods/disambiguate-multiple-blanket-impl.stderr
@@ -1,18 +1,3 @@
-error[E0223]: ambiguous associated type
-  --> $DIR/disambiguate-multiple-blanket-impl.rs:36:12
-   |
-LL |     let _: S::Type;
-   |            ^^^^^^^
-   |
-help: use fully-qualified syntax
-   |
-LL -     let _: S::Type;
-LL +     let _: <S as A>::Type;
-   |
-LL -     let _: S::Type;
-LL +     let _: <S as B>::Type;
-   |
-
 error[E0034]: multiple applicable items in scope
   --> $DIR/disambiguate-multiple-blanket-impl.rs:30:8
    |
@@ -63,6 +48,21 @@ LL -     S::CONST;
 LL +     <S as B>::CONST;
    |
 
+error[E0223]: ambiguous associated type
+  --> $DIR/disambiguate-multiple-blanket-impl.rs:36:12
+   |
+LL |     let _: S::Type;
+   |            ^^^^^^^
+   |
+help: use fully-qualified syntax
+   |
+LL -     let _: S::Type;
+LL +     let _: <S as A>::Type;
+   |
+LL -     let _: S::Type;
+LL +     let _: <S as B>::Type;
+   |
+
 error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0034, E0223.
diff --git a/tests/ui/methods/disambiguate-multiple-impl.stderr b/tests/ui/methods/disambiguate-multiple-impl.stderr
index 2563c2327b7..319d5886f8e 100644
--- a/tests/ui/methods/disambiguate-multiple-impl.stderr
+++ b/tests/ui/methods/disambiguate-multiple-impl.stderr
@@ -1,18 +1,3 @@
-error[E0223]: ambiguous associated type
-  --> $DIR/disambiguate-multiple-impl.rs:32:12
-   |
-LL |     let _: S::Type = ();
-   |            ^^^^^^^
-   |
-help: use fully-qualified syntax
-   |
-LL -     let _: S::Type = ();
-LL +     let _: <S as A>::Type = ();
-   |
-LL -     let _: S::Type = ();
-LL +     let _: <S as B>::Type = ();
-   |
-
 error[E0034]: multiple applicable items in scope
   --> $DIR/disambiguate-multiple-impl.rs:29:8
    |
@@ -38,6 +23,21 @@ LL -     S::foo(&s);
 LL +     B::foo(&s);
    |
 
+error[E0223]: ambiguous associated type
+  --> $DIR/disambiguate-multiple-impl.rs:32:12
+   |
+LL |     let _: S::Type = ();
+   |            ^^^^^^^
+   |
+help: use fully-qualified syntax
+   |
+LL -     let _: S::Type = ();
+LL +     let _: <S as A>::Type = ();
+   |
+LL -     let _: S::Type = ();
+LL +     let _: <S as B>::Type = ();
+   |
+
 error[E0034]: multiple applicable items in scope
   --> $DIR/disambiguate-multiple-impl.rs:34:16
    |
diff --git a/tests/ui/methods/disambiguate-multiple-trait-2.stderr b/tests/ui/methods/disambiguate-multiple-trait-2.stderr
index 08e264c20c8..f9119e60750 100644
--- a/tests/ui/methods/disambiguate-multiple-trait-2.stderr
+++ b/tests/ui/methods/disambiguate-multiple-trait-2.stderr
@@ -1,26 +1,3 @@
-error[E0221]: ambiguous associated type `Type` in bounds of `T`
-  --> $DIR/disambiguate-multiple-trait-2.rs:23:12
-   |
-LL |     type Type;
-   |     --------- ambiguous `Type` from `A`
-...
-LL |     type Type;
-   |     --------- ambiguous `Type` from `B`
-...
-LL |     let _: T::Type;
-   |            ^^^^^^^ ambiguous associated type `Type`
-   |
-help: use fully-qualified syntax to disambiguate
-   |
-LL -     let _: T::Type;
-LL +     let _: <T as A>::Type;
-   |
-help: use fully-qualified syntax to disambiguate
-   |
-LL -     let _: T::Type;
-LL +     let _: <T as B>::Type;
-   |
-
 error[E0034]: multiple applicable items in scope
   --> $DIR/disambiguate-multiple-trait-2.rs:16:7
    |
@@ -73,19 +50,27 @@ LL -     let _ = T::CONST;
 LL +     let _ = <T as B>::CONST;
    |
 
-error[E0223]: ambiguous associated type
-  --> $DIR/disambiguate-multiple-trait-2.rs:52:12
+error[E0221]: ambiguous associated type `Type` in bounds of `T`
+  --> $DIR/disambiguate-multiple-trait-2.rs:23:12
    |
-LL |     let _: S::Type;
-   |            ^^^^^^^
+LL |     type Type;
+   |     --------- ambiguous `Type` from `A`
+...
+LL |     type Type;
+   |     --------- ambiguous `Type` from `B`
+...
+LL |     let _: T::Type;
+   |            ^^^^^^^ ambiguous associated type `Type`
    |
-help: use fully-qualified syntax
+help: use fully-qualified syntax to disambiguate
    |
-LL -     let _: S::Type;
-LL +     let _: <S as A>::Type;
+LL -     let _: T::Type;
+LL +     let _: <T as A>::Type;
    |
-LL -     let _: S::Type;
-LL +     let _: <S as B>::Type;
+help: use fully-qualified syntax to disambiguate
+   |
+LL -     let _: T::Type;
+LL +     let _: <T as B>::Type;
    |
 
 error[E0034]: multiple applicable items in scope
@@ -138,6 +123,21 @@ LL -     let _ = S::CONST;
 LL +     let _ = <S as B>::CONST;
    |
 
+error[E0223]: ambiguous associated type
+  --> $DIR/disambiguate-multiple-trait-2.rs:52:12
+   |
+LL |     let _: S::Type;
+   |            ^^^^^^^
+   |
+help: use fully-qualified syntax
+   |
+LL -     let _: S::Type;
+LL +     let _: <S as A>::Type;
+   |
+LL -     let _: S::Type;
+LL +     let _: <S as B>::Type;
+   |
+
 error: aborting due to 6 previous errors
 
 Some errors have detailed explanations: E0034, E0221, E0223.
diff --git a/tests/ui/methods/disambiguate-multiple-trait.stderr b/tests/ui/methods/disambiguate-multiple-trait.stderr
index a977fe2cd03..f35eec3b048 100644
--- a/tests/ui/methods/disambiguate-multiple-trait.stderr
+++ b/tests/ui/methods/disambiguate-multiple-trait.stderr
@@ -1,18 +1,3 @@
-error[E0223]: ambiguous associated type
-  --> $DIR/disambiguate-multiple-trait.rs:30:12
-   |
-LL |     let _: S::Type;
-   |            ^^^^^^^
-   |
-help: use fully-qualified syntax
-   |
-LL -     let _: S::Type;
-LL +     let _: <S as A>::Type;
-   |
-LL -     let _: S::Type;
-LL +     let _: <S as B>::Type;
-   |
-
 error[E0034]: multiple applicable items in scope
   --> $DIR/disambiguate-multiple-trait.rs:24:8
    |
@@ -63,6 +48,21 @@ LL -     let _ = S::CONST;
 LL +     let _ = <S as B>::CONST;
    |
 
+error[E0223]: ambiguous associated type
+  --> $DIR/disambiguate-multiple-trait.rs:30:12
+   |
+LL |     let _: S::Type;
+   |            ^^^^^^^
+   |
+help: use fully-qualified syntax
+   |
+LL -     let _: S::Type;
+LL +     let _: <S as A>::Type;
+   |
+LL -     let _: S::Type;
+LL +     let _: <S as B>::Type;
+   |
+
 error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0034, E0223.
diff --git a/tests/ui/mir/lint/assignment-overlap.rs b/tests/ui/mir/lint/assignment-overlap.rs
index 950279b1555..bbc14090467 100644
--- a/tests/ui/mir/lint/assignment-overlap.rs
+++ b/tests/ui/mir/lint/assignment-overlap.rs
@@ -2,7 +2,7 @@
 //@ build-fail
 //@ failure-status: 101
 //@ dont-check-compiler-stderr
-//@ error-pattern: encountered `Assign` statement with overlapping memory
+
 #![feature(custom_mir, core_intrinsics)]
 extern crate core;
 use core::intrinsics::mir::*;
@@ -13,6 +13,7 @@ pub fn main() {
         let a: [u8; 1024];
         {
             a = a; //~ ERROR broken MIR
+                   //~^ ERROR encountered `Assign` statement with overlapping memory
             Return()
         }
     }
diff --git a/tests/ui/mir/lint/call-overlap.rs b/tests/ui/mir/lint/call-overlap.rs
index 3c42e04e3ec..f43edfb8738 100644
--- a/tests/ui/mir/lint/call-overlap.rs
+++ b/tests/ui/mir/lint/call-overlap.rs
@@ -2,7 +2,7 @@
 //@ build-fail
 //@ failure-status: 101
 //@ dont-check-compiler-stderr
-//@ error-pattern: encountered overlapping memory in `Move` arguments to `Call`
+
 #![feature(custom_mir, core_intrinsics)]
 extern crate core;
 use core::intrinsics::mir::*;
@@ -13,6 +13,7 @@ pub fn main() {
         let a: [u8; 1024];
         {
             Call(a = f(Move(a)), ReturnTo(bb1), UnwindUnreachable()) //~ ERROR broken MIR
+            //~^ ERROR encountered overlapping memory in `Move` arguments to `Call`
         }
         bb1 = {
             Return()
diff --git a/tests/ui/mir/lint/storage-live.rs b/tests/ui/mir/lint/storage-live.rs
index 19d046b619c..252e3b8456c 100644
--- a/tests/ui/mir/lint/storage-live.rs
+++ b/tests/ui/mir/lint/storage-live.rs
@@ -1,7 +1,5 @@
 //@ compile-flags: -Zlint-mir -Ztreat-err-as-bug
 //@ failure-status: 101
-//@ error-pattern: broken MIR in
-//@ error-pattern: StorageLive(_1) which already has storage here
 //@ normalize-stderr: "note: .*\n\n" -> ""
 //@ normalize-stderr: "thread 'rustc' panicked.*\n" -> ""
 //@ normalize-stderr: "storage_live\[....\]" -> "storage_live[HASH]"
@@ -21,6 +19,7 @@ fn multiple_storage() {
         {
             StorageLive(a);
             StorageLive(a); //~ ERROR broken MIR
+                            //~| ERROR StorageLive(_1) which already has storage here
             Return()
         }
     }
diff --git a/tests/ui/mir/lint/storage-live.stderr b/tests/ui/mir/lint/storage-live.stderr
index 651b8e2327e..50df9ae061f 100644
--- a/tests/ui/mir/lint/storage-live.stderr
+++ b/tests/ui/mir/lint/storage-live.stderr
@@ -1,12 +1,12 @@
 error: internal compiler error: broken MIR in Item(DefId(0:8 ~ storage_live[HASH]::multiple_storage)) (after pass CheckForceInline) at bb0[1]:
                                 StorageLive(_1) which already has storage here
-  --> $DIR/storage-live.rs:23:13
+  --> $DIR/storage-live.rs:21:13
    |
 LL |             StorageLive(a);
    |             ^^^^^^^^^^^^^^
    |
 note: delayed at compiler/rustc_mir_transform/src/lint.rs:LL:CC - disabled backtrace
-  --> $DIR/storage-live.rs:23:13
+  --> $DIR/storage-live.rs:21:13
    |
 LL |             StorageLive(a);
    |             ^^^^^^^^^^^^^^
diff --git a/tests/ui/mir/lint/storage-return.rs b/tests/ui/mir/lint/storage-return.rs
index 3bbd0045d9d..c3e1f00bd72 100644
--- a/tests/ui/mir/lint/storage-return.rs
+++ b/tests/ui/mir/lint/storage-return.rs
@@ -1,7 +1,7 @@
 //@ compile-flags: -Zlint-mir -Ztreat-err-as-bug -Zeagerly-emit-delayed-bugs
 //@ failure-status: 101
 //@ dont-check-compiler-stderr
-//@ error-pattern: has storage when returning
+
 #![feature(custom_mir, core_intrinsics)]
 extern crate core;
 use core::intrinsics::mir::*;
@@ -14,6 +14,7 @@ fn main() {
             StorageLive(a);
             RET = a;
             Return() //~ ERROR broken MIR
+                     //~^ ERROR has storage when returning
         }
     }
 }
diff --git a/tests/ui/mir/validate/critical-edge.rs b/tests/ui/mir/validate/critical-edge.rs
index 9048d08a22a..2a3bf6a6181 100644
--- a/tests/ui/mir/validate/critical-edge.rs
+++ b/tests/ui/mir/validate/critical-edge.rs
@@ -5,7 +5,7 @@
 //@ compile-flags: --crate-type=lib
 //@ failure-status: 101
 //@ dont-check-compiler-stderr
-//@ error-pattern: encountered critical edge in `Call` terminator
+
 #![feature(custom_mir, core_intrinsics)]
 use core::intrinsics::mir::*;
 
@@ -29,3 +29,5 @@ pub fn f(a: u32) -> u32 {
         }
     }
 }
+
+//~? RAW encountered critical edge in `Call` terminator
diff --git a/tests/ui/mismatched_types/dont-point-return-on-E0308.rs b/tests/ui/mismatched_types/dont-point-return-on-E0308.rs
index dca917e3ba1..750329d29c0 100644
--- a/tests/ui/mismatched_types/dont-point-return-on-E0308.rs
+++ b/tests/ui/mismatched_types/dont-point-return-on-E0308.rs
@@ -2,7 +2,6 @@
 
 async fn f(_: &()) {}
 //~^ NOTE function defined here
-//~| NOTE
 // Second note is the span of the underlined argument, I think...
 
 fn main() {
diff --git a/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr b/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr
index 9d4852cff8c..105dc5c2e79 100644
--- a/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr
+++ b/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/dont-point-return-on-E0308.rs:11:11
+  --> $DIR/dont-point-return-on-E0308.rs:10:11
    |
 LL |         f(());
    |         - ^^ expected `&()`, found `()`
diff --git a/tests/ui/mismatched_types/similar_paths_primitive.rs b/tests/ui/mismatched_types/similar_paths_primitive.rs
index b20ca80ac07..a58fe68b863 100644
--- a/tests/ui/mismatched_types/similar_paths_primitive.rs
+++ b/tests/ui/mismatched_types/similar_paths_primitive.rs
@@ -4,9 +4,8 @@ struct bool; //~ NOTE the other `bool` is defined in the current crate
 struct str; //~ NOTE the other `str` is defined in the current crate
 
 fn foo(_: bool) {} //~ NOTE function defined here
-                   //~^ NOTE
 fn bar(_: &str) {} //~ NOTE function defined here
-                   //~^ NOTE
+
 fn main() {
     foo(true);
     //~^ ERROR mismatched types [E0308]
diff --git a/tests/ui/mismatched_types/similar_paths_primitive.stderr b/tests/ui/mismatched_types/similar_paths_primitive.stderr
index 9c1aa0d7105..cf26234dba8 100644
--- a/tests/ui/mismatched_types/similar_paths_primitive.stderr
+++ b/tests/ui/mismatched_types/similar_paths_primitive.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/similar_paths_primitive.rs:11:9
+  --> $DIR/similar_paths_primitive.rs:10:9
    |
 LL |     foo(true);
    |     --- ^^^^ expected `bool`, found a different `bool`
@@ -20,7 +20,7 @@ LL | fn foo(_: bool) {}
    |    ^^^ -------
 
 error[E0308]: mismatched types
-  --> $DIR/similar_paths_primitive.rs:17:9
+  --> $DIR/similar_paths_primitive.rs:16:9
    |
 LL |     bar("hello");
    |     --- ^^^^^^^ expected `str`, found a different `str`
@@ -35,7 +35,7 @@ note: the other `str` is defined in the current crate
 LL | struct str;
    | ^^^^^^^^^^
 note: function defined here
-  --> $DIR/similar_paths_primitive.rs:8:4
+  --> $DIR/similar_paths_primitive.rs:7:4
    |
 LL | fn bar(_: &str) {}
    |    ^^^ -------
diff --git a/tests/ui/nll/nested-bodies-in-dead-code.rs b/tests/ui/nll/nested-bodies-in-dead-code.rs
new file mode 100644
index 00000000000..6ac68f5adbc
--- /dev/null
+++ b/tests/ui/nll/nested-bodies-in-dead-code.rs
@@ -0,0 +1,28 @@
+//@ edition: 2024
+
+// Regression test for #140583. We want to borrowck nested
+// bodies even if they are in dead code. While not necessary for
+// soundness, it is desirable to error in such cases.
+
+fn main() {
+    return;
+    |x: &str| -> &'static str { x };
+    //~^ ERROR lifetime may not live long enough
+    || {
+        || {
+            let temp = 1;
+            let p: &'static u32 = &temp;
+            //~^ ERROR `temp` does not live long enough
+        };
+    };
+    const {
+        let temp = 1;
+        let p: &'static u32 = &temp;
+        //~^ ERROR `temp` does not live long enough
+    };
+    async {
+        let temp = 1;
+        let p: &'static u32 = &temp;
+        //~^ ERROR `temp` does not live long enough
+    };
+}
diff --git a/tests/ui/nll/nested-bodies-in-dead-code.stderr b/tests/ui/nll/nested-bodies-in-dead-code.stderr
new file mode 100644
index 00000000000..da6ccff5777
--- /dev/null
+++ b/tests/ui/nll/nested-bodies-in-dead-code.stderr
@@ -0,0 +1,50 @@
+error: lifetime may not live long enough
+  --> $DIR/nested-bodies-in-dead-code.rs:9:33
+   |
+LL |     |x: &str| -> &'static str { x };
+   |         -                       ^ returning this value requires that `'1` must outlive `'static`
+   |         |
+   |         let's call the lifetime of this reference `'1`
+
+error[E0597]: `temp` does not live long enough
+  --> $DIR/nested-bodies-in-dead-code.rs:14:35
+   |
+LL |             let temp = 1;
+   |                 ---- binding `temp` declared here
+LL |             let p: &'static u32 = &temp;
+   |                    ------------   ^^^^^ borrowed value does not live long enough
+   |                    |
+   |                    type annotation requires that `temp` is borrowed for `'static`
+LL |
+LL |         };
+   |         - `temp` dropped here while still borrowed
+
+error[E0597]: `temp` does not live long enough
+  --> $DIR/nested-bodies-in-dead-code.rs:20:31
+   |
+LL |         let temp = 1;
+   |             ---- binding `temp` declared here
+LL |         let p: &'static u32 = &temp;
+   |                ------------   ^^^^^ borrowed value does not live long enough
+   |                |
+   |                type annotation requires that `temp` is borrowed for `'static`
+LL |
+LL |     };
+   |     - `temp` dropped here while still borrowed
+
+error[E0597]: `temp` does not live long enough
+  --> $DIR/nested-bodies-in-dead-code.rs:25:31
+   |
+LL |         let temp = 1;
+   |             ---- binding `temp` declared here
+LL |         let p: &'static u32 = &temp;
+   |                ------------   ^^^^^ borrowed value does not live long enough
+   |                |
+   |                type annotation requires that `temp` is borrowed for `'static`
+LL |
+LL |     };
+   |     - `temp` dropped here while still borrowed
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/no-link-unknown-crate.rs b/tests/ui/no-link-unknown-crate.rs
deleted file mode 100644
index c7da2e41832..00000000000
--- a/tests/ui/no-link-unknown-crate.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-#[no_link]
-extern crate doesnt_exist; //~ ERROR can't find crate
-
-fn main() {}
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.fixed b/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.fixed
index e3b613cc3f6..9f891afc313 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.fixed
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.fixed
@@ -12,17 +12,6 @@ fn foo<N>(_x: N) {}
 //~| NOTE function defined here
 //~| NOTE function defined here
 //~| NOTE function defined here
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
 
 fn main() {
     foo::<i32>(42_i32);
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.rs b/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.rs
index 3b384e76310..a735fade86e 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.rs
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.rs
@@ -12,17 +12,6 @@ fn foo<N>(_x: N) {}
 //~| NOTE function defined here
 //~| NOTE function defined here
 //~| NOTE function defined here
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
 
 fn main() {
     foo::<i32>(42_usize);
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.stderr b/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.stderr
index 6c6b8b51c22..b3450b41d38 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.stderr
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-i32.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i32.rs:28:16
+  --> $DIR/numeric-suffix-i32.rs:17:16
    |
 LL |     foo::<i32>(42_usize);
    |     ---------- ^^^^^^^^ expected `i32`, found `usize`
@@ -18,7 +18,7 @@ LL +     foo::<i32>(42_i32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i32.rs:32:16
+  --> $DIR/numeric-suffix-i32.rs:21:16
    |
 LL |     foo::<i32>(42_u64);
    |     ---------- ^^^^^^ expected `i32`, found `u64`
@@ -37,7 +37,7 @@ LL +     foo::<i32>(42_i32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i32.rs:36:16
+  --> $DIR/numeric-suffix-i32.rs:25:16
    |
 LL |     foo::<i32>(42_u32);
    |     ---------- ^^^^^^ expected `i32`, found `u32`
@@ -56,7 +56,7 @@ LL +     foo::<i32>(42_i32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i32.rs:40:16
+  --> $DIR/numeric-suffix-i32.rs:29:16
    |
 LL |     foo::<i32>(42_u16);
    |     ---------- ^^^^^^ expected `i32`, found `u16`
@@ -75,7 +75,7 @@ LL +     foo::<i32>(42_i32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i32.rs:44:16
+  --> $DIR/numeric-suffix-i32.rs:33:16
    |
 LL |     foo::<i32>(42_u8);
    |     ---------- ^^^^^ expected `i32`, found `u8`
@@ -94,7 +94,7 @@ LL +     foo::<i32>(42_i32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i32.rs:48:16
+  --> $DIR/numeric-suffix-i32.rs:37:16
    |
 LL |     foo::<i32>(42_isize);
    |     ---------- ^^^^^^^^ expected `i32`, found `isize`
@@ -113,7 +113,7 @@ LL +     foo::<i32>(42_i32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i32.rs:52:16
+  --> $DIR/numeric-suffix-i32.rs:41:16
    |
 LL |     foo::<i32>(42_i64);
    |     ---------- ^^^^^^ expected `i32`, found `i64`
@@ -132,7 +132,7 @@ LL +     foo::<i32>(42_i32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i32.rs:57:16
+  --> $DIR/numeric-suffix-i32.rs:46:16
    |
 LL |     foo::<i32>(42_i16);
    |     ---------- ^^^^^^ expected `i32`, found `i16`
@@ -151,7 +151,7 @@ LL +     foo::<i32>(42_i32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i32.rs:61:16
+  --> $DIR/numeric-suffix-i32.rs:50:16
    |
 LL |     foo::<i32>(42_i8);
    |     ---------- ^^^^^ expected `i32`, found `i8`
@@ -170,7 +170,7 @@ LL +     foo::<i32>(42_i32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i32.rs:65:16
+  --> $DIR/numeric-suffix-i32.rs:54:16
    |
 LL |     foo::<i32>(42.0_f64);
    |     ---------- ^^^^^^^^ expected `i32`, found `f64`
@@ -189,7 +189,7 @@ LL +     foo::<i32>(42i32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i32.rs:69:16
+  --> $DIR/numeric-suffix-i32.rs:58:16
    |
 LL |     foo::<i32>(42.0_f32);
    |     ---------- ^^^^^^^^ expected `i32`, found `f32`
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.fixed b/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.fixed
index 0fcda6c1f80..6d1c585a563 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.fixed
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.fixed
@@ -12,17 +12,6 @@ fn foo<N>(_x: N) {}
 //~| NOTE function defined here
 //~| NOTE function defined here
 //~| NOTE function defined here
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
 
 fn main() {
     foo::<i64>(42_i64);
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.rs b/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.rs
index 9c912bc38da..fd4862be387 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.rs
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.rs
@@ -12,17 +12,6 @@ fn foo<N>(_x: N) {}
 //~| NOTE function defined here
 //~| NOTE function defined here
 //~| NOTE function defined here
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
 
 fn main() {
     foo::<i64>(42_usize);
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.stderr b/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.stderr
index 7c26dd7be1c..63326f49a8f 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.stderr
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-i64.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i64.rs:28:16
+  --> $DIR/numeric-suffix-i64.rs:17:16
    |
 LL |     foo::<i64>(42_usize);
    |     ---------- ^^^^^^^^ expected `i64`, found `usize`
@@ -18,7 +18,7 @@ LL +     foo::<i64>(42_i64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i64.rs:32:16
+  --> $DIR/numeric-suffix-i64.rs:21:16
    |
 LL |     foo::<i64>(42_u64);
    |     ---------- ^^^^^^ expected `i64`, found `u64`
@@ -37,7 +37,7 @@ LL +     foo::<i64>(42_i64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i64.rs:36:16
+  --> $DIR/numeric-suffix-i64.rs:25:16
    |
 LL |     foo::<i64>(42_u32);
    |     ---------- ^^^^^^ expected `i64`, found `u32`
@@ -56,7 +56,7 @@ LL +     foo::<i64>(42_i64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i64.rs:40:16
+  --> $DIR/numeric-suffix-i64.rs:29:16
    |
 LL |     foo::<i64>(42_u16);
    |     ---------- ^^^^^^ expected `i64`, found `u16`
@@ -75,7 +75,7 @@ LL +     foo::<i64>(42_i64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i64.rs:44:16
+  --> $DIR/numeric-suffix-i64.rs:33:16
    |
 LL |     foo::<i64>(42_u8);
    |     ---------- ^^^^^ expected `i64`, found `u8`
@@ -94,7 +94,7 @@ LL +     foo::<i64>(42_i64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i64.rs:48:16
+  --> $DIR/numeric-suffix-i64.rs:37:16
    |
 LL |     foo::<i64>(42_isize);
    |     ---------- ^^^^^^^^ expected `i64`, found `isize`
@@ -113,7 +113,7 @@ LL +     foo::<i64>(42_i64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i64.rs:53:16
+  --> $DIR/numeric-suffix-i64.rs:42:16
    |
 LL |     foo::<i64>(42_i32);
    |     ---------- ^^^^^^ expected `i64`, found `i32`
@@ -132,7 +132,7 @@ LL +     foo::<i64>(42_i64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i64.rs:57:16
+  --> $DIR/numeric-suffix-i64.rs:46:16
    |
 LL |     foo::<i64>(42_i16);
    |     ---------- ^^^^^^ expected `i64`, found `i16`
@@ -151,7 +151,7 @@ LL +     foo::<i64>(42_i64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i64.rs:61:16
+  --> $DIR/numeric-suffix-i64.rs:50:16
    |
 LL |     foo::<i64>(42_i8);
    |     ---------- ^^^^^ expected `i64`, found `i8`
@@ -170,7 +170,7 @@ LL +     foo::<i64>(42_i64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i64.rs:65:16
+  --> $DIR/numeric-suffix-i64.rs:54:16
    |
 LL |     foo::<i64>(42.0_f64);
    |     ---------- ^^^^^^^^ expected `i64`, found `f64`
@@ -189,7 +189,7 @@ LL +     foo::<i64>(42i64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-i64.rs:69:16
+  --> $DIR/numeric-suffix-i64.rs:58:16
    |
 LL |     foo::<i64>(42.0_f32);
    |     ---------- ^^^^^^^^ expected `i64`, found `f32`
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.fixed b/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.fixed
index 23e7cf780e9..f24fce3f1d6 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.fixed
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.fixed
@@ -12,17 +12,6 @@ fn foo<N>(_x: N) {}
 //~| NOTE function defined here
 //~| NOTE function defined here
 //~| NOTE function defined here
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
 
 fn main() {
     foo::<isize>(42_isize);
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.rs b/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.rs
index 5d6fd4d932a..fdf86895ff2 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.rs
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.rs
@@ -12,17 +12,6 @@ fn foo<N>(_x: N) {}
 //~| NOTE function defined here
 //~| NOTE function defined here
 //~| NOTE function defined here
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
 
 fn main() {
     foo::<isize>(42_usize);
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.stderr b/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.stderr
index 8365350f2bf..99561b19021 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.stderr
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-isize.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-isize.rs:28:18
+  --> $DIR/numeric-suffix-isize.rs:17:18
    |
 LL |     foo::<isize>(42_usize);
    |     ------------ ^^^^^^^^ expected `isize`, found `usize`
@@ -18,7 +18,7 @@ LL +     foo::<isize>(42_isize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-isize.rs:32:18
+  --> $DIR/numeric-suffix-isize.rs:21:18
    |
 LL |     foo::<isize>(42_u64);
    |     ------------ ^^^^^^ expected `isize`, found `u64`
@@ -37,7 +37,7 @@ LL +     foo::<isize>(42_isize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-isize.rs:36:18
+  --> $DIR/numeric-suffix-isize.rs:25:18
    |
 LL |     foo::<isize>(42_u32);
    |     ------------ ^^^^^^ expected `isize`, found `u32`
@@ -56,7 +56,7 @@ LL +     foo::<isize>(42_isize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-isize.rs:40:18
+  --> $DIR/numeric-suffix-isize.rs:29:18
    |
 LL |     foo::<isize>(42_u16);
    |     ------------ ^^^^^^ expected `isize`, found `u16`
@@ -75,7 +75,7 @@ LL +     foo::<isize>(42_isize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-isize.rs:44:18
+  --> $DIR/numeric-suffix-isize.rs:33:18
    |
 LL |     foo::<isize>(42_u8);
    |     ------------ ^^^^^ expected `isize`, found `u8`
@@ -94,7 +94,7 @@ LL +     foo::<isize>(42_isize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-isize.rs:49:18
+  --> $DIR/numeric-suffix-isize.rs:38:18
    |
 LL |     foo::<isize>(42_i64);
    |     ------------ ^^^^^^ expected `isize`, found `i64`
@@ -113,7 +113,7 @@ LL +     foo::<isize>(42_isize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-isize.rs:53:18
+  --> $DIR/numeric-suffix-isize.rs:42:18
    |
 LL |     foo::<isize>(42_i32);
    |     ------------ ^^^^^^ expected `isize`, found `i32`
@@ -132,7 +132,7 @@ LL +     foo::<isize>(42_isize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-isize.rs:57:18
+  --> $DIR/numeric-suffix-isize.rs:46:18
    |
 LL |     foo::<isize>(42_i16);
    |     ------------ ^^^^^^ expected `isize`, found `i16`
@@ -151,7 +151,7 @@ LL +     foo::<isize>(42_isize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-isize.rs:61:18
+  --> $DIR/numeric-suffix-isize.rs:50:18
    |
 LL |     foo::<isize>(42_i8);
    |     ------------ ^^^^^ expected `isize`, found `i8`
@@ -170,7 +170,7 @@ LL +     foo::<isize>(42_isize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-isize.rs:65:18
+  --> $DIR/numeric-suffix-isize.rs:54:18
    |
 LL |     foo::<isize>(42.0_f64);
    |     ------------ ^^^^^^^^ expected `isize`, found `f64`
@@ -189,7 +189,7 @@ LL +     foo::<isize>(42isize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-isize.rs:69:18
+  --> $DIR/numeric-suffix-isize.rs:58:18
    |
 LL |     foo::<isize>(42.0_f32);
    |     ------------ ^^^^^^^^ expected `isize`, found `f32`
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.fixed b/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.fixed
index 2dd7d9aabdb..eba5d7c1c26 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.fixed
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.fixed
@@ -12,17 +12,6 @@ fn foo<N>(_x: N) {}
 //~| NOTE function defined here
 //~| NOTE function defined here
 //~| NOTE function defined here
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
 
 fn main() {
     foo::<u32>(42_u32);
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.rs b/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.rs
index 46bbb033185..d127353e975 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.rs
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.rs
@@ -12,17 +12,6 @@ fn foo<N>(_x: N) {}
 //~| NOTE function defined here
 //~| NOTE function defined here
 //~| NOTE function defined here
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
 
 fn main() {
     foo::<u32>(42_usize);
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.stderr b/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.stderr
index 610e6ece276..95e913595e5 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.stderr
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-u32.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u32.rs:28:16
+  --> $DIR/numeric-suffix-u32.rs:17:16
    |
 LL |     foo::<u32>(42_usize);
    |     ---------- ^^^^^^^^ expected `u32`, found `usize`
@@ -18,7 +18,7 @@ LL +     foo::<u32>(42_u32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u32.rs:32:16
+  --> $DIR/numeric-suffix-u32.rs:21:16
    |
 LL |     foo::<u32>(42_u64);
    |     ---------- ^^^^^^ expected `u32`, found `u64`
@@ -37,7 +37,7 @@ LL +     foo::<u32>(42_u32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u32.rs:37:16
+  --> $DIR/numeric-suffix-u32.rs:26:16
    |
 LL |     foo::<u32>(42_u16);
    |     ---------- ^^^^^^ expected `u32`, found `u16`
@@ -56,7 +56,7 @@ LL +     foo::<u32>(42_u32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u32.rs:41:16
+  --> $DIR/numeric-suffix-u32.rs:30:16
    |
 LL |     foo::<u32>(42_u8);
    |     ---------- ^^^^^ expected `u32`, found `u8`
@@ -75,7 +75,7 @@ LL +     foo::<u32>(42_u32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u32.rs:45:16
+  --> $DIR/numeric-suffix-u32.rs:34:16
    |
 LL |     foo::<u32>(42_isize);
    |     ---------- ^^^^^^^^ expected `u32`, found `isize`
@@ -94,7 +94,7 @@ LL +     foo::<u32>(42_u32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u32.rs:49:16
+  --> $DIR/numeric-suffix-u32.rs:38:16
    |
 LL |     foo::<u32>(42_i64);
    |     ---------- ^^^^^^ expected `u32`, found `i64`
@@ -113,7 +113,7 @@ LL +     foo::<u32>(42_u32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u32.rs:53:16
+  --> $DIR/numeric-suffix-u32.rs:42:16
    |
 LL |     foo::<u32>(42_i32);
    |     ---------- ^^^^^^ expected `u32`, found `i32`
@@ -132,7 +132,7 @@ LL +     foo::<u32>(42_u32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u32.rs:57:16
+  --> $DIR/numeric-suffix-u32.rs:46:16
    |
 LL |     foo::<u32>(42_i16);
    |     ---------- ^^^^^^ expected `u32`, found `i16`
@@ -151,7 +151,7 @@ LL +     foo::<u32>(42_u32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u32.rs:61:16
+  --> $DIR/numeric-suffix-u32.rs:50:16
    |
 LL |     foo::<u32>(42_i8);
    |     ---------- ^^^^^ expected `u32`, found `i8`
@@ -170,7 +170,7 @@ LL +     foo::<u32>(42_u32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u32.rs:65:16
+  --> $DIR/numeric-suffix-u32.rs:54:16
    |
 LL |     foo::<u32>(42.0_f64);
    |     ---------- ^^^^^^^^ expected `u32`, found `f64`
@@ -189,7 +189,7 @@ LL +     foo::<u32>(42u32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u32.rs:69:16
+  --> $DIR/numeric-suffix-u32.rs:58:16
    |
 LL |     foo::<u32>(42.0_f32);
    |     ---------- ^^^^^^^^ expected `u32`, found `f32`
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.fixed b/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.fixed
index 2dea195f098..c8344211d3d 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.fixed
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.fixed
@@ -12,17 +12,6 @@ fn foo<N>(_x: N) {}
 //~| NOTE function defined here
 //~| NOTE function defined here
 //~| NOTE function defined here
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
 
 fn main() {
     foo::<u64>(42_u64);
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.rs b/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.rs
index 6fca089b07d..f9b35efbc4b 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.rs
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.rs
@@ -12,17 +12,6 @@ fn foo<N>(_x: N) {}
 //~| NOTE function defined here
 //~| NOTE function defined here
 //~| NOTE function defined here
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
 
 fn main() {
     foo::<u64>(42_usize);
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.stderr b/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.stderr
index 112dddccd6f..0c92b413761 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.stderr
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-u64.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u64.rs:28:16
+  --> $DIR/numeric-suffix-u64.rs:17:16
    |
 LL |     foo::<u64>(42_usize);
    |     ---------- ^^^^^^^^ expected `u64`, found `usize`
@@ -18,7 +18,7 @@ LL +     foo::<u64>(42_u64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u64.rs:33:16
+  --> $DIR/numeric-suffix-u64.rs:22:16
    |
 LL |     foo::<u64>(42_u32);
    |     ---------- ^^^^^^ expected `u64`, found `u32`
@@ -37,7 +37,7 @@ LL +     foo::<u64>(42_u64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u64.rs:37:16
+  --> $DIR/numeric-suffix-u64.rs:26:16
    |
 LL |     foo::<u64>(42_u16);
    |     ---------- ^^^^^^ expected `u64`, found `u16`
@@ -56,7 +56,7 @@ LL +     foo::<u64>(42_u64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u64.rs:41:16
+  --> $DIR/numeric-suffix-u64.rs:30:16
    |
 LL |     foo::<u64>(42_u8);
    |     ---------- ^^^^^ expected `u64`, found `u8`
@@ -75,7 +75,7 @@ LL +     foo::<u64>(42_u64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u64.rs:45:16
+  --> $DIR/numeric-suffix-u64.rs:34:16
    |
 LL |     foo::<u64>(42_isize);
    |     ---------- ^^^^^^^^ expected `u64`, found `isize`
@@ -94,7 +94,7 @@ LL +     foo::<u64>(42_u64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u64.rs:49:16
+  --> $DIR/numeric-suffix-u64.rs:38:16
    |
 LL |     foo::<u64>(42_i64);
    |     ---------- ^^^^^^ expected `u64`, found `i64`
@@ -113,7 +113,7 @@ LL +     foo::<u64>(42_u64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u64.rs:53:16
+  --> $DIR/numeric-suffix-u64.rs:42:16
    |
 LL |     foo::<u64>(42_i32);
    |     ---------- ^^^^^^ expected `u64`, found `i32`
@@ -132,7 +132,7 @@ LL +     foo::<u64>(42_u64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u64.rs:57:16
+  --> $DIR/numeric-suffix-u64.rs:46:16
    |
 LL |     foo::<u64>(42_i16);
    |     ---------- ^^^^^^ expected `u64`, found `i16`
@@ -151,7 +151,7 @@ LL +     foo::<u64>(42_u64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u64.rs:61:16
+  --> $DIR/numeric-suffix-u64.rs:50:16
    |
 LL |     foo::<u64>(42_i8);
    |     ---------- ^^^^^ expected `u64`, found `i8`
@@ -170,7 +170,7 @@ LL +     foo::<u64>(42_u64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u64.rs:65:16
+  --> $DIR/numeric-suffix-u64.rs:54:16
    |
 LL |     foo::<u64>(42.0_f64);
    |     ---------- ^^^^^^^^ expected `u64`, found `f64`
@@ -189,7 +189,7 @@ LL +     foo::<u64>(42u64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-u64.rs:69:16
+  --> $DIR/numeric-suffix-u64.rs:58:16
    |
 LL |     foo::<u64>(42.0_f32);
    |     ---------- ^^^^^^^^ expected `u64`, found `f32`
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.fixed b/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.fixed
index 63422c305d3..4d5176fe724 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.fixed
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.fixed
@@ -12,17 +12,6 @@ fn foo<N>(_x: N) {}
 //~| NOTE function defined here
 //~| NOTE function defined here
 //~| NOTE function defined here
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
 
 fn main() {
     foo::<usize>(42_usize);
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.rs b/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.rs
index 4d20e4fc843..118d8ca219e 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.rs
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.rs
@@ -12,17 +12,6 @@ fn foo<N>(_x: N) {}
 //~| NOTE function defined here
 //~| NOTE function defined here
 //~| NOTE function defined here
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
 
 fn main() {
     foo::<usize>(42_usize);
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.stderr b/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.stderr
index e7d6a04f18e..86181d6714f 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.stderr
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix-usize.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-usize.rs:29:18
+  --> $DIR/numeric-suffix-usize.rs:18:18
    |
 LL |     foo::<usize>(42_u64);
    |     ------------ ^^^^^^ expected `usize`, found `u64`
@@ -18,7 +18,7 @@ LL +     foo::<usize>(42_usize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-usize.rs:33:18
+  --> $DIR/numeric-suffix-usize.rs:22:18
    |
 LL |     foo::<usize>(42_u32);
    |     ------------ ^^^^^^ expected `usize`, found `u32`
@@ -37,7 +37,7 @@ LL +     foo::<usize>(42_usize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-usize.rs:37:18
+  --> $DIR/numeric-suffix-usize.rs:26:18
    |
 LL |     foo::<usize>(42_u16);
    |     ------------ ^^^^^^ expected `usize`, found `u16`
@@ -56,7 +56,7 @@ LL +     foo::<usize>(42_usize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-usize.rs:41:18
+  --> $DIR/numeric-suffix-usize.rs:30:18
    |
 LL |     foo::<usize>(42_u8);
    |     ------------ ^^^^^ expected `usize`, found `u8`
@@ -75,7 +75,7 @@ LL +     foo::<usize>(42_usize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-usize.rs:45:18
+  --> $DIR/numeric-suffix-usize.rs:34:18
    |
 LL |     foo::<usize>(42_isize);
    |     ------------ ^^^^^^^^ expected `usize`, found `isize`
@@ -94,7 +94,7 @@ LL +     foo::<usize>(42_usize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-usize.rs:49:18
+  --> $DIR/numeric-suffix-usize.rs:38:18
    |
 LL |     foo::<usize>(42_i64);
    |     ------------ ^^^^^^ expected `usize`, found `i64`
@@ -113,7 +113,7 @@ LL +     foo::<usize>(42_usize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-usize.rs:53:18
+  --> $DIR/numeric-suffix-usize.rs:42:18
    |
 LL |     foo::<usize>(42_i32);
    |     ------------ ^^^^^^ expected `usize`, found `i32`
@@ -132,7 +132,7 @@ LL +     foo::<usize>(42_usize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-usize.rs:57:18
+  --> $DIR/numeric-suffix-usize.rs:46:18
    |
 LL |     foo::<usize>(42_i16);
    |     ------------ ^^^^^^ expected `usize`, found `i16`
@@ -151,7 +151,7 @@ LL +     foo::<usize>(42_usize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-usize.rs:61:18
+  --> $DIR/numeric-suffix-usize.rs:50:18
    |
 LL |     foo::<usize>(42_i8);
    |     ------------ ^^^^^ expected `usize`, found `i8`
@@ -170,7 +170,7 @@ LL +     foo::<usize>(42_usize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-usize.rs:65:18
+  --> $DIR/numeric-suffix-usize.rs:54:18
    |
 LL |     foo::<usize>(42.0_f64);
    |     ------------ ^^^^^^^^ expected `usize`, found `f64`
@@ -189,7 +189,7 @@ LL +     foo::<usize>(42usize);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix-usize.rs:69:18
+  --> $DIR/numeric-suffix-usize.rs:58:18
    |
 LL |     foo::<usize>(42.0_f32);
    |     ------------ ^^^^^^^^ expected `usize`, found `f32`
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix.fixed b/tests/ui/numeric/numeric-suffix/numeric-suffix.fixed
index 270afb63957..b20b594dc2c 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix.fixed
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix.fixed
@@ -69,75 +69,6 @@ fn foo<N>(_x: N) {}
 //~| NOTE function defined here
 //~| NOTE function defined here
 //~| NOTE function defined here
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-
 
 fn main() {
     foo::<u16>(42_u16);
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix.rs b/tests/ui/numeric/numeric-suffix/numeric-suffix.rs
index 05be58e335b..9272902f519 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix.rs
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix.rs
@@ -69,75 +69,6 @@ fn foo<N>(_x: N) {}
 //~| NOTE function defined here
 //~| NOTE function defined here
 //~| NOTE function defined here
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-//~| NOTE
-
 
 fn main() {
     foo::<u16>(42_usize);
diff --git a/tests/ui/numeric/numeric-suffix/numeric-suffix.stderr b/tests/ui/numeric/numeric-suffix/numeric-suffix.stderr
index d26639a76f0..cae1268beec 100644
--- a/tests/ui/numeric/numeric-suffix/numeric-suffix.stderr
+++ b/tests/ui/numeric/numeric-suffix/numeric-suffix.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:143:16
+  --> $DIR/numeric-suffix.rs:74:16
    |
 LL |     foo::<u16>(42_usize);
    |     ---------- ^^^^^^^^ expected `u16`, found `usize`
@@ -18,7 +18,7 @@ LL +     foo::<u16>(42_u16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:147:16
+  --> $DIR/numeric-suffix.rs:78:16
    |
 LL |     foo::<u16>(42_u64);
    |     ---------- ^^^^^^ expected `u16`, found `u64`
@@ -37,7 +37,7 @@ LL +     foo::<u16>(42_u16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:151:16
+  --> $DIR/numeric-suffix.rs:82:16
    |
 LL |     foo::<u16>(42_u32);
    |     ---------- ^^^^^^ expected `u16`, found `u32`
@@ -56,7 +56,7 @@ LL +     foo::<u16>(42_u16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:156:16
+  --> $DIR/numeric-suffix.rs:87:16
    |
 LL |     foo::<u16>(42_u8);
    |     ---------- ^^^^^ expected `u16`, found `u8`
@@ -75,7 +75,7 @@ LL +     foo::<u16>(42_u16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:160:16
+  --> $DIR/numeric-suffix.rs:91:16
    |
 LL |     foo::<u16>(42_isize);
    |     ---------- ^^^^^^^^ expected `u16`, found `isize`
@@ -94,7 +94,7 @@ LL +     foo::<u16>(42_u16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:164:16
+  --> $DIR/numeric-suffix.rs:95:16
    |
 LL |     foo::<u16>(42_i64);
    |     ---------- ^^^^^^ expected `u16`, found `i64`
@@ -113,7 +113,7 @@ LL +     foo::<u16>(42_u16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:168:16
+  --> $DIR/numeric-suffix.rs:99:16
    |
 LL |     foo::<u16>(42_i32);
    |     ---------- ^^^^^^ expected `u16`, found `i32`
@@ -132,7 +132,7 @@ LL +     foo::<u16>(42_u16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:172:16
+  --> $DIR/numeric-suffix.rs:103:16
    |
 LL |     foo::<u16>(42_i16);
    |     ---------- ^^^^^^ expected `u16`, found `i16`
@@ -151,7 +151,7 @@ LL +     foo::<u16>(42_u16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:176:16
+  --> $DIR/numeric-suffix.rs:107:16
    |
 LL |     foo::<u16>(42_i8);
    |     ---------- ^^^^^ expected `u16`, found `i8`
@@ -170,7 +170,7 @@ LL +     foo::<u16>(42_u16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:180:16
+  --> $DIR/numeric-suffix.rs:111:16
    |
 LL |     foo::<u16>(42.0_f64);
    |     ---------- ^^^^^^^^ expected `u16`, found `f64`
@@ -189,7 +189,7 @@ LL +     foo::<u16>(42u16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:184:16
+  --> $DIR/numeric-suffix.rs:115:16
    |
 LL |     foo::<u16>(42.0_f32);
    |     ---------- ^^^^^^^^ expected `u16`, found `f32`
@@ -208,7 +208,7 @@ LL +     foo::<u16>(42u16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:189:16
+  --> $DIR/numeric-suffix.rs:120:16
    |
 LL |     foo::<i16>(42_usize);
    |     ---------- ^^^^^^^^ expected `i16`, found `usize`
@@ -227,7 +227,7 @@ LL +     foo::<i16>(42_i16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:193:16
+  --> $DIR/numeric-suffix.rs:124:16
    |
 LL |     foo::<i16>(42_u64);
    |     ---------- ^^^^^^ expected `i16`, found `u64`
@@ -246,7 +246,7 @@ LL +     foo::<i16>(42_i16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:197:16
+  --> $DIR/numeric-suffix.rs:128:16
    |
 LL |     foo::<i16>(42_u32);
    |     ---------- ^^^^^^ expected `i16`, found `u32`
@@ -265,7 +265,7 @@ LL +     foo::<i16>(42_i16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:201:16
+  --> $DIR/numeric-suffix.rs:132:16
    |
 LL |     foo::<i16>(42_u16);
    |     ---------- ^^^^^^ expected `i16`, found `u16`
@@ -284,7 +284,7 @@ LL +     foo::<i16>(42_i16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:205:16
+  --> $DIR/numeric-suffix.rs:136:16
    |
 LL |     foo::<i16>(42_u8);
    |     ---------- ^^^^^ expected `i16`, found `u8`
@@ -303,7 +303,7 @@ LL +     foo::<i16>(42_i16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:209:16
+  --> $DIR/numeric-suffix.rs:140:16
    |
 LL |     foo::<i16>(42_isize);
    |     ---------- ^^^^^^^^ expected `i16`, found `isize`
@@ -322,7 +322,7 @@ LL +     foo::<i16>(42_i16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:213:16
+  --> $DIR/numeric-suffix.rs:144:16
    |
 LL |     foo::<i16>(42_i64);
    |     ---------- ^^^^^^ expected `i16`, found `i64`
@@ -341,7 +341,7 @@ LL +     foo::<i16>(42_i16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:217:16
+  --> $DIR/numeric-suffix.rs:148:16
    |
 LL |     foo::<i16>(42_i32);
    |     ---------- ^^^^^^ expected `i16`, found `i32`
@@ -360,7 +360,7 @@ LL +     foo::<i16>(42_i16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:222:16
+  --> $DIR/numeric-suffix.rs:153:16
    |
 LL |     foo::<i16>(42_i8);
    |     ---------- ^^^^^ expected `i16`, found `i8`
@@ -379,7 +379,7 @@ LL +     foo::<i16>(42_i16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:226:16
+  --> $DIR/numeric-suffix.rs:157:16
    |
 LL |     foo::<i16>(42.0_f64);
    |     ---------- ^^^^^^^^ expected `i16`, found `f64`
@@ -398,7 +398,7 @@ LL +     foo::<i16>(42i16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:230:16
+  --> $DIR/numeric-suffix.rs:161:16
    |
 LL |     foo::<i16>(42.0_f32);
    |     ---------- ^^^^^^^^ expected `i16`, found `f32`
@@ -417,7 +417,7 @@ LL +     foo::<i16>(42i16);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:235:15
+  --> $DIR/numeric-suffix.rs:166:15
    |
 LL |     foo::<u8>(42_usize);
    |     --------- ^^^^^^^^ expected `u8`, found `usize`
@@ -436,7 +436,7 @@ LL +     foo::<u8>(42_u8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:239:15
+  --> $DIR/numeric-suffix.rs:170:15
    |
 LL |     foo::<u8>(42_u64);
    |     --------- ^^^^^^ expected `u8`, found `u64`
@@ -455,7 +455,7 @@ LL +     foo::<u8>(42_u8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:243:15
+  --> $DIR/numeric-suffix.rs:174:15
    |
 LL |     foo::<u8>(42_u32);
    |     --------- ^^^^^^ expected `u8`, found `u32`
@@ -474,7 +474,7 @@ LL +     foo::<u8>(42_u8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:247:15
+  --> $DIR/numeric-suffix.rs:178:15
    |
 LL |     foo::<u8>(42_u16);
    |     --------- ^^^^^^ expected `u8`, found `u16`
@@ -493,7 +493,7 @@ LL +     foo::<u8>(42_u8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:252:15
+  --> $DIR/numeric-suffix.rs:183:15
    |
 LL |     foo::<u8>(42_isize);
    |     --------- ^^^^^^^^ expected `u8`, found `isize`
@@ -512,7 +512,7 @@ LL +     foo::<u8>(42_u8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:256:15
+  --> $DIR/numeric-suffix.rs:187:15
    |
 LL |     foo::<u8>(42_i64);
    |     --------- ^^^^^^ expected `u8`, found `i64`
@@ -531,7 +531,7 @@ LL +     foo::<u8>(42_u8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:260:15
+  --> $DIR/numeric-suffix.rs:191:15
    |
 LL |     foo::<u8>(42_i32);
    |     --------- ^^^^^^ expected `u8`, found `i32`
@@ -550,7 +550,7 @@ LL +     foo::<u8>(42_u8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:264:15
+  --> $DIR/numeric-suffix.rs:195:15
    |
 LL |     foo::<u8>(42_i16);
    |     --------- ^^^^^^ expected `u8`, found `i16`
@@ -569,7 +569,7 @@ LL +     foo::<u8>(42_u8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:268:15
+  --> $DIR/numeric-suffix.rs:199:15
    |
 LL |     foo::<u8>(42_i8);
    |     --------- ^^^^^ expected `u8`, found `i8`
@@ -588,7 +588,7 @@ LL +     foo::<u8>(42_u8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:272:15
+  --> $DIR/numeric-suffix.rs:203:15
    |
 LL |     foo::<u8>(42.0_f64);
    |     --------- ^^^^^^^^ expected `u8`, found `f64`
@@ -607,7 +607,7 @@ LL +     foo::<u8>(42u8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:276:15
+  --> $DIR/numeric-suffix.rs:207:15
    |
 LL |     foo::<u8>(42.0_f32);
    |     --------- ^^^^^^^^ expected `u8`, found `f32`
@@ -626,7 +626,7 @@ LL +     foo::<u8>(42u8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:281:15
+  --> $DIR/numeric-suffix.rs:212:15
    |
 LL |     foo::<i8>(42_usize);
    |     --------- ^^^^^^^^ expected `i8`, found `usize`
@@ -645,7 +645,7 @@ LL +     foo::<i8>(42_i8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:285:15
+  --> $DIR/numeric-suffix.rs:216:15
    |
 LL |     foo::<i8>(42_u64);
    |     --------- ^^^^^^ expected `i8`, found `u64`
@@ -664,7 +664,7 @@ LL +     foo::<i8>(42_i8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:289:15
+  --> $DIR/numeric-suffix.rs:220:15
    |
 LL |     foo::<i8>(42_u32);
    |     --------- ^^^^^^ expected `i8`, found `u32`
@@ -683,7 +683,7 @@ LL +     foo::<i8>(42_i8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:293:15
+  --> $DIR/numeric-suffix.rs:224:15
    |
 LL |     foo::<i8>(42_u16);
    |     --------- ^^^^^^ expected `i8`, found `u16`
@@ -702,7 +702,7 @@ LL +     foo::<i8>(42_i8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:297:15
+  --> $DIR/numeric-suffix.rs:228:15
    |
 LL |     foo::<i8>(42_u8);
    |     --------- ^^^^^ expected `i8`, found `u8`
@@ -721,7 +721,7 @@ LL +     foo::<i8>(42_i8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:301:15
+  --> $DIR/numeric-suffix.rs:232:15
    |
 LL |     foo::<i8>(42_isize);
    |     --------- ^^^^^^^^ expected `i8`, found `isize`
@@ -740,7 +740,7 @@ LL +     foo::<i8>(42_i8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:305:15
+  --> $DIR/numeric-suffix.rs:236:15
    |
 LL |     foo::<i8>(42_i64);
    |     --------- ^^^^^^ expected `i8`, found `i64`
@@ -759,7 +759,7 @@ LL +     foo::<i8>(42_i8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:309:15
+  --> $DIR/numeric-suffix.rs:240:15
    |
 LL |     foo::<i8>(42_i32);
    |     --------- ^^^^^^ expected `i8`, found `i32`
@@ -778,7 +778,7 @@ LL +     foo::<i8>(42_i8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:313:15
+  --> $DIR/numeric-suffix.rs:244:15
    |
 LL |     foo::<i8>(42_i16);
    |     --------- ^^^^^^ expected `i8`, found `i16`
@@ -797,7 +797,7 @@ LL +     foo::<i8>(42_i8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:318:15
+  --> $DIR/numeric-suffix.rs:249:15
    |
 LL |     foo::<i8>(42.0_f64);
    |     --------- ^^^^^^^^ expected `i8`, found `f64`
@@ -816,7 +816,7 @@ LL +     foo::<i8>(42i8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:322:15
+  --> $DIR/numeric-suffix.rs:253:15
    |
 LL |     foo::<i8>(42.0_f32);
    |     --------- ^^^^^^^^ expected `i8`, found `f32`
@@ -835,7 +835,7 @@ LL +     foo::<i8>(42i8);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:327:16
+  --> $DIR/numeric-suffix.rs:258:16
    |
 LL |     foo::<f64>(42_usize);
    |     ---------- ^^^^^^^^ expected `f64`, found `usize`
@@ -854,7 +854,7 @@ LL +     foo::<f64>(42_f64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:331:16
+  --> $DIR/numeric-suffix.rs:262:16
    |
 LL |     foo::<f64>(42_u64);
    |     ---------- ^^^^^^ expected `f64`, found `u64`
@@ -873,7 +873,7 @@ LL +     foo::<f64>(42_f64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:335:16
+  --> $DIR/numeric-suffix.rs:266:16
    |
 LL |     foo::<f64>(42_u32);
    |     ---------- ^^^^^^ expected `f64`, found `u32`
@@ -891,7 +891,7 @@ LL |     foo::<f64>(42_u32.into());
    |                      +++++++
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:339:16
+  --> $DIR/numeric-suffix.rs:270:16
    |
 LL |     foo::<f64>(42_u16);
    |     ---------- ^^^^^^ expected `f64`, found `u16`
@@ -909,7 +909,7 @@ LL |     foo::<f64>(42_u16.into());
    |                      +++++++
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:343:16
+  --> $DIR/numeric-suffix.rs:274:16
    |
 LL |     foo::<f64>(42_u8);
    |     ---------- ^^^^^ expected `f64`, found `u8`
@@ -927,7 +927,7 @@ LL |     foo::<f64>(42_u8.into());
    |                     +++++++
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:347:16
+  --> $DIR/numeric-suffix.rs:278:16
    |
 LL |     foo::<f64>(42_isize);
    |     ---------- ^^^^^^^^ expected `f64`, found `isize`
@@ -946,7 +946,7 @@ LL +     foo::<f64>(42_f64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:351:16
+  --> $DIR/numeric-suffix.rs:282:16
    |
 LL |     foo::<f64>(42_i64);
    |     ---------- ^^^^^^ expected `f64`, found `i64`
@@ -965,7 +965,7 @@ LL +     foo::<f64>(42_f64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:355:16
+  --> $DIR/numeric-suffix.rs:286:16
    |
 LL |     foo::<f64>(42_i32);
    |     ---------- ^^^^^^ expected `f64`, found `i32`
@@ -983,7 +983,7 @@ LL |     foo::<f64>(42_i32.into());
    |                      +++++++
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:359:16
+  --> $DIR/numeric-suffix.rs:290:16
    |
 LL |     foo::<f64>(42_i16);
    |     ---------- ^^^^^^ expected `f64`, found `i16`
@@ -1001,7 +1001,7 @@ LL |     foo::<f64>(42_i16.into());
    |                      +++++++
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:363:16
+  --> $DIR/numeric-suffix.rs:294:16
    |
 LL |     foo::<f64>(42_i8);
    |     ---------- ^^^^^ expected `f64`, found `i8`
@@ -1019,7 +1019,7 @@ LL |     foo::<f64>(42_i8.into());
    |                     +++++++
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:368:16
+  --> $DIR/numeric-suffix.rs:299:16
    |
 LL |     foo::<f64>(42.0_f32);
    |     ---------- ^^^^^^^^ expected `f64`, found `f32`
@@ -1038,7 +1038,7 @@ LL +     foo::<f64>(42.0_f64);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:373:16
+  --> $DIR/numeric-suffix.rs:304:16
    |
 LL |     foo::<f32>(42_usize);
    |     ---------- ^^^^^^^^ expected `f32`, found `usize`
@@ -1057,7 +1057,7 @@ LL +     foo::<f32>(42_f32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:377:16
+  --> $DIR/numeric-suffix.rs:308:16
    |
 LL |     foo::<f32>(42_u64);
    |     ---------- ^^^^^^ expected `f32`, found `u64`
@@ -1076,7 +1076,7 @@ LL +     foo::<f32>(42_f32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:381:16
+  --> $DIR/numeric-suffix.rs:312:16
    |
 LL |     foo::<f32>(42_u32);
    |     ---------- ^^^^^^ expected `f32`, found `u32`
@@ -1095,7 +1095,7 @@ LL +     foo::<f32>(42_f32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:385:16
+  --> $DIR/numeric-suffix.rs:316:16
    |
 LL |     foo::<f32>(42_u16);
    |     ---------- ^^^^^^ expected `f32`, found `u16`
@@ -1113,7 +1113,7 @@ LL |     foo::<f32>(42_u16.into());
    |                      +++++++
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:389:16
+  --> $DIR/numeric-suffix.rs:320:16
    |
 LL |     foo::<f32>(42_u8);
    |     ---------- ^^^^^ expected `f32`, found `u8`
@@ -1131,7 +1131,7 @@ LL |     foo::<f32>(42_u8.into());
    |                     +++++++
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:393:16
+  --> $DIR/numeric-suffix.rs:324:16
    |
 LL |     foo::<f32>(42_isize);
    |     ---------- ^^^^^^^^ expected `f32`, found `isize`
@@ -1150,7 +1150,7 @@ LL +     foo::<f32>(42_f32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:397:16
+  --> $DIR/numeric-suffix.rs:328:16
    |
 LL |     foo::<f32>(42_i64);
    |     ---------- ^^^^^^ expected `f32`, found `i64`
@@ -1169,7 +1169,7 @@ LL +     foo::<f32>(42_f32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:401:16
+  --> $DIR/numeric-suffix.rs:332:16
    |
 LL |     foo::<f32>(42_i32);
    |     ---------- ^^^^^^ expected `f32`, found `i32`
@@ -1188,7 +1188,7 @@ LL +     foo::<f32>(42_f32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:405:16
+  --> $DIR/numeric-suffix.rs:336:16
    |
 LL |     foo::<f32>(42_i16);
    |     ---------- ^^^^^^ expected `f32`, found `i16`
@@ -1206,7 +1206,7 @@ LL |     foo::<f32>(42_i16.into());
    |                      +++++++
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:409:16
+  --> $DIR/numeric-suffix.rs:340:16
    |
 LL |     foo::<f32>(42_i8);
    |     ---------- ^^^^^ expected `f32`, found `i8`
@@ -1224,7 +1224,7 @@ LL |     foo::<f32>(42_i8.into());
    |                     +++++++
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:413:16
+  --> $DIR/numeric-suffix.rs:344:16
    |
 LL |     foo::<f32>(42.0_f64);
    |     ---------- ^^^^^^^^ expected `f32`, found `f64`
@@ -1243,7 +1243,7 @@ LL +     foo::<f32>(42.0_f32);
    |
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:419:16
+  --> $DIR/numeric-suffix.rs:350:16
    |
 LL |     foo::<u32>(42_u8 as u16);
    |     ---------- ^^^^^^^^^^^^ expected `u32`, found `u16`
@@ -1261,7 +1261,7 @@ LL |     foo::<u32>((42_u8 as u16).into());
    |                +            ++++++++
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:423:16
+  --> $DIR/numeric-suffix.rs:354:16
    |
 LL |     foo::<i32>(-42_i8);
    |     ---------- ^^^^^^ expected `i32`, found `i8`
diff --git a/tests/ui/on-unimplemented/bad-annotation.rs b/tests/ui/on-unimplemented/bad-annotation.rs
index f2b97865759..25de5978110 100644
--- a/tests/ui/on-unimplemented/bad-annotation.rs
+++ b/tests/ui/on-unimplemented/bad-annotation.rs
@@ -1,64 +1,109 @@
-// ignore-tidy-linelength
-
+#![crate_type = "lib"]
 #![feature(rustc_attrs)]
-
 #![allow(unused)]
 
 #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"]
-trait Foo<Bar, Baz, Quux>
-{}
+trait Foo<Bar, Baz, Quux> {}
 
-#[rustc_on_unimplemented="a collection of type `{Self}` cannot be built from an iterator over elements of type `{A}`"]
+#[rustc_on_unimplemented = "a collection of type `{Self}` cannot \
+ be built from an iterator over elements of type `{A}`"]
 trait MyFromIterator<A> {
     /// Builds a container with elements from an external iterator.
-    fn my_from_iter<T: Iterator<Item=A>>(iterator: T) -> Self;
+    fn my_from_iter<T: Iterator<Item = A>>(iterator: T) -> Self;
 }
 
 #[rustc_on_unimplemented]
 //~^ ERROR malformed `rustc_on_unimplemented` attribute
-trait BadAnnotation1
-{}
+trait NoContent {}
 
 #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"]
 //~^ ERROR cannot find parameter C on this trait
-trait BadAnnotation2<A,B>
-{}
+trait ParameterNotPresent<A, B> {}
 
 #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"]
 //~^ ERROR positional format arguments are not allowed here
-trait BadAnnotation3<A,B>
-{}
+trait NoPositionalArgs<A, B> {}
 
-#[rustc_on_unimplemented(lorem="")]
-//~^ ERROR this attribute must have a valid
-trait BadAnnotation4 {}
+#[rustc_on_unimplemented(lorem = "")]
+//~^ ERROR this attribute must have a value
+//~^^ NOTE e.g. `#[rustc_on_unimplemented(message="foo")]`
+//~^^^ NOTE expected value here
+trait EmptyMessage {}
 
 #[rustc_on_unimplemented(lorem(ipsum(dolor)))]
-//~^ ERROR this attribute must have a valid
-trait BadAnnotation5 {}
-
-#[rustc_on_unimplemented(message="x", message="y")]
-//~^ ERROR this attribute must have a valid
-trait BadAnnotation6 {}
-
-#[rustc_on_unimplemented(message="x", on(desugared, message="y"))]
-//~^ ERROR this attribute must have a valid
-trait BadAnnotation7 {}
-
-#[rustc_on_unimplemented(on(), message="y")]
+//~^ ERROR this attribute must have a value
+//~^^ NOTE e.g. `#[rustc_on_unimplemented(message="foo")]`
+//~^^^ NOTE expected value here
+trait Invalid {}
+
+#[rustc_on_unimplemented(message = "x", message = "y")]
+//~^ ERROR this attribute must have a value
+//~^^ NOTE e.g. `#[rustc_on_unimplemented(message="foo")]`
+//~^^^ NOTE expected value here
+trait DuplicateMessage {}
+
+#[rustc_on_unimplemented(message = "x", on(desugared, message = "y"))]
+//~^ ERROR this attribute must have a value
+//~^^ NOTE e.g. `#[rustc_on_unimplemented(message="foo")]`
+//~^^^ NOTE expected value here
+trait OnInWrongPosition {}
+
+#[rustc_on_unimplemented(on(), message = "y")]
 //~^ ERROR empty `on`-clause
-trait BadAnnotation8 {}
-
-#[rustc_on_unimplemented(on="x", message="y")]
-//~^ ERROR this attribute must have a valid
-trait BadAnnotation9 {}
-
-#[rustc_on_unimplemented(on(x="y"), message="y")]
-trait BadAnnotation10 {}
-
-#[rustc_on_unimplemented(on(desugared, on(desugared, message="x")), message="y")]
-//~^ ERROR this attribute must have a valid
-trait BadAnnotation11 {}
-
-pub fn main() {
-}
+//~^^ NOTE empty `on`-clause here
+trait EmptyOn {}
+
+#[rustc_on_unimplemented(on = "x", message = "y")]
+//~^ ERROR this attribute must have a value
+//~^^ NOTE e.g. `#[rustc_on_unimplemented(message="foo")]`
+//~^^^ NOTE expected value here
+trait ExpectedPredicateInOn {}
+
+#[rustc_on_unimplemented(on(x = "y"), message = "y")]
+trait OnWithoutDirectives {}
+
+#[rustc_on_unimplemented(on(from_desugaring, on(from_desugaring, message = "x")), message = "y")]
+//~^ ERROR this attribute must have a value
+//~^^ NOTE e.g. `#[rustc_on_unimplemented(message="foo")]`
+//~^^^ NOTE expected value here
+trait NestedOn {}
+
+#[rustc_on_unimplemented(on("y", message = "y"))]
+//~^ ERROR literals inside `on`-clauses are not supported
+//~^^ NOTE unexpected literal here
+trait UnsupportedLiteral {}
+
+#[rustc_on_unimplemented(on(42, message = "y"))]
+//~^ ERROR literals inside `on`-clauses are not supported
+//~^^ NOTE unexpected literal here
+trait UnsupportedLiteral2 {}
+
+#[rustc_on_unimplemented(on(not(a, b), message = "y"))]
+//~^ ERROR expected a single predicate in `not(..)` [E0232]
+//~^^ NOTE unexpected quantity of predicates here
+trait ExpectedOnePattern {}
+
+#[rustc_on_unimplemented(on(not(), message = "y"))]
+//~^ ERROR expected a single predicate in `not(..)` [E0232]
+//~^^ NOTE unexpected quantity of predicates here
+trait ExpectedOnePattern2 {}
+
+#[rustc_on_unimplemented(on(thing::What, message = "y"))]
+//~^ ERROR expected an identifier inside this `on`-clause
+//~^^ NOTE expected an identifier here, not `thing::What`
+trait KeyMustBeIdentifier {}
+
+#[rustc_on_unimplemented(on(thing::What = "value", message = "y"))]
+//~^ ERROR  expected an identifier inside this `on`-clause
+//~^^ NOTE expected an identifier here, not `thing::What`
+trait KeyMustBeIdentifier2 {}
+
+#[rustc_on_unimplemented(on(aaaaaaaaaaaaaa(a, b), message = "y"))]
+//~^ ERROR this predicate is invalid
+//~^^ NOTE expected one of `any`, `all` or `not` here, not `aaaaaaaaaaaaaa`
+trait InvalidPredicate {}
+
+#[rustc_on_unimplemented(on(something, message = "y"))]
+//~^ ERROR invalid flag in `on`-clause
+//~^^ NOTE expected one of the `crate_local`, `direct` or `from_desugaring` flags, not `something`
+trait InvalidFlag {}
diff --git a/tests/ui/on-unimplemented/bad-annotation.stderr b/tests/ui/on-unimplemented/bad-annotation.stderr
index afd737dc85e..35b919c7b78 100644
--- a/tests/ui/on-unimplemented/bad-annotation.stderr
+++ b/tests/ui/on-unimplemented/bad-annotation.stderr
@@ -1,5 +1,5 @@
 error: malformed `rustc_on_unimplemented` attribute input
-  --> $DIR/bad-annotation.rs:17:1
+  --> $DIR/bad-annotation.rs:15:1
    |
 LL | #[rustc_on_unimplemented]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -12,72 +12,120 @@ LL | #[rustc_on_unimplemented(/*opt*/ message = "...", /*opt*/ label = "...", /*
    |                         ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 error[E0230]: cannot find parameter C on this trait
-  --> $DIR/bad-annotation.rs:22:90
+  --> $DIR/bad-annotation.rs:19:90
    |
 LL | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"]
    |                                                                                          ^
 
 error[E0231]: positional format arguments are not allowed here
-  --> $DIR/bad-annotation.rs:27:90
+  --> $DIR/bad-annotation.rs:23:90
    |
 LL | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"]
    |                                                                                          ^
 
-error[E0232]: this attribute must have a valid value
-  --> $DIR/bad-annotation.rs:32:26
+error[E0232]: this attribute must have a value
+  --> $DIR/bad-annotation.rs:27:26
    |
-LL | #[rustc_on_unimplemented(lorem="")]
-   |                          ^^^^^^^^ expected value here
+LL | #[rustc_on_unimplemented(lorem = "")]
+   |                          ^^^^^^^^^^ expected value here
    |
-   = note: eg `#[rustc_on_unimplemented(message="foo")]`
+   = note: e.g. `#[rustc_on_unimplemented(message="foo")]`
 
-error[E0232]: this attribute must have a valid value
-  --> $DIR/bad-annotation.rs:36:26
+error[E0232]: this attribute must have a value
+  --> $DIR/bad-annotation.rs:33:26
    |
 LL | #[rustc_on_unimplemented(lorem(ipsum(dolor)))]
    |                          ^^^^^^^^^^^^^^^^^^^ expected value here
    |
-   = note: eg `#[rustc_on_unimplemented(message="foo")]`
+   = note: e.g. `#[rustc_on_unimplemented(message="foo")]`
 
-error[E0232]: this attribute must have a valid value
-  --> $DIR/bad-annotation.rs:40:39
+error[E0232]: this attribute must have a value
+  --> $DIR/bad-annotation.rs:39:41
    |
-LL | #[rustc_on_unimplemented(message="x", message="y")]
-   |                                       ^^^^^^^^^^^ expected value here
+LL | #[rustc_on_unimplemented(message = "x", message = "y")]
+   |                                         ^^^^^^^^^^^^^ expected value here
    |
-   = note: eg `#[rustc_on_unimplemented(message="foo")]`
+   = note: e.g. `#[rustc_on_unimplemented(message="foo")]`
 
-error[E0232]: this attribute must have a valid value
-  --> $DIR/bad-annotation.rs:44:39
+error[E0232]: this attribute must have a value
+  --> $DIR/bad-annotation.rs:45:41
    |
-LL | #[rustc_on_unimplemented(message="x", on(desugared, message="y"))]
-   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here
+LL | #[rustc_on_unimplemented(message = "x", on(desugared, message = "y"))]
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here
    |
-   = note: eg `#[rustc_on_unimplemented(message="foo")]`
+   = note: e.g. `#[rustc_on_unimplemented(message="foo")]`
 
 error[E0232]: empty `on`-clause in `#[rustc_on_unimplemented]`
-  --> $DIR/bad-annotation.rs:48:26
+  --> $DIR/bad-annotation.rs:51:26
+   |
+LL | #[rustc_on_unimplemented(on(), message = "y")]
+   |                          ^^^^ empty `on`-clause here
+
+error[E0232]: this attribute must have a value
+  --> $DIR/bad-annotation.rs:56:26
+   |
+LL | #[rustc_on_unimplemented(on = "x", message = "y")]
+   |                          ^^^^^^^^ expected value here
+   |
+   = note: e.g. `#[rustc_on_unimplemented(message="foo")]`
+
+error[E0232]: this attribute must have a value
+  --> $DIR/bad-annotation.rs:65:46
+   |
+LL | #[rustc_on_unimplemented(on(from_desugaring, on(from_desugaring, message = "x")), message = "y")]
+   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here
+   |
+   = note: e.g. `#[rustc_on_unimplemented(message="foo")]`
+
+error[E0232]: literals inside `on`-clauses are not supported
+  --> $DIR/bad-annotation.rs:71:29
    |
-LL | #[rustc_on_unimplemented(on(), message="y")]
-   |                          ^^^^ empty on-clause here
+LL | #[rustc_on_unimplemented(on("y", message = "y"))]
+   |                             ^^^ unexpected literal here
 
-error[E0232]: this attribute must have a valid value
-  --> $DIR/bad-annotation.rs:52:26
+error[E0232]: literals inside `on`-clauses are not supported
+  --> $DIR/bad-annotation.rs:76:29
    |
-LL | #[rustc_on_unimplemented(on="x", message="y")]
-   |                          ^^^^^^ expected value here
+LL | #[rustc_on_unimplemented(on(42, message = "y"))]
+   |                             ^^ unexpected literal here
+
+error[E0232]: expected a single predicate in `not(..)`
+  --> $DIR/bad-annotation.rs:81:33
    |
-   = note: eg `#[rustc_on_unimplemented(message="foo")]`
+LL | #[rustc_on_unimplemented(on(not(a, b), message = "y"))]
+   |                                 ^^^^ unexpected quantity of predicates here
 
-error[E0232]: this attribute must have a valid value
-  --> $DIR/bad-annotation.rs:59:40
+error[E0232]: expected a single predicate in `not(..)`
+  --> $DIR/bad-annotation.rs:86:29
    |
-LL | #[rustc_on_unimplemented(on(desugared, on(desugared, message="x")), message="y")]
-   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here
+LL | #[rustc_on_unimplemented(on(not(), message = "y"))]
+   |                             ^^^^^ unexpected quantity of predicates here
+
+error[E0232]: expected an identifier inside this `on`-clause
+  --> $DIR/bad-annotation.rs:91:29
+   |
+LL | #[rustc_on_unimplemented(on(thing::What, message = "y"))]
+   |                             ^^^^^^^^^^^ expected an identifier here, not `thing::What`
+
+error[E0232]: expected an identifier inside this `on`-clause
+  --> $DIR/bad-annotation.rs:96:29
+   |
+LL | #[rustc_on_unimplemented(on(thing::What = "value", message = "y"))]
+   |                             ^^^^^^^^^^^ expected an identifier here, not `thing::What`
+
+error[E0232]: this predicate is invalid
+  --> $DIR/bad-annotation.rs:101:29
+   |
+LL | #[rustc_on_unimplemented(on(aaaaaaaaaaaaaa(a, b), message = "y"))]
+   |                             ^^^^^^^^^^^^^^ expected one of `any`, `all` or `not` here, not `aaaaaaaaaaaaaa`
+
+error[E0232]: invalid flag in `on`-clause
+  --> $DIR/bad-annotation.rs:106:29
    |
-   = note: eg `#[rustc_on_unimplemented(message="foo")]`
+LL | #[rustc_on_unimplemented(on(something, message = "y"))]
+   |                             ^^^^^^^^^ expected one of the `crate_local`, `direct` or `from_desugaring` flags, not `something`
 
-error: aborting due to 10 previous errors
+error: aborting due to 18 previous errors
 
 Some errors have detailed explanations: E0230, E0231, E0232.
 For more information about an error, try `rustc --explain E0230`.
diff --git a/tests/ui/panic-runtime/two-panic-runtimes.rs b/tests/ui/panic-runtime/two-panic-runtimes.rs
index 80591edd107..de76578a267 100644
--- a/tests/ui/panic-runtime/two-panic-runtimes.rs
+++ b/tests/ui/panic-runtime/two-panic-runtimes.rs
@@ -1,11 +1,19 @@
 // ignore-tidy-linelength
 //@ build-fail
-//@ dont-require-annotations: ERROR
 //@ dont-check-compiler-stderr
 //@ aux-build:panic-runtime-unwind.rs
 //@ aux-build:panic-runtime-unwind2.rs
 //@ aux-build:panic-runtime-lang-items.rs
 
+// NOTE: there can be additional errors regarding trying to mix this crate if the precompiled target
+// (such as `wasm32-unknown-unknown` currently unconditionally defaulting to panic=abort) panic
+// strategy differs to abort, then involving a potentially-unwinding `panic_runtime_unwind` that
+// uses a different panic strategy. These errors are important but not to the test intention, which
+// is to check that trying to bring two panic runtimes (`panic_runtime_unwind`) and
+// (`panic_runtime_unwind2`) is prohibited. As such, the additional errors are not checked in this
+// test.
+//@ dont-require-annotations: ERROR
+
 #![no_std]
 #![no_main]
 
@@ -16,7 +24,3 @@ extern crate panic_runtime_lang_items;
 fn main() {}
 
 //~? ERROR cannot link together two panic runtimes: panic_runtime_unwind and panic_runtime_unwind2
-// FIXME: These errors are target-dependent, could be served by some "optional error" annotation
-// instead of `dont-require-annotations`.
-//FIXME~? ERROR the linked panic runtime `panic_runtime_unwind2` is not compiled with this crate's panic strategy `abort`
-//FIXME~? ERROR the crate `panic_runtime_unwind` requires panic strategy `unwind` which is incompatible with this crate's strategy of `abort`
diff --git a/tests/ui/panic-runtime/want-abort-got-unwind.rs b/tests/ui/panic-runtime/want-abort-got-unwind.rs
index 42cdf8bc662..7a6bd011d9e 100644
--- a/tests/ui/panic-runtime/want-abort-got-unwind.rs
+++ b/tests/ui/panic-runtime/want-abort-got-unwind.rs
@@ -1,16 +1,18 @@
 // ignore-tidy-linelength
 //@ build-fail
-//@ dont-require-annotations: ERROR
 //@ dont-check-compiler-stderr
 //@ aux-build:panic-runtime-unwind.rs
 //@ compile-flags:-C panic=abort
 
+// NOTE: depending on the target's default panic strategy, there can be additional errors that
+// complain about linking two panic runtimes (e.g. precompiled `panic_unwind` if target default
+// panic strategy is unwind, in addition to `panic_runtime_unwind`). These additional errors will
+// not be observed on targets whose default panic strategy is abort, where `panic_abort` is linked
+// in instead.
+//@ dont-require-annotations: ERROR
+
 extern crate panic_runtime_unwind;
 
 fn main() {}
 
 //~? ERROR the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort`
-// FIXME: These errors are target-dependent, could be served by some "optional error" annotation
-// instead of `dont-require-annotations`.
-//FIXME~? ERROR cannot link together two panic runtimes: panic_unwind and panic_runtime_unwind
-//FIXME~? ERROR the crate `panic_unwind` requires panic strategy `unwind` which is incompatible with this crate's strategy of `abort`
diff --git a/tests/ui/panic-runtime/want-abort-got-unwind2.rs b/tests/ui/panic-runtime/want-abort-got-unwind2.rs
index ddf12cd2a9a..da239a675e5 100644
--- a/tests/ui/panic-runtime/want-abort-got-unwind2.rs
+++ b/tests/ui/panic-runtime/want-abort-got-unwind2.rs
@@ -1,17 +1,23 @@
 // ignore-tidy-linelength
 //@ build-fail
-//@ dont-require-annotations: ERROR
 //@ dont-check-compiler-stderr
 //@ aux-build:panic-runtime-unwind.rs
 //@ aux-build:wants-panic-runtime-unwind.rs
 //@ compile-flags:-C panic=abort
 
+// Like `want-abort-got-unwind.rs`, this version checks that if the root binary wants abort panic
+// runtime, that the compiler rejects a setup where a dependency crate in the dependency DAG
+// transitively provides an unwind panic runtime (which also is built with `-Cpanic=unwind`, making
+// that potentially-unwinding).
+
+// NOTE: similar to `want-abort-got-unwind.rs`, there can be additional errors if the target default
+// panic strategy is unwind, because then the precompiled `panic_unwind` would also be linked in,
+// duplicating `panic_runtime_unwind` (transitively). But those additional errors are not important
+// to test intention.
+//@ dont-require-annotations: ERROR
+
 extern crate wants_panic_runtime_unwind;
 
 fn main() {}
 
 //~? ERROR the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort`
-// FIXME: These errors are target-dependent, could be served by some "optional error" annotation
-// instead of `dont-require-annotations`.
-//FIXME~? ERROR cannot link together two panic runtimes: panic_unwind and panic_runtime_unwind
-//FIXME~? ERROR the crate `panic_unwind` requires panic strategy `unwind` which is incompatible with this crate's strategy of `abort`
diff --git a/tests/ui/panics/default-backtrace-ice.rs b/tests/ui/panics/default-backtrace-ice.rs
index cf8b0cea849..e919e1a4ea6 100644
--- a/tests/ui/panics/default-backtrace-ice.rs
+++ b/tests/ui/panics/default-backtrace-ice.rs
@@ -1,8 +1,5 @@
 //@ unset-rustc-env:RUST_BACKTRACE
 //@ compile-flags:-Z treat-err-as-bug=1
-//@ error-pattern:stack backtrace:
-// Verify this is a full backtrace, not a short backtrace.
-//@ error-pattern:__rust_begin_short_backtrace
 //@ failure-status:101
 //@ ignore-msvc
 //@ normalize-stderr: "note: .*" -> ""
@@ -21,3 +18,7 @@
 // aren't reliable.
 
 fn main() { missing_ident; } //~ ERROR cannot find value `missing_ident` in this scope
+
+//~? RAW stack backtrace:
+// Verify this is a full backtrace, not a short backtrace.
+//~? RAW __rust_begin_short_backtrace
diff --git a/tests/ui/panics/default-backtrace-ice.stderr b/tests/ui/panics/default-backtrace-ice.stderr
index 2147b0971b5..a7d99e325d9 100644
--- a/tests/ui/panics/default-backtrace-ice.stderr
+++ b/tests/ui/panics/default-backtrace-ice.stderr
@@ -1,5 +1,5 @@
 error: internal compiler error[E0425]: cannot find value `missing_ident` in this scope
-  --> $DIR/default-backtrace-ice.rs:23:13
+  --> $DIR/default-backtrace-ice.rs:20:13
    |
 LL | fn main() { missing_ident; }
    |             ^^^^^^^^^^^^^ not found in this scope
diff --git a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs
index 6bfe16ae37d..db25ce44089 100644
--- a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs
+++ b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs
@@ -2,8 +2,10 @@
 
 fn main() {
     unsafe {
-        dealloc(ptr2, Layout::(x: !)(1, 1)); //~ ERROR: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
-        //~^ ERROR: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
-        //~| NOTE while parsing this parenthesized list of type arguments starting here
+        dealloc(ptr2, Layout::(x: !)(1, 1)); //~ ERROR `Trait(...)` syntax does not support named parameters
+        //~^ ERROR cannot find function `dealloc` in this scope [E0425]
+        //~| ERROR cannot find value `ptr2` in this scope [E0425]
+        //~| ERROR the `!` type is experimental [E0658]
+        //~| ERROR cannot find function, tuple struct or tuple variant `Layout` in this scope [E0425]
     }
 }
diff --git a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr
index c12bf7f9e3f..a083883af21 100644
--- a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr
+++ b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr
@@ -1,16 +1,43 @@
-error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:`
-  --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:33
+error: `Trait(...)` syntax does not support named parameters
+  --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:32
    |
 LL |         dealloc(ptr2, Layout::(x: !)(1, 1));
-   |                             --- ^ expected one of 7 possible tokens
-   |                             |
-   |                             while parsing this parenthesized list of type arguments starting here
+   |                                ^ help: remove the parameter name
 
-error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
-  --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:43
+error[E0425]: cannot find function `dealloc` in this scope
+  --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:9
    |
 LL |         dealloc(ptr2, Layout::(x: !)(1, 1));
-   |                                           ^ expected one of `.`, `;`, `?`, `}`, or an operator
+   |         ^^^^^^^ not found in this scope
+   |
+help: consider importing this function
+   |
+LL + use std::alloc::dealloc;
+   |
+
+error[E0425]: cannot find value `ptr2` in this scope
+  --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:17
+   |
+LL |         dealloc(ptr2, Layout::(x: !)(1, 1));
+   |                 ^^^^ not found in this scope
+
+error[E0658]: the `!` type is experimental
+  --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:35
+   |
+LL |         dealloc(ptr2, Layout::(x: !)(1, 1));
+   |                                   ^
+   |
+   = note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
+   = help: add `#![feature(never_type)]` 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[E0425]: cannot find function, tuple struct or tuple variant `Layout` in this scope
+  --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:23
+   |
+LL |         dealloc(ptr2, Layout::(x: !)(1, 1));
+   |                       ^^^^^^ not found in this scope
 
-error: aborting due to 2 previous errors
+error: aborting due to 5 previous errors
 
+Some errors have detailed explanations: E0425, E0658.
+For more information about an error, try `rustc --explain E0425`.
diff --git a/tests/ui/parser/fn-arg-doc-comment.rs b/tests/ui/parser/fn-arg-doc-comment.rs
index 21d753ad037..57a4d15fa25 100644
--- a/tests/ui/parser/fn-arg-doc-comment.rs
+++ b/tests/ui/parser/fn-arg-doc-comment.rs
@@ -2,12 +2,10 @@ pub fn f( //~ NOTE function defined here
     /// Comment
     //~^ ERROR documentation comments cannot be applied to function parameters
     //~| NOTE doc comments are not allowed here
-    //~| NOTE
     id: u8,
     /// Other
     //~^ ERROR documentation comments cannot be applied to function parameters
     //~| NOTE doc comments are not allowed here
-    //~| NOTE
     a: u8,
 ) {}
 
@@ -15,7 +13,6 @@ fn bar(id: #[allow(dead_code)] i32) {}
 //~^ ERROR attributes cannot be applied to a function parameter's type
 //~| NOTE attributes are not allowed here
 //~| NOTE function defined here
-//~| NOTE
 
 fn main() {
     // verify that the parser recovered and properly typechecked the args
diff --git a/tests/ui/parser/fn-arg-doc-comment.stderr b/tests/ui/parser/fn-arg-doc-comment.stderr
index 1891c708903..84c8bb3c2d0 100644
--- a/tests/ui/parser/fn-arg-doc-comment.stderr
+++ b/tests/ui/parser/fn-arg-doc-comment.stderr
@@ -1,5 +1,5 @@
 error: attributes cannot be applied to a function parameter's type
-  --> $DIR/fn-arg-doc-comment.rs:14:12
+  --> $DIR/fn-arg-doc-comment.rs:12:12
    |
 LL | fn bar(id: #[allow(dead_code)] i32) {}
    |            ^^^^^^^^^^^^^^^^^^^ attributes are not allowed here
@@ -11,13 +11,13 @@ LL |     /// Comment
    |     ^^^^^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/fn-arg-doc-comment.rs:7:5
+  --> $DIR/fn-arg-doc-comment.rs:6:5
    |
 LL |     /// Other
    |     ^^^^^^^^^ doc comments are not allowed here
 
 error[E0308]: arguments to this function are incorrect
-  --> $DIR/fn-arg-doc-comment.rs:22:5
+  --> $DIR/fn-arg-doc-comment.rs:19:5
    |
 LL |     f("", "");
    |     ^ --  -- expected `u8`, found `&str`
@@ -39,7 +39,7 @@ LL | |     a: u8,
    | |_________-
 
 error[E0308]: mismatched types
-  --> $DIR/fn-arg-doc-comment.rs:26:9
+  --> $DIR/fn-arg-doc-comment.rs:23:9
    |
 LL |     bar("");
    |     --- ^^ expected `i32`, found `&str`
@@ -47,7 +47,7 @@ LL |     bar("");
    |     arguments to this function are incorrect
    |
 note: function defined here
-  --> $DIR/fn-arg-doc-comment.rs:14:4
+  --> $DIR/fn-arg-doc-comment.rs:12:4
    |
 LL | fn bar(id: #[allow(dead_code)] i32) {}
    |    ^^^ ---------------------------
diff --git a/tests/ui/parser/issues/invalid-parse-format-issue-139104.rs b/tests/ui/parser/issues/invalid-parse-format-issue-139104.rs
new file mode 100644
index 00000000000..7644df8be49
--- /dev/null
+++ b/tests/ui/parser/issues/invalid-parse-format-issue-139104.rs
@@ -0,0 +1,13 @@
+fn main() {
+    println!("{foo:_1.4}", foo = 3.14); //~ ERROR invalid format string: expected `}`, found `.`
+    println!("{0:_1.4}", 1.11); //~ ERROR invalid format string: expected `}`, found `.`
+    println!("{:_1.4}", 3.14); //~ ERROR invalid format string: expected `}`, found `.`
+
+    println!("{foo:_1.4", foo = 3.14); //~ ERROR invalid format string: expected `}`, found `.`
+    println!("{0:_1.4", 1.11); //~ ERROR invalid format string: expected `}`, found `.`
+    println!("{:_1.4", 3.14); //~ ERROR invalid format string: expected `}`, found `.`
+
+    println!("{  0", 1.11); //~ ERROR invalid format string: expected `}`, found `0`
+    println!("{foo:1.4_1.4}", foo = 3.14); //~ ERROR invalid format string: expected `}`, found `.`
+    println!("{0:1.4_1.4}", 3.14); //~ ERROR invalid format string: expected `}`, found `.`
+}
diff --git a/tests/ui/parser/issues/invalid-parse-format-issue-139104.stderr b/tests/ui/parser/issues/invalid-parse-format-issue-139104.stderr
new file mode 100644
index 00000000000..202aa450cab
--- /dev/null
+++ b/tests/ui/parser/issues/invalid-parse-format-issue-139104.stderr
@@ -0,0 +1,92 @@
+error: invalid format string: expected `}`, found `.`
+  --> $DIR/invalid-parse-format-issue-139104.rs:2:22
+   |
+LL |     println!("{foo:_1.4}", foo = 3.14);
+   |               -      ^ expected `}` in format string
+   |               |
+   |               because of this opening brace
+   |
+   = note: if you intended to print `{`, you can escape it using `{{`
+
+error: invalid format string: expected `}`, found `.`
+  --> $DIR/invalid-parse-format-issue-139104.rs:3:20
+   |
+LL |     println!("{0:_1.4}", 1.11);
+   |               -    ^ expected `}` in format string
+   |               |
+   |               because of this opening brace
+   |
+   = note: if you intended to print `{`, you can escape it using `{{`
+
+error: invalid format string: expected `}`, found `.`
+  --> $DIR/invalid-parse-format-issue-139104.rs:4:19
+   |
+LL |     println!("{:_1.4}", 3.14);
+   |               -   ^ expected `}` in format string
+   |               |
+   |               because of this opening brace
+   |
+   = note: if you intended to print `{`, you can escape it using `{{`
+
+error: invalid format string: expected `}`, found `.`
+  --> $DIR/invalid-parse-format-issue-139104.rs:6:22
+   |
+LL |     println!("{foo:_1.4", foo = 3.14);
+   |               -      ^ expected `}` in format string
+   |               |
+   |               because of this opening brace
+   |
+   = note: if you intended to print `{`, you can escape it using `{{`
+
+error: invalid format string: expected `}`, found `.`
+  --> $DIR/invalid-parse-format-issue-139104.rs:7:20
+   |
+LL |     println!("{0:_1.4", 1.11);
+   |               -    ^ expected `}` in format string
+   |               |
+   |               because of this opening brace
+   |
+   = note: if you intended to print `{`, you can escape it using `{{`
+
+error: invalid format string: expected `}`, found `.`
+  --> $DIR/invalid-parse-format-issue-139104.rs:8:19
+   |
+LL |     println!("{:_1.4", 3.14);
+   |               -   ^ expected `}` in format string
+   |               |
+   |               because of this opening brace
+   |
+   = note: if you intended to print `{`, you can escape it using `{{`
+
+error: invalid format string: expected `}`, found `0`
+  --> $DIR/invalid-parse-format-issue-139104.rs:10:18
+   |
+LL |     println!("{  0", 1.11);
+   |               -  ^ expected `}` in format string
+   |               |
+   |               because of this opening brace
+   |
+   = note: if you intended to print `{`, you can escape it using `{{`
+
+error: invalid format string: expected `}`, found `.`
+  --> $DIR/invalid-parse-format-issue-139104.rs:11:25
+   |
+LL |     println!("{foo:1.4_1.4}", foo = 3.14);
+   |               -         ^ expected `}` in format string
+   |               |
+   |               because of this opening brace
+   |
+   = note: if you intended to print `{`, you can escape it using `{{`
+
+error: invalid format string: expected `}`, found `.`
+  --> $DIR/invalid-parse-format-issue-139104.rs:12:23
+   |
+LL |     println!("{0:1.4_1.4}", 3.14);
+   |               -       ^ expected `}` in format string
+   |               |
+   |               because of this opening brace
+   |
+   = note: if you intended to print `{`, you can escape it using `{{`
+
+error: aborting due to 9 previous errors
+
diff --git a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs
index 1c28c0632fa..60dd88e6540 100644
--- a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs
+++ b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs
@@ -2,7 +2,4 @@
 
 struct Apple((Apple, Option(Banana ? Citron)));
 //~^ ERROR invalid `?` in type
-//~| ERROR expected one of `)` or `,`, found `Citron`
-//~| ERROR cannot find type `Citron` in this scope [E0412]
-//~| ERROR parenthesized type parameters may only be used with a `Fn` trait [E0214]
-//~| ERROR `Apple` has infinite size
+//~| ERROR unexpected token: `Citron`
diff --git a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr
index 97a73b4fd5e..c92535c3906 100644
--- a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr
+++ b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr
@@ -10,44 +10,11 @@ LL - struct Apple((Apple, Option(Banana ? Citron)));
 LL + struct Apple((Apple, Option(Option<Banana > Citron)));
    |
 
-error: expected one of `)` or `,`, found `Citron`
+error: unexpected token: `Citron`
   --> $DIR/issue-103748-ICE-wrong-braces.rs:3:38
    |
 LL | struct Apple((Apple, Option(Banana ? Citron)));
-   |                                     -^^^^^^ expected one of `)` or `,`
-   |                                     |
-   |                                     help: missing `,`
+   |                                      ^^^^^^ unexpected token after this
 
-error[E0412]: cannot find type `Citron` in this scope
-  --> $DIR/issue-103748-ICE-wrong-braces.rs:3:38
-   |
-LL | struct Apple((Apple, Option(Banana ? Citron)));
-   |                                      ^^^^^^ not found in this scope
-
-error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-103748-ICE-wrong-braces.rs:3:22
-   |
-LL | struct Apple((Apple, Option(Banana ? Citron)));
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses
-   |
-help: use angle brackets instead
-   |
-LL - struct Apple((Apple, Option(Banana ? Citron)));
-LL + struct Apple((Apple, Option<Banana ? Citron>));
-   |
-
-error[E0072]: recursive type `Apple` has infinite size
-  --> $DIR/issue-103748-ICE-wrong-braces.rs:3:1
-   |
-LL | struct Apple((Apple, Option(Banana ? Citron)));
-   | ^^^^^^^^^^^^  ----- recursive without indirection
-   |
-help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
-   |
-LL | struct Apple((Box<Apple>, Option(Banana ? Citron)));
-   |               ++++     +
-
-error: aborting due to 5 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0072, E0214, E0412.
-For more information about an error, try `rustc --explain E0072`.
diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs b/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs
index c137e136335..e6235b1e892 100644
--- a/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs
+++ b/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs
@@ -10,6 +10,5 @@ const async const fn test() {}
 //~| ERROR functions cannot be both `const` and `async`
 //~| NOTE `const` because of this
 //~| NOTE `async` because of this
-//~| NOTE
 
 fn main() {}
diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs b/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs
index 49a49d337c4..40f993eafbb 100644
--- a/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs
+++ b/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs
@@ -15,6 +15,5 @@ async unsafe const fn test() {}
 //~| ERROR functions cannot be both `const` and `async`
 //~| NOTE `const` because of this
 //~| NOTE `async` because of this
-//~| NOTE
 
 fn main() {}
diff --git a/tests/ui/auxiliary/issue-24106.rs b/tests/ui/pattern/auxiliary/cross-crate-enum-pattern.rs
index 2c6a6034806..2c6a6034806 100644
--- a/tests/ui/auxiliary/issue-24106.rs
+++ b/tests/ui/pattern/auxiliary/cross-crate-enum-pattern.rs
diff --git a/tests/ui/pattern/cross-crate-enum-pattern.rs b/tests/ui/pattern/cross-crate-enum-pattern.rs
new file mode 100644
index 00000000000..254caf99277
--- /dev/null
+++ b/tests/ui/pattern/cross-crate-enum-pattern.rs
@@ -0,0 +1,13 @@
+//! Test that we can match on enum constants across crates.
+//!
+//! Regression test for <https://github.com/rust-lang/rust/issues/24106>.
+
+
+//@ run-pass
+//@ aux-build:cross-crate-enum-pattern.rs
+
+extern crate cross_crate_enum_pattern;
+
+fn main() {
+    cross_crate_enum_pattern::go::<()>();
+}
diff --git a/tests/ui/pattern/deref-patterns/bindings.rs b/tests/ui/pattern/deref-patterns/bindings.rs
index ac48e3ffefc..92c01d737ba 100644
--- a/tests/ui/pattern/deref-patterns/bindings.rs
+++ b/tests/ui/pattern/deref-patterns/bindings.rs
@@ -13,7 +13,6 @@ fn simple_vec(vec: Vec<u32>) -> u32 {
         deref!([x]) => x,
         deref!([1, x]) => x + 200,
         deref!(ref slice) => slice.iter().sum(),
-        _ => 2000,
     }
 }
 
@@ -25,7 +24,6 @@ fn simple_vec(vec: Vec<u32>) -> u32 {
         [x] => x,
         [1, x] => x + 200,
         deref!(ref slice) => slice.iter().sum(),
-        _ => 2000,
     }
 }
 
diff --git a/tests/ui/pattern/deref-patterns/byte-string-type-errors.rs b/tests/ui/pattern/deref-patterns/byte-string-type-errors.rs
index 64acc4748af..fdcc6cb4611 100644
--- a/tests/ui/pattern/deref-patterns/byte-string-type-errors.rs
+++ b/tests/ui/pattern/deref-patterns/byte-string-type-errors.rs
@@ -33,4 +33,23 @@ fn main() {
     if let b"test" = *b"this array is too long" {}
     //~^ ERROR mismatched types
     //~| NOTE expected an array with a size of 22, found one with a size of 4
+
+    // Test matching on `&mut T`: we peel the `&mut` before applying the usual special cases.
+    // No special cases apply to `()`, so the "found" type is the type of the literal.
+    if let b"test" = &mut () {}
+    //~^ ERROR mismatched types
+    //~| NOTE expected `()`, found `&[u8; 4]`
+
+    // If the pointee is an array or slice, the usual special cases will apply to the "found" type:
+    if let b"test" = &mut [] as &mut [i8] {}
+    //~^ ERROR mismatched type
+    //~| NOTE expected `[i8]`, found `[u8]`
+
+    if let b"test" = &mut [()] {}
+    //~^ ERROR mismatched types
+    //~| NOTE expected `[(); 1]`, found `[u8; 4]`
+
+    if let b"test" = &mut *b"this array is too long" {}
+    //~^ ERROR mismatched type
+    //~| NOTE expected an array with a size of 22, found one with a size of 4
 }
diff --git a/tests/ui/pattern/deref-patterns/byte-string-type-errors.stderr b/tests/ui/pattern/deref-patterns/byte-string-type-errors.stderr
index 0317b7209e1..046682004be 100644
--- a/tests/ui/pattern/deref-patterns/byte-string-type-errors.stderr
+++ b/tests/ui/pattern/deref-patterns/byte-string-type-errors.stderr
@@ -47,6 +47,44 @@ LL |     if let b"test" = *b"this array is too long" {}
    |            |
    |            expected an array with a size of 22, found one with a size of 4
 
-error: aborting due to 5 previous errors
+error[E0308]: mismatched types
+  --> $DIR/byte-string-type-errors.rs:39:12
+   |
+LL |     if let b"test" = &mut () {}
+   |            ^^^^^^^   ------- this expression has type `&mut ()`
+   |            |
+   |            expected `()`, found `&[u8; 4]`
+
+error[E0308]: mismatched types
+  --> $DIR/byte-string-type-errors.rs:44:12
+   |
+LL |     if let b"test" = &mut [] as &mut [i8] {}
+   |            ^^^^^^^   -------------------- this expression has type `&mut [i8]`
+   |            |
+   |            expected `[i8]`, found `[u8]`
+   |
+   = note: expected slice `[i8]`
+              found slice `[u8]`
+
+error[E0308]: mismatched types
+  --> $DIR/byte-string-type-errors.rs:48:12
+   |
+LL |     if let b"test" = &mut [()] {}
+   |            ^^^^^^^   --------- this expression has type `&mut [(); 1]`
+   |            |
+   |            expected `[(); 1]`, found `[u8; 4]`
+   |
+   = note: expected array `[(); 1]`
+              found array `[u8; 4]`
+
+error[E0308]: mismatched types
+  --> $DIR/byte-string-type-errors.rs:52:12
+   |
+LL |     if let b"test" = &mut *b"this array is too long" {}
+   |            ^^^^^^^   ------------------------------- this expression has type `&mut [u8; 22]`
+   |            |
+   |            expected an array with a size of 22, found one with a size of 4
+
+error: aborting due to 9 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/pattern/deref-patterns/closure_capture.rs b/tests/ui/pattern/deref-patterns/closure_capture.rs
index cf78eeda1d5..497ec622b0c 100644
--- a/tests/ui/pattern/deref-patterns/closure_capture.rs
+++ b/tests/ui/pattern/deref-patterns/closure_capture.rs
@@ -9,7 +9,7 @@ struct NoCopy;
 fn main() {
     let b = Rc::new("aaa".to_string());
     let f = || {
-        let deref!(ref s) = b else { unreachable!() };
+        let deref!(ref s) = b;
         assert_eq!(s.len(), 3);
     };
     assert_eq!(b.len(), 3);
@@ -26,7 +26,7 @@ fn main() {
 
     let mut b = "aaa".to_string();
     let mut f = || {
-        let deref!(ref mut s) = b else { unreachable!() };
+        let deref!(ref mut s) = b;
         s.make_ascii_uppercase();
     };
     f();
@@ -53,7 +53,7 @@ fn main() {
     let b = Box::new(NoCopy);
     let f = || {
         // this should move out of the box rather than borrow.
-        let deref!(x) = b else { unreachable!() };
+        let deref!(x) = b;
         drop::<NoCopy>(x);
     };
     f();
@@ -61,7 +61,7 @@ fn main() {
     let b = Box::new((NoCopy,));
     let f = || {
         // this should move out of the box rather than borrow.
-        let (x,) = b else { unreachable!() };
+        let (x,) = b;
         drop::<NoCopy>(x);
     };
     f();
diff --git a/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.rs b/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.rs
new file mode 100644
index 00000000000..3a2531f4b95
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.rs
@@ -0,0 +1,54 @@
+//@ revisions: stable deref_patterns
+//@[deref_patterns] check-pass
+//! `deref_patterns` allows string and byte string literal patterns to implicitly peel references
+//! and smart pointers from the scrutinee before matching. Since strings and byte strings themselves
+//! have reference types, we need to make sure we don't peel too much. By leaving the type of the
+//! match scrutinee partially uninferred, these tests make sure we only peel as much as needed in
+//! order to match. In particular, when peeling isn't needed, the results should be the same was
+//! we'd get without `deref_patterns` enabled.
+
+#![cfg_attr(deref_patterns, feature(deref_patterns))]
+#![cfg_attr(deref_patterns, expect(incomplete_features))]
+
+fn uninferred<T>() -> T { unimplemented!() }
+
+// Assert type equality without allowing coercions.
+trait Is<T> {}
+impl<T> Is<T> for T {}
+fn has_type<T>(_: impl Is<T>) {}
+
+fn main() {
+    // We don't need to peel anything to unify the type of `x` with `&str`, so `x: &str`.
+    let x = uninferred();
+    if let "..." = x {}
+    has_type::<&str>(x);
+
+    // We don't need to peel anything to unify the type of `&x` with `&[u8; 3]`, so `x: [u8; 3]`.
+    let x = uninferred();
+    if let b"..." = &x {}
+    has_type::<[u8; 3]>(x);
+
+    // Peeling a single `&` lets us unify the type of `&x` with `&[u8; 3]`, giving `x: [u8; 3]`.
+    let x = uninferred();
+    if let b"..." = &&x {}
+    //[stable]~^ ERROR: mismatched types
+    has_type::<[u8; 3]>(x);
+
+    // We have to peel both the `&` and the box before unifying the type of `x` with `&str`.
+    let x = uninferred();
+    if let "..." = &Box::new(x) {}
+    //[stable]~^ ERROR mismatched types
+    has_type::<&str>(x);
+
+    // After peeling the box, we can unify the type of `&x` with `&[u8; 3]`, giving `x: [u8; 3]`.
+    let x = uninferred();
+    if let b"..." = Box::new(&x) {}
+    //[stable]~^ ERROR mismatched types
+    has_type::<[u8; 3]>(x);
+
+    // `&` and `&mut` aren't interchangeable: `&mut`s need to be peeled before unifying, like boxes:
+    let mut x = uninferred();
+    if let "..." = &mut x {}
+    //[stable]~^ ERROR mismatched types
+    has_type::<&str>(x);
+}
diff --git a/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.stable.stderr b/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.stable.stderr
new file mode 100644
index 00000000000..61079718c5d
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/const-pats-do-not-mislead-inference.stable.stderr
@@ -0,0 +1,55 @@
+error[E0308]: mismatched types
+  --> $DIR/const-pats-do-not-mislead-inference.rs:33:12
+   |
+LL |     if let b"..." = &&x {}
+   |            ^^^^^^   --- this expression has type `&&_`
+   |            |
+   |            expected `&&_`, found `&[u8; 3]`
+   |
+   = note: expected reference `&&_`
+              found reference `&'static [u8; 3]`
+
+error[E0308]: mismatched types
+  --> $DIR/const-pats-do-not-mislead-inference.rs:39:12
+   |
+LL |     if let "..." = &Box::new(x) {}
+   |            ^^^^^   ------------ this expression has type `&Box<_>`
+   |            |
+   |            expected `&Box<_>`, found `&str`
+   |
+   = note: expected reference `&Box<_>`
+              found reference `&'static str`
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |     if let "..." = &*Box::new(x) {}
+   |                     +
+
+error[E0308]: mismatched types
+  --> $DIR/const-pats-do-not-mislead-inference.rs:45:12
+   |
+LL |     if let b"..." = Box::new(&x) {}
+   |            ^^^^^^   ------------ this expression has type `Box<&_>`
+   |            |
+   |            expected `Box<&_>`, found `&[u8; 3]`
+   |
+   = note: expected struct `Box<&_>`
+           found reference `&'static [u8; 3]`
+help: consider dereferencing to access the inner value using the Deref trait
+   |
+LL |     if let b"..." = *Box::new(&x) {}
+   |                     +
+
+error[E0308]: mismatched types
+  --> $DIR/const-pats-do-not-mislead-inference.rs:51:12
+   |
+LL |     if let "..." = &mut x {}
+   |            ^^^^^   ------ this expression has type `&mut _`
+   |            |
+   |            types differ in mutability
+   |
+   = note: expected mutable reference `&mut _`
+                      found reference `&'static str`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/pattern/deref-patterns/deref-box.rs b/tests/ui/pattern/deref-patterns/deref-box.rs
index 2d0a8d01972..39b23dcab51 100644
--- a/tests/ui/pattern/deref-patterns/deref-box.rs
+++ b/tests/ui/pattern/deref-patterns/deref-box.rs
@@ -6,18 +6,18 @@
 #![expect(incomplete_features)]
 
 fn unbox_1<T>(b: Box<T>) -> T {
-    let deref!(x) = b else { unreachable!() };
+    let deref!(x) = b;
     x
 }
 
 fn unbox_2<T>(b: Box<(T,)>) -> T {
-    let (x,) = b else { unreachable!() };
+    let (x,) = b;
     x
 }
 
 fn unbox_separately<T>(b: Box<(T, T)>) -> (T, T) {
-    let (x, _) = b else { unreachable!() };
-    let (_, y) = b else { unreachable!() };
+    let (x, _) = b;
+    let (_, y) = b;
     (x, y)
 }
 
@@ -31,7 +31,7 @@ fn main() {
 
     // test that borrowing from a box also works
     let mut b = "hi".to_owned().into_boxed_str();
-    let deref!(ref mut s) = b else { unreachable!() };
+    let deref!(ref mut s) = b;
     s.make_ascii_uppercase();
     assert_eq!(&*b, "HI");
 }
diff --git a/tests/ui/pattern/deref-patterns/implicit-cow-deref.rs b/tests/ui/pattern/deref-patterns/implicit-cow-deref.rs
index 04c83d4c33f..24770261edc 100644
--- a/tests/ui/pattern/deref-patterns/implicit-cow-deref.rs
+++ b/tests/ui/pattern/deref-patterns/implicit-cow-deref.rs
@@ -11,7 +11,6 @@ fn main() {
 
     match cow {
         [..] => {}
-        _ => unreachable!(),
     }
 
     match cow {
@@ -22,14 +21,12 @@ fn main() {
     match Rc::new(&cow) {
         Cow::Borrowed { 0: _ } => {}
         Cow::Owned { 0: _ } => unreachable!(),
-        _ => unreachable!(),
     }
 
     let cow_of_cow: Cow<'_, Cow<'static, [u8]>> = Cow::Owned(cow);
 
     match cow_of_cow {
         [..] => {}
-        _ => unreachable!(),
     }
 
     // This matches on the outer `Cow` (the owned one).
@@ -41,6 +38,5 @@ fn main() {
     match Rc::new(&cow_of_cow) {
         Cow::Borrowed { 0: _ } => unreachable!(),
         Cow::Owned { 0: _ } => {}
-        _ => unreachable!(),
     }
 }
diff --git a/tests/ui/pattern/deref-patterns/needs-gate.rs b/tests/ui/pattern/deref-patterns/needs-gate.rs
index 7944744ee83..953051f7b04 100644
--- a/tests/ui/pattern/deref-patterns/needs-gate.rs
+++ b/tests/ui/pattern/deref-patterns/needs-gate.rs
@@ -29,4 +29,30 @@ fn main() {
         //~^ ERROR: mismatched types
         _ => {}
     }
+
+    // `deref_patterns` allows string and byte string patterns to implicitly peel references.
+    match &"str" {
+        "str" => {}
+        //~^ ERROR: mismatched types
+        _ => {}
+    }
+    match &b"str" {
+        b"str" => {}
+        //~^ ERROR: mismatched types
+        _ => {}
+    }
+    match "str".to_owned() {
+        "str" => {}
+        //~^ ERROR: mismatched types
+        _ => {}
+    }
+
+    // `deref_patterns` allows string and byte string patterns to match on mutable references.
+    // See also `tests/ui/pattern/byte-string-mutability-mismatch.rs`.
+    if let "str" = &mut *"str".to_string() {}
+    //~^ ERROR mismatched types
+    if let b"str" = &mut b"str".clone() {}
+    //~^ ERROR mismatched types
+    if let b"str" = &mut b"str".clone()[..] {}
+    //~^ ERROR mismatched types
 }
diff --git a/tests/ui/pattern/deref-patterns/needs-gate.stderr b/tests/ui/pattern/deref-patterns/needs-gate.stderr
index e886ca98055..3d938a7e23f 100644
--- a/tests/ui/pattern/deref-patterns/needs-gate.stderr
+++ b/tests/ui/pattern/deref-patterns/needs-gate.stderr
@@ -47,7 +47,70 @@ LL |     match *(b"test" as &[u8]) {
 LL |         b"test" => {}
    |         ^^^^^^^ expected `[u8]`, found `&[u8; 4]`
 
-error: aborting due to 5 previous errors
+error[E0308]: mismatched types
+  --> $DIR/needs-gate.rs:35:9
+   |
+LL |     match &"str" {
+   |           ------ this expression has type `&&str`
+LL |         "str" => {}
+   |         ^^^^^ expected `&&str`, found `&str`
+   |
+   = note: expected reference `&&_`
+              found reference `&'static _`
+
+error[E0308]: mismatched types
+  --> $DIR/needs-gate.rs:40:9
+   |
+LL |     match &b"str" {
+   |           ------- this expression has type `&&[u8; 3]`
+LL |         b"str" => {}
+   |         ^^^^^^ expected `&&[u8; 3]`, found `&[u8; 3]`
+   |
+   = note: expected reference `&&_`
+              found reference `&'static _`
+
+error[E0308]: mismatched types
+  --> $DIR/needs-gate.rs:45:9
+   |
+LL |     match "str".to_owned() {
+   |           ---------------- this expression has type `String`
+LL |         "str" => {}
+   |         ^^^^^ expected `String`, found `&str`
+
+error[E0308]: mismatched types
+  --> $DIR/needs-gate.rs:52:12
+   |
+LL |     if let "str" = &mut *"str".to_string() {}
+   |            ^^^^^   ----------------------- this expression has type `&mut str`
+   |            |
+   |            types differ in mutability
+   |
+   = note: expected mutable reference `&mut _`
+                      found reference `&'static _`
+
+error[E0308]: mismatched types
+  --> $DIR/needs-gate.rs:54:12
+   |
+LL |     if let b"str" = &mut b"str".clone() {}
+   |            ^^^^^^   ------------------- this expression has type `&mut [u8; 3]`
+   |            |
+   |            types differ in mutability
+   |
+   = note: expected mutable reference `&mut _`
+                      found reference `&'static _`
+
+error[E0308]: mismatched types
+  --> $DIR/needs-gate.rs:56:12
+   |
+LL |     if let b"str" = &mut b"str".clone()[..] {}
+   |            ^^^^^^   ----------------------- this expression has type `&mut [u8]`
+   |            |
+   |            types differ in mutability
+   |
+   = note: expected mutable reference `&mut _`
+                      found reference `&'static _`
+
+error: aborting due to 11 previous errors
 
 Some errors have detailed explanations: E0308, E0658.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/pattern/deref-patterns/strings.rs b/tests/ui/pattern/deref-patterns/strings.rs
index 536e943b3f6..fac15a9aee3 100644
--- a/tests/ui/pattern/deref-patterns/strings.rs
+++ b/tests/ui/pattern/deref-patterns/strings.rs
@@ -14,10 +14,26 @@ fn main() {
         };
         assert_eq!(test_actual, test_expect);
 
-        // Test string literals in explicit `deref!(_)` patterns.
+        // Test matching on `&mut str`.
+        let test_actual = match &mut *test_in.to_string() {
+            "zero" => 0,
+            "one" => 1,
+            _ => 2,
+        };
+        assert_eq!(test_actual, test_expect);
+
+        // Test string literals in deref patterns.
         let test_actual = match test_in.to_string() {
             deref!("zero") => 0,
-            deref!("one") => 1,
+            "one" => 1,
+            _ => 2,
+        };
+        assert_eq!(test_actual, test_expect);
+
+        // Test peeling references in addition to smart pointers.
+        let test_actual = match &test_in.to_string() {
+            deref!("zero") => 0,
+            "one" => 1,
             _ => 2,
         };
         assert_eq!(test_actual, test_expect);
@@ -47,18 +63,34 @@ fn main() {
         };
         assert_eq!(test_actual, test_expect);
 
-        // Test byte string literals used as arrays in explicit `deref!(_)` patterns.
+        // Test matching on `&mut [u8; N]`.
+        let test_actual = match &mut test_in.clone() {
+            b"0" => 0,
+            b"1" => 1,
+            _ => 2,
+        };
+        assert_eq!(test_actual, test_expect);
+
+        // Test matching on `&mut [u8]`.
+        let test_actual = match &mut test_in.clone()[..] {
+            b"0" => 0,
+            b"1" => 1,
+            _ => 2,
+        };
+        assert_eq!(test_actual, test_expect);
+
+        // Test byte string literals used as arrays in deref patterns.
         let test_actual = match Box::new(*test_in) {
             deref!(b"0") => 0,
-            deref!(b"1") => 1,
+            b"1" => 1,
             _ => 2,
         };
         assert_eq!(test_actual, test_expect);
 
-        // Test byte string literals used as slices in explicit `deref!(_)` patterns.
+        // Test byte string literals used as slices in deref patterns.
         let test_actual = match test_in.to_vec() {
             deref!(b"0") => 0,
-            deref!(b"1") => 1,
+            b"1" => 1,
             _ => 2,
         };
         assert_eq!(test_actual, test_expect);
diff --git a/tests/ui/pattern/deref-patterns/typeck_fail.rs b/tests/ui/pattern/deref-patterns/typeck_fail.rs
index 52d84f7a34d..6ae87bb7bc3 100644
--- a/tests/ui/pattern/deref-patterns/typeck_fail.rs
+++ b/tests/ui/pattern/deref-patterns/typeck_fail.rs
@@ -2,19 +2,6 @@
 #![allow(incomplete_features)]
 
 fn main() {
-    // FIXME(deref_patterns): fails to typecheck because string literal patterns don't peel
-    // references from the scrutinee.
-    match "foo".to_string() {
-        "foo" => {}
-        //~^ ERROR: mismatched types
-        _ => {}
-    }
-    match &"foo".to_string() {
-        "foo" => {}
-        //~^ ERROR: mismatched types
-        _ => {}
-    }
-
     // Make sure we don't try implicitly dereferncing any ADT.
     match Some(0) {
         Ok(0) => {}
diff --git a/tests/ui/pattern/deref-patterns/typeck_fail.stderr b/tests/ui/pattern/deref-patterns/typeck_fail.stderr
index e87528c1c51..fc29caac563 100644
--- a/tests/ui/pattern/deref-patterns/typeck_fail.stderr
+++ b/tests/ui/pattern/deref-patterns/typeck_fail.stderr
@@ -1,24 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/typeck_fail.rs:8:9
-   |
-LL |     match "foo".to_string() {
-   |           ----------------- this expression has type `String`
-LL |         "foo" => {}
-   |         ^^^^^ expected `String`, found `&str`
-
-error[E0308]: mismatched types
-  --> $DIR/typeck_fail.rs:13:9
-   |
-LL |     match &"foo".to_string() {
-   |           ------------------ this expression has type `&String`
-LL |         "foo" => {}
-   |         ^^^^^ expected `&String`, found `&str`
-   |
-   = note: expected reference `&String`
-              found reference `&'static str`
-
-error[E0308]: mismatched types
-  --> $DIR/typeck_fail.rs:20:9
+  --> $DIR/typeck_fail.rs:7:9
    |
 LL |     match Some(0) {
    |           ------- this expression has type `Option<{integer}>`
@@ -28,6 +9,6 @@ LL |         Ok(0) => {}
    = note: expected enum `Option<{integer}>`
               found enum `Result<_, _>`
 
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/pattern/deref-patterns/usefulness/empty-types.rs b/tests/ui/pattern/deref-patterns/usefulness/empty-types.rs
new file mode 100644
index 00000000000..03419030e72
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/usefulness/empty-types.rs
@@ -0,0 +1,47 @@
+//! Test that the place behind a deref pattern is treated as maybe-invalid, and thus empty arms
+//! cannot be omitted. This is handled the same as for refs and union fields, so this leaves the
+//! bulk of the testing to `tests/ui/pattern/usefulness/empty-types.rs`.
+// FIXME(deref_patterns): On stabilization, cases for deref patterns could be worked into that file
+// to keep the tests for empty types in one place and test more thoroughly.
+#![feature(deref_patterns)]
+#![expect(incomplete_features)]
+#![deny(unreachable_patterns)]
+
+enum Void {}
+
+fn main() {
+    // Sanity check: matching on an empty type without pointer indirection lets us omit arms.
+    let opt_void: Option<Void> = None;
+    match opt_void {
+        None => {}
+    }
+
+    // But if we hide it behind a smart pointer, we need an arm.
+    let box_opt_void: Box<Option<Void>> = Box::new(None);
+    match box_opt_void {
+        //~^ ERROR non-exhaustive patterns: `deref!(Some(_))` not covered
+        None => {}
+    }
+    match box_opt_void {
+        None => {}
+        Some(_) => {}
+    }
+    match box_opt_void {
+        None => {}
+        _ => {}
+    }
+
+    // For consistency, this behaves the same as if we manually dereferenced the scrutinee.
+    match *box_opt_void {
+        //~^ ERROR non-exhaustive patterns: `Some(_)` not covered
+        None => {}
+    }
+    match *box_opt_void {
+        None => {}
+        Some(_) => {}
+    }
+    match *box_opt_void {
+        None => {}
+        _ => {}
+    }
+}
diff --git a/tests/ui/pattern/deref-patterns/usefulness/empty-types.stderr b/tests/ui/pattern/deref-patterns/usefulness/empty-types.stderr
new file mode 100644
index 00000000000..e3247708566
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/usefulness/empty-types.stderr
@@ -0,0 +1,38 @@
+error[E0004]: non-exhaustive patterns: `deref!(Some(_))` not covered
+  --> $DIR/empty-types.rs:21:11
+   |
+LL |     match box_opt_void {
+   |           ^^^^^^^^^^^^ pattern `deref!(Some(_))` not covered
+   |
+note: `Box<Option<Void>>` defined here
+  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+   = note: the matched value is of type `Box<Option<Void>>`
+   = note: `Void` is uninhabited but is not being matched by value, so a wildcard `_` is required
+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 ~         None => {},
+LL +         deref!(Some(_)) => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `Some(_)` not covered
+  --> $DIR/empty-types.rs:35:11
+   |
+LL |     match *box_opt_void {
+   |           ^^^^^^^^^^^^^ pattern `Some(_)` not covered
+   |
+note: `Option<Void>` defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+  ::: $SRC_DIR/core/src/option.rs:LL:COL
+   |
+   = note: not covered
+   = note: the matched value is of type `Option<Void>`
+   = note: `Void` is uninhabited but is not being matched by value, so a wildcard `_` is required
+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 ~         None => {},
+LL +         Some(_) => todo!()
+   |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.rs b/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.rs
new file mode 100644
index 00000000000..f567dc07bb5
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.rs
@@ -0,0 +1,48 @@
+//! Test matches with a mix of ADT constructors and deref patterns. Currently, usefulness analysis
+//! doesn't support this, so make sure we catch it beforehand. As a consequence, it takes priority
+//! over non-exhaustive match and unreachable pattern errors.
+#![feature(deref_patterns)]
+#![expect(incomplete_features)]
+#![deny(unreachable_patterns)]
+
+use std::borrow::Cow;
+
+fn main() {
+    let cow: Cow<'static, bool> = Cow::Borrowed(&false);
+
+    match cow {
+        true => {}
+        //~v ERROR mix of deref patterns and normal constructors
+        false => {}
+        Cow::Borrowed(_) => {}
+    }
+
+    match cow {
+        Cow::Owned(_) => {}
+        Cow::Borrowed(_) => {}
+        true => {}
+        //~^ ERROR mix of deref patterns and normal constructors
+    }
+
+    match cow {
+        _ => {}
+        Cow::Owned(_) => {}
+        false => {}
+        //~^ ERROR mix of deref patterns and normal constructors
+    }
+
+    match (cow, 0) {
+        (Cow::Owned(_), 0) => {}
+        (Cow::Borrowed(_), 0) => {}
+        (true, 0) => {}
+        //~^ ERROR mix of deref patterns and normal constructors
+    }
+
+    match (0, cow) {
+        (0, Cow::Owned(_)) => {}
+        (0, Cow::Borrowed(_)) => {}
+        _ => {}
+        (1, true) => {}
+        //~^ ERROR mix of deref patterns and normal constructors
+    }
+}
diff --git a/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.stderr b/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.stderr
new file mode 100644
index 00000000000..5ad24164b98
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.stderr
@@ -0,0 +1,43 @@
+error: mix of deref patterns and normal constructors
+  --> $DIR/mixed-constructors.rs:16:9
+   |
+LL |         false => {}
+   |         ^^^^^ matches on the result of dereferencing `Cow<'_, bool>`
+LL |         Cow::Borrowed(_) => {}
+   |         ^^^^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>`
+
+error: mix of deref patterns and normal constructors
+  --> $DIR/mixed-constructors.rs:22:9
+   |
+LL |         Cow::Borrowed(_) => {}
+   |         ^^^^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>`
+LL |         true => {}
+   |         ^^^^ matches on the result of dereferencing `Cow<'_, bool>`
+
+error: mix of deref patterns and normal constructors
+  --> $DIR/mixed-constructors.rs:29:9
+   |
+LL |         Cow::Owned(_) => {}
+   |         ^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>`
+LL |         false => {}
+   |         ^^^^^ matches on the result of dereferencing `Cow<'_, bool>`
+
+error: mix of deref patterns and normal constructors
+  --> $DIR/mixed-constructors.rs:36:10
+   |
+LL |         (Cow::Borrowed(_), 0) => {}
+   |          ^^^^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>`
+LL |         (true, 0) => {}
+   |          ^^^^ matches on the result of dereferencing `Cow<'_, bool>`
+
+error: mix of deref patterns and normal constructors
+  --> $DIR/mixed-constructors.rs:43:13
+   |
+LL |         (0, Cow::Borrowed(_)) => {}
+   |             ^^^^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>`
+LL |         _ => {}
+LL |         (1, true) => {}
+   |             ^^^^ matches on the result of dereferencing `Cow<'_, bool>`
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.rs b/tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.rs
new file mode 100644
index 00000000000..704cae8bdbc
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.rs
@@ -0,0 +1,28 @@
+//! Test non-exhaustive matches involving deref patterns.
+#![feature(deref_patterns)]
+#![expect(incomplete_features)]
+#![deny(unreachable_patterns)]
+
+fn main() {
+    match Box::new(false) {
+        //~^ ERROR non-exhaustive patterns: `deref!(true)` not covered
+        false => {}
+    }
+
+    match Box::new(Box::new(false)) {
+        //~^ ERROR non-exhaustive patterns: `deref!(deref!(false))` not covered
+        true => {}
+    }
+
+    match Box::new((true, Box::new(false))) {
+        //~^ ERROR non-exhaustive patterns: `deref!((false, deref!(false)))` and `deref!((true, deref!(true)))` not covered
+        (true, false) => {}
+        (false, true) => {}
+    }
+
+    enum T { A, B, C }
+    match Box::new((Box::new(T::A), Box::new(T::A))) {
+        //~^ ERROR non-exhaustive patterns: `deref!((deref!(T::C), _))` not covered
+        (T::A | T::B, T::C) => {}
+    }
+}
diff --git a/tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.stderr b/tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.stderr
new file mode 100644
index 00000000000..55fa84bafde
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/usefulness/non-exhaustive.stderr
@@ -0,0 +1,63 @@
+error[E0004]: non-exhaustive patterns: `deref!(true)` not covered
+  --> $DIR/non-exhaustive.rs:7:11
+   |
+LL |     match Box::new(false) {
+   |           ^^^^^^^^^^^^^^^ pattern `deref!(true)` not covered
+   |
+note: `Box<bool>` defined here
+  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+   = note: the matched value is of type `Box<bool>`
+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 => {},
+LL +         deref!(true) => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `deref!(deref!(false))` not covered
+  --> $DIR/non-exhaustive.rs:12:11
+   |
+LL |     match Box::new(Box::new(false)) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `deref!(deref!(false))` not covered
+   |
+note: `Box<Box<bool>>` defined here
+  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+   = note: the matched value is of type `Box<Box<bool>>`
+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 ~         true => {},
+LL +         deref!(deref!(false)) => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `deref!((false, deref!(false)))` and `deref!((true, deref!(true)))` not covered
+  --> $DIR/non-exhaustive.rs:17:11
+   |
+LL |     match Box::new((true, Box::new(false))) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ patterns `deref!((false, deref!(false)))` and `deref!((true, deref!(true)))` not covered
+   |
+note: `Box<(bool, Box<bool>)>` defined here
+  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+   = note: the matched value is of type `Box<(bool, Box<bool>)>`
+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, true) => {},
+LL +         deref!((false, deref!(false))) | deref!((true, deref!(true))) => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `deref!((deref!(T::C), _))` not covered
+  --> $DIR/non-exhaustive.rs:24:11
+   |
+LL |     match Box::new((Box::new(T::A), Box::new(T::A))) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `deref!((deref!(T::C), _))` not covered
+   |
+note: `Box<(Box<T>, Box<T>)>` defined here
+  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+   = note: the matched value is of type `Box<(Box<T>, Box<T>)>`
+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 ~         (T::A | T::B, T::C) => {},
+LL +         deref!((deref!(T::C), _)) => todo!()
+   |
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.rs b/tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.rs
new file mode 100644
index 00000000000..2677fc54ded
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.rs
@@ -0,0 +1,33 @@
+//! Test unreachable patterns involving deref patterns.
+#![feature(deref_patterns)]
+#![expect(incomplete_features)]
+#![deny(unreachable_patterns)]
+
+fn main() {
+    match Box::new(false) {
+        true => {}
+        false => {}
+        false => {} //~ ERROR unreachable pattern
+    }
+
+    match Box::new(Box::new(false)) {
+        true => {}
+        false => {}
+        true => {} //~ ERROR unreachable pattern
+    }
+
+    match Box::new((true, Box::new(false))) {
+        (true, _) => {}
+        (_, true) => {}
+        (false, false) => {}
+        _ => {} //~ ERROR unreachable pattern
+    }
+
+    enum T { A, B, C }
+    match Box::new((Box::new(T::A), Box::new(T::A))) {
+        (T::A | T::B, T::A | T::C) => {}
+        (T::A, T::C) => {} //~ ERROR unreachable pattern
+        (T::B, T::A) => {} //~ ERROR unreachable pattern
+        _ => {}
+    }
+}
diff --git a/tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.stderr b/tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.stderr
new file mode 100644
index 00000000000..045e11be319
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/usefulness/unreachable-patterns.stderr
@@ -0,0 +1,60 @@
+error: unreachable pattern
+  --> $DIR/unreachable-patterns.rs:10:9
+   |
+LL |         false => {}
+   |         ----- matches all the relevant values
+LL |         false => {}
+   |         ^^^^^ no value can reach this
+   |
+note: the lint level is defined here
+  --> $DIR/unreachable-patterns.rs:4:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/unreachable-patterns.rs:16:9
+   |
+LL |         true => {}
+   |         ---- matches all the relevant values
+LL |         false => {}
+LL |         true => {}
+   |         ^^^^ no value can reach this
+
+error: unreachable pattern
+  --> $DIR/unreachable-patterns.rs:23:9
+   |
+LL |         _ => {}
+   |         ^ no value can reach this
+   |
+note: multiple earlier patterns match some of the same values
+  --> $DIR/unreachable-patterns.rs:23:9
+   |
+LL |         (true, _) => {}
+   |         --------- matches some of the same values
+LL |         (_, true) => {}
+   |         --------- matches some of the same values
+LL |         (false, false) => {}
+   |         -------------- matches some of the same values
+LL |         _ => {}
+   |         ^ collectively making this unreachable
+
+error: unreachable pattern
+  --> $DIR/unreachable-patterns.rs:29:9
+   |
+LL |         (T::A | T::B, T::A | T::C) => {}
+   |         -------------------------- matches all the relevant values
+LL |         (T::A, T::C) => {}
+   |         ^^^^^^^^^^^^ no value can reach this
+
+error: unreachable pattern
+  --> $DIR/unreachable-patterns.rs:30:9
+   |
+LL |         (T::A | T::B, T::A | T::C) => {}
+   |         -------------------------- matches all the relevant values
+LL |         (T::A, T::C) => {}
+LL |         (T::B, T::A) => {}
+   |         ^^^^^^^^^^^^ no value can reach this
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/pattern/normalize-ty-in-range.rs b/tests/ui/pattern/normalize-ty-in-range.rs
new file mode 100644
index 00000000000..f0d22362608
--- /dev/null
+++ b/tests/ui/pattern/normalize-ty-in-range.rs
@@ -0,0 +1,24 @@
+//@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/200>.
+// Make sure we structurally normalize in range pattern checking in HIR typeck.
+
+trait Foo {
+    type Bar;
+}
+
+impl Foo for () {
+    type Bar = i32;
+}
+
+fn main() {
+    const X: <() as Foo>::Bar = 0;
+
+    match 0 {
+        X..=X => {}
+        _ => {}
+    }
+}
diff --git a/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs b/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs
index cbfcf0eafd4..6c5a331b4b5 100644
--- a/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs
+++ b/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs
@@ -1,6 +1,5 @@
 enum A {}
     //~^ NOTE `A` defined here
-    //~| NOTE
 
 fn f(a: &A) {
     match a {}
diff --git a/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr b/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr
index c37a9a51579..67ee38eed60 100644
--- a/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr
+++ b/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: type `&A` is non-empty
-  --> $DIR/issue-78123-non-exhaustive-reference.rs:6:11
+  --> $DIR/issue-78123-non-exhaustive-reference.rs:5:11
    |
 LL |     match a {}
    |           ^
diff --git a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.rs b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.rs
index e505fe43520..2771b4717fb 100644
--- a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.rs
+++ b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.rs
@@ -9,14 +9,14 @@ use core::{
 
 fn function_call_stops_borrow_extension() {
     let phantom_pinned = identity(pin!(PhantomPinned));
-    //~^ ERROR does not live long enough
+    //~^ ERROR temporary value dropped while borrowed [E0716]
     stuff(phantom_pinned)
 }
 
 fn promotion_only_works_for_the_innermost_block() {
     let phantom_pinned = {
         let phantom_pinned = pin!(PhantomPinned);
-        //~^ ERROR does not live long enough
+        //~^ ERROR temporary value dropped while borrowed [E0716]
         phantom_pinned
     };
     stuff(phantom_pinned)
diff --git a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr
index 43fb82be7c2..4ecc6370d3c 100644
--- a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr
+++ b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr
@@ -1,29 +1,31 @@
-error[E0597]: value does not live long enough
+error[E0716]: temporary value dropped while borrowed
   --> $DIR/lifetime_errors_on_promotion_misusage.rs:11:35
    |
 LL |     let phantom_pinned = identity(pin!(PhantomPinned));
-   |                                   ^^^^^^^^^^^^^^^^^^^ - value dropped here while still borrowed
+   |                                   ^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
    |                                   |
-   |                                   borrowed value does not live long enough
+   |                                   creates a temporary value which is freed while still in use
 LL |
 LL |     stuff(phantom_pinned)
    |           -------------- borrow later used here
    |
+   = note: consider using a `let` binding to create a longer lived value
    = note: this error originates in the macro `pin` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0597]: value does not live long enough
+error[E0716]: temporary value dropped while borrowed
   --> $DIR/lifetime_errors_on_promotion_misusage.rs:18:30
    |
 LL |     let phantom_pinned = {
    |         -------------- borrow later stored here
 LL |         let phantom_pinned = pin!(PhantomPinned);
-   |                              ^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
+   |                              ^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
 ...
 LL |     };
-   |     - value dropped here while still borrowed
+   |     - temporary value is freed at the end of this statement
    |
+   = note: consider using a `let` binding to create a longer lived value
    = note: this error originates in the macro `pin` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0597`.
+For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/auxiliary/impl_privacy_xc_1.rs b/tests/ui/privacy/auxiliary/impl-privacy-cross-crate-1.rs
index 367b8ec8b88..367b8ec8b88 100644
--- a/tests/ui/auxiliary/impl_privacy_xc_1.rs
+++ b/tests/ui/privacy/auxiliary/impl-privacy-cross-crate-1.rs
diff --git a/tests/ui/privacy/auxiliary/impl_privacy_xc_2.rs b/tests/ui/privacy/auxiliary/impl-privacy-cross-crate-2.rs
index 5f9c2268167..5f9c2268167 100644
--- a/tests/ui/privacy/auxiliary/impl_privacy_xc_2.rs
+++ b/tests/ui/privacy/auxiliary/impl-privacy-cross-crate-2.rs
diff --git a/tests/ui/privacy/impl-privacy-cross-crate-1.rs b/tests/ui/privacy/impl-privacy-cross-crate-1.rs
new file mode 100644
index 00000000000..6b2ef3ccc78
--- /dev/null
+++ b/tests/ui/privacy/impl-privacy-cross-crate-1.rs
@@ -0,0 +1,10 @@
+//@ run-pass
+//@ aux-build:impl-privacy-cross-crate-1.rs
+
+
+extern crate impl_privacy_cross_crate_1;
+
+pub fn main() {
+    let fish = impl_privacy_cross_crate_1::Fish { x: 1 };
+    fish.swim();
+}
diff --git a/tests/ui/privacy/impl-privacy-cross-crate-2.rs b/tests/ui/privacy/impl-privacy-cross-crate-2.rs
new file mode 100644
index 00000000000..fa07e6e8cce
--- /dev/null
+++ b/tests/ui/privacy/impl-privacy-cross-crate-2.rs
@@ -0,0 +1,10 @@
+//@ run-pass
+//@ aux-build:impl-privacy-cross-crate-2.rs
+
+extern crate impl_privacy_cross_crate_2;
+
+pub fn main() {
+    let fish1 = impl_privacy_cross_crate_2::Fish { x: 1 };
+    let fish2 = impl_privacy_cross_crate_2::Fish { x: 2 };
+    if fish1.eq(&fish2) { println!("yes") } else { println!("no") };
+}
diff --git a/tests/ui/privacy/impl-privacy-xc-2.rs b/tests/ui/privacy/impl-privacy-xc-2.rs
deleted file mode 100644
index da345ba2072..00000000000
--- a/tests/ui/privacy/impl-privacy-xc-2.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ run-pass
-//@ aux-build:impl_privacy_xc_2.rs
-
-extern crate impl_privacy_xc_2;
-
-pub fn main() {
-    let fish1 = impl_privacy_xc_2::Fish { x: 1 };
-    let fish2 = impl_privacy_xc_2::Fish { x: 2 };
-    if fish1.eq(&fish2) { println!("yes") } else { println!("no") };
-}
diff --git a/tests/ui/pub/pub-restricted-warning.rs b/tests/ui/pub/pub-restricted-warning.rs
new file mode 100644
index 00000000000..80384afbb00
--- /dev/null
+++ b/tests/ui/pub/pub-restricted-warning.rs
@@ -0,0 +1,25 @@
+//@ check-pass
+
+#![allow(dead_code)]
+
+mod outer {
+    pub mod inner {
+        pub(in crate::outer) struct Foo;
+        pub fn bar() -> Foo {
+            //~^ WARNING type `Foo` is more private than the item `outer::inner::bar` [private_interfaces]
+            Foo
+        }
+    }
+
+    pub mod nested {
+        pub mod inner {
+            pub(in crate::outer::nested) struct NestedFoo;
+            pub fn bar() -> NestedFoo {
+                //~^ WARNING type `NestedFoo` is more private than the item `nested::inner::bar` [private_interfaces]
+                NestedFoo
+            }
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/pub/pub-restricted-warning.stderr b/tests/ui/pub/pub-restricted-warning.stderr
new file mode 100644
index 00000000000..74f32d3de3c
--- /dev/null
+++ b/tests/ui/pub/pub-restricted-warning.stderr
@@ -0,0 +1,27 @@
+warning: type `Foo` is more private than the item `outer::inner::bar`
+  --> $DIR/pub-restricted-warning.rs:8:9
+   |
+LL |         pub fn bar() -> Foo {
+   |         ^^^^^^^^^^^^^^^^^^^ function `outer::inner::bar` is reachable at visibility `pub(crate)`
+   |
+note: but type `Foo` is only usable at visibility `pub(in crate::outer)`
+  --> $DIR/pub-restricted-warning.rs:7:9
+   |
+LL |         pub(in crate::outer) struct Foo;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `#[warn(private_interfaces)]` on by default
+
+warning: type `NestedFoo` is more private than the item `nested::inner::bar`
+  --> $DIR/pub-restricted-warning.rs:17:13
+   |
+LL |             pub fn bar() -> NestedFoo {
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ function `nested::inner::bar` is reachable at visibility `pub(crate)`
+   |
+note: but type `NestedFoo` is only usable at visibility `pub(in crate::outer::nested)`
+  --> $DIR/pub-restricted-warning.rs:16:13
+   |
+LL |             pub(in crate::outer::nested) struct NestedFoo;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.stderr b/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.stderr
index 400969c279e..99fd83e7b6f 100644
--- a/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.stderr
+++ b/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.stderr
@@ -4,11 +4,11 @@ error[E0277]: the trait bound `Something: Termination` is not satisfied
 LL |         fn main() -> Something {
    |                      ^^^^^^^^^ the trait `Termination` is not implemented for `Something`
    |
-note: required by a bound in `Main::{anon_assoc#0}`
+note: required by a bound in `Main::main::{anon_assoc#0}`
   --> $DIR/issue-103052-2.rs:3:27
    |
 LL |         fn main() -> impl std::process::Termination;
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Main::{anon_assoc#0}`
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Main::main::{anon_assoc#0}`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/runtime/backtrace-debuginfo.rs b/tests/ui/runtime/backtrace-debuginfo.rs
index afc96d6bb5f..37fce2788b7 100644
--- a/tests/ui/runtime/backtrace-debuginfo.rs
+++ b/tests/ui/runtime/backtrace-debuginfo.rs
@@ -42,9 +42,13 @@ macro_rules! dump_and_die {
         // there, even on i686-pc-windows-msvc. We do the best we can in
         // rust-lang/rust to test it as well, but sometimes we just gotta keep
         // landing PRs.
+        //
+        // aarch64-msvc is broken as its backtraces are truncated.
+        // See https://github.com/rust-lang/rust/issues/140489
         if cfg!(any(target_os = "android",
                     all(target_os = "linux", target_arch = "arm"),
                     all(target_env = "msvc", target_arch = "x86"),
+                    all(target_env = "msvc", target_arch = "aarch64"),
                     target_os = "freebsd",
                     target_os = "dragonfly",
                     target_os = "openbsd")) {
diff --git a/tests/ui/rust-2024/unsafe-attributes/auxiliary/safe_attr.rs b/tests/ui/rust-2024/unsafe-attributes/auxiliary/safe_attr.rs
new file mode 100644
index 00000000000..161b71b9737
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-attributes/auxiliary/safe_attr.rs
@@ -0,0 +1,7 @@
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+#[proc_macro_attribute]
+pub fn safe(_attr: TokenStream, item: TokenStream) -> TokenStream {
+    item
+}
diff --git a/tests/ui/rust-2024/unsafe-attributes/safe-proc-macro-attribute.rs b/tests/ui/rust-2024/unsafe-attributes/safe-proc-macro-attribute.rs
new file mode 100644
index 00000000000..56b7001bdbf
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-attributes/safe-proc-macro-attribute.rs
@@ -0,0 +1,22 @@
+//! Anti-regression test for `#[safe]` proc-macro attribute.
+
+//@ revisions: unknown_attr proc_macro_attr
+//@[proc_macro_attr] proc-macro: safe_attr.rs
+//@[proc_macro_attr] check-pass
+
+#![warn(unsafe_attr_outside_unsafe)]
+
+#[cfg(proc_macro_attr)]
+extern crate safe_attr;
+#[cfg(proc_macro_attr)]
+use safe_attr::safe;
+
+#[safe]
+//[unknown_attr]~^ ERROR cannot find attribute `safe` in this scope
+fn foo() {}
+
+#[safe(no_mangle)]
+//[unknown_attr]~^ ERROR cannot find attribute `safe` in this scope
+fn bar() {}
+
+fn main() {}
diff --git a/tests/ui/rust-2024/unsafe-attributes/safe-proc-macro-attribute.unknown_attr.stderr b/tests/ui/rust-2024/unsafe-attributes/safe-proc-macro-attribute.unknown_attr.stderr
new file mode 100644
index 00000000000..93c6d75e52f
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-attributes/safe-proc-macro-attribute.unknown_attr.stderr
@@ -0,0 +1,14 @@
+error: cannot find attribute `safe` in this scope
+  --> $DIR/safe-proc-macro-attribute.rs:18:3
+   |
+LL | #[safe(no_mangle)]
+   |   ^^^^
+
+error: cannot find attribute `safe` in this scope
+  --> $DIR/safe-proc-macro-attribute.rs:14:3
+   |
+LL | #[safe]
+   |   ^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-allow.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-allow.rs
new file mode 100644
index 00000000000..76fdce7e5cf
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-allow.rs
@@ -0,0 +1,16 @@
+//@ check-pass
+//@ edition: 2021
+//
+// Anti-regression test for https://github.com/rust-lang/rust/issues/140602
+// where the generated warning couldn't be allowed due too being attached to
+// the wrong AST node.
+
+#![deny(unsafe_attr_outside_unsafe)]
+
+#[allow(unsafe_attr_outside_unsafe)]
+mod generated {
+    #[no_mangle]
+    fn _generated_foo() {}
+}
+
+fn main() {}
diff --git a/tests/ui/stability-attribute/generics-default-stability.stderr b/tests/ui/stability-attribute/generics-default-stability.stderr
index f4f51a14248..53ef3e170cc 100644
--- a/tests/ui/stability-attribute/generics-default-stability.stderr
+++ b/tests/ui/stability-attribute/generics-default-stability.stderr
@@ -270,6 +270,18 @@ LL |     let _: Struct3<usize, usize> = Struct3 { field1: 0, field2: 0 };
    = help: add `#![feature(unstable_default)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
+warning: use of deprecated field `unstable_generic_param::Struct4::field`: test
+  --> $DIR/generics-default-stability.rs:71:39
+   |
+LL |     let _: Struct4<isize> = Struct4 { field: 1 };
+   |                                       ^^^^^^^^
+
+warning: use of deprecated field `unstable_generic_param::Struct4::field`: test
+  --> $DIR/generics-default-stability.rs:78:39
+   |
+LL |     let _: Struct4<isize> = Struct4 { field: 0 };
+   |                                       ^^^^^^^^
+
 error[E0658]: use of unstable library feature `unstable_default`
   --> $DIR/generics-default-stability.rs:84:20
    |
@@ -279,6 +291,12 @@ LL |     let _: Struct5<isize> = Struct5 { field: 1 };
    = help: add `#![feature(unstable_default)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
+warning: use of deprecated field `unstable_generic_param::Struct5::field`: test
+  --> $DIR/generics-default-stability.rs:84:39
+   |
+LL |     let _: Struct5<isize> = Struct5 { field: 1 };
+   |                                       ^^^^^^^^
+
 error[E0658]: use of unstable library feature `unstable_default`
   --> $DIR/generics-default-stability.rs:90:20
    |
@@ -297,6 +315,12 @@ LL |     let _: Struct5<isize> = Struct5 { field: 0 };
    = help: add `#![feature(unstable_default)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
+warning: use of deprecated field `unstable_generic_param::Struct5::field`: test
+  --> $DIR/generics-default-stability.rs:92:39
+   |
+LL |     let _: Struct5<isize> = Struct5 { field: 0 };
+   |                                       ^^^^^^^^
+
 error[E0658]: use of unstable library feature `unstable_default`
   --> $DIR/generics-default-stability.rs:100:19
    |
@@ -468,30 +492,6 @@ LL |     let _: Box1<isize, System> = Box1::new(1);
    = help: add `#![feature(box_alloc_param)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-warning: use of deprecated field `unstable_generic_param::Struct4::field`: test
-  --> $DIR/generics-default-stability.rs:71:39
-   |
-LL |     let _: Struct4<isize> = Struct4 { field: 1 };
-   |                                       ^^^^^^^^
-
-warning: use of deprecated field `unstable_generic_param::Struct4::field`: test
-  --> $DIR/generics-default-stability.rs:78:39
-   |
-LL |     let _: Struct4<isize> = Struct4 { field: 0 };
-   |                                       ^^^^^^^^
-
-warning: use of deprecated field `unstable_generic_param::Struct5::field`: test
-  --> $DIR/generics-default-stability.rs:84:39
-   |
-LL |     let _: Struct5<isize> = Struct5 { field: 1 };
-   |                                       ^^^^^^^^
-
-warning: use of deprecated field `unstable_generic_param::Struct5::field`: test
-  --> $DIR/generics-default-stability.rs:92:39
-   |
-LL |     let _: Struct5<isize> = Struct5 { field: 0 };
-   |                                       ^^^^^^^^
-
 error: aborting due to 28 previous errors; 40 warnings emitted
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/stability-attribute/suggest-vec-allocator-api.stderr b/tests/ui/stability-attribute/suggest-vec-allocator-api.stderr
index 6662ceda90b..78b7d07b60c 100644
--- a/tests/ui/stability-attribute/suggest-vec-allocator-api.stderr
+++ b/tests/ui/stability-attribute/suggest-vec-allocator-api.stderr
@@ -27,22 +27,22 @@ LL ~         _)> = vec![];
    |
 
 error[E0658]: use of unstable library feature `allocator_api`
-  --> $DIR/suggest-vec-allocator-api.rs:8:26
+  --> $DIR/suggest-vec-allocator-api.rs:7:24
    |
-LL |     let _boxed: Box<u32, _> = Box::new(10);
-   |                          ^
+LL |     let _ = Vec::<u16, _>::new();
+   |                   -----^
+   |                   |
+   |                   help: consider wrapping the inner types in tuple: `(u16, _)`
    |
    = note: see issue #32838 <https://github.com/rust-lang/rust/issues/32838> for more information
    = help: add `#![feature(allocator_api)]` 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]: use of unstable library feature `allocator_api`
-  --> $DIR/suggest-vec-allocator-api.rs:7:24
+  --> $DIR/suggest-vec-allocator-api.rs:8:26
    |
-LL |     let _ = Vec::<u16, _>::new();
-   |                   -----^
-   |                   |
-   |                   help: consider wrapping the inner types in tuple: `(u16, _)`
+LL |     let _boxed: Box<u32, _> = Box::new(10);
+   |                          ^
    |
    = note: see issue #32838 <https://github.com/rust-lang/rust/issues/32838> for more information
    = help: add `#![feature(allocator_api)]` to the crate attributes to enable
diff --git a/tests/ui/statics/auxiliary/inner_static.rs b/tests/ui/statics/auxiliary/inner_static.rs
new file mode 100644
index 00000000000..1c62046438f
--- /dev/null
+++ b/tests/ui/statics/auxiliary/inner_static.rs
@@ -0,0 +1,67 @@
+//! Test for inner statics with the same name.
+//!
+//! Before, the path name for all items defined in methods of traits and impls never
+//! took into account the name of the method. This meant that if you had two statics
+//! of the same name in two different methods the statics would end up having the
+//! same symbol named (even after mangling) because the path components leading to
+//! the symbol were exactly the same (just __extensions__ and the static name).
+//!
+//! It turns out that if you add the symbol "A" twice to LLVM, it automatically
+//! makes the second one "A1" instead of "A". What this meant is that in local crate
+//! compilations we never found this bug. Even across crates, this was never a
+//! problem. The problem arises when you have generic methods that don't get
+//! generated at compile-time of a library. If the statics were re-added to LLVM by
+//! a client crate of a library in a different order, you would reference different
+//! constants (the integer suffixes wouldn't be guaranteed to be the same).
+
+pub struct A<T> { pub v: T }
+pub struct B<T> { pub v: T }
+
+pub mod test {
+    pub struct A<T> { pub v: T }
+
+    impl<T> A<T> {
+        pub fn foo(&self) -> isize {
+            static a: isize = 5;
+            return a
+        }
+
+        pub fn bar(&self) -> isize {
+            static a: isize = 6;
+            return a;
+        }
+    }
+}
+
+impl<T> A<T> {
+    pub fn foo(&self) -> isize {
+        static a: isize = 1;
+        return a
+    }
+
+    pub fn bar(&self) -> isize {
+        static a: isize = 2;
+        return a;
+    }
+}
+
+impl<T> B<T> {
+    pub fn foo(&self) -> isize {
+        static a: isize = 3;
+        return a
+    }
+
+    pub fn bar(&self) -> isize {
+        static a: isize = 4;
+        return a;
+    }
+}
+
+pub fn foo() -> isize {
+    let a = A { v: () };
+    let b = B { v: () };
+    let c = test::A { v: () };
+    return a.foo() + a.bar() +
+           b.foo() + b.bar() +
+           c.foo() + c.bar();
+}
diff --git a/tests/ui/statics/inner-static.rs b/tests/ui/statics/inner-static.rs
new file mode 100644
index 00000000000..1916435c46a
--- /dev/null
+++ b/tests/ui/statics/inner-static.rs
@@ -0,0 +1,30 @@
+//! Test for inner statics with the same name.
+//!
+//! Before, the path name for all items defined in methods of traits and impls never
+//! took into account the name of the method. This meant that if you had two statics
+//! of the same name in two different methods the statics would end up having the
+//! same symbol named (even after mangling) because the path components leading to
+//! the symbol were exactly the same (just __extensions__ and the static name).
+//!
+//! It turns out that if you add the symbol "A" twice to LLVM, it automatically
+//! makes the second one "A1" instead of "A". What this meant is that in local crate
+//! compilations we never found this bug. Even across crates, this was never a
+//! problem. The problem arises when you have generic methods that don't get
+//! generated at compile-time of a library. If the statics were re-added to LLVM by
+//! a client crate of a library in a different order, you would reference different
+//! constants (the integer suffixes wouldn't be guaranteed to be the same).
+
+//@ run-pass
+//@ aux-build:inner_static.rs
+
+
+extern crate inner_static;
+
+pub fn main() {
+    let a = inner_static::A::<()> { v: () };
+    let b = inner_static::B::<()> { v: () };
+    let c = inner_static::test::A::<()> { v: () };
+    assert_eq!(a.bar(), 2);
+    assert_eq!(b.bar(), 4);
+    assert_eq!(c.bar(), 6);
+}
diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.riscv.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.riscv.stderr
new file mode 100644
index 00000000000..49c5479275f
--- /dev/null
+++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.riscv.stderr
@@ -0,0 +1,8 @@
+error: target feature `d` cannot be enabled with `#[target_feature]`: this feature is incompatible with the target ABI
+  --> $DIR/abi-incompatible-target-feature-attribute.rs:15:90
+   |
+LL | #[cfg_attr(x86, target_feature(enable = "soft-float"))] #[cfg_attr(riscv, target_feature(enable = "d"))]
+   |                                                                                          ^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs
new file mode 100644
index 00000000000..a8733440759
--- /dev/null
+++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.rs
@@ -0,0 +1,17 @@
+//! Ensure ABI-incompatible features cannot be enabled via `#[target_feature]`.
+// ignore-tidy-linelength
+//@ compile-flags: --crate-type=lib
+//@ revisions: x86 riscv
+//@[x86] compile-flags: --target=x86_64-unknown-linux-gnu
+//@[x86] needs-llvm-components: x86
+//@[riscv] compile-flags: --target=riscv32e-unknown-none-elf
+//@[riscv] needs-llvm-components: riscv
+#![feature(no_core, lang_items, riscv_target_feature, x87_target_feature)]
+#![no_core]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[cfg_attr(x86, target_feature(enable = "soft-float"))] #[cfg_attr(riscv, target_feature(enable = "d"))]
+//~^ERROR: cannot be enabled with
+pub unsafe fn my_fun() {}
diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr
new file mode 100644
index 00000000000..81471fd7e30
--- /dev/null
+++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr
@@ -0,0 +1,8 @@
+error: target feature `soft-float` cannot be enabled with `#[target_feature]`: this feature is incompatible with the target ABI
+  --> $DIR/abi-incompatible-target-feature-attribute.rs:15:32
+   |
+LL | #[cfg_attr(x86, target_feature(enable = "soft-float"))] #[cfg_attr(riscv, target_feature(enable = "d"))]
+   |                                ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.riscv.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.riscv.stderr
new file mode 100644
index 00000000000..2dca0c22033
--- /dev/null
+++ b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.riscv.stderr
@@ -0,0 +1,19 @@
+warning: target feature `d` must be disabled to ensure that the ABI of the current target can be implemented correctly
+   |
+   = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
+
+warning: unstable feature specified for `-Ctarget-feature`: `d`
+   |
+   = note: this feature is not stably supported; its behavior can change in the future
+
+warning: unstable feature specified for `-Ctarget-feature`: `f`
+   |
+   = note: this feature is not stably supported; its behavior can change in the future
+
+warning: unstable feature specified for `-Ctarget-feature`: `zicsr`
+   |
+   = note: this feature is not stably supported; its behavior can change in the future
+
+warning: 4 warnings emitted
+
diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs
new file mode 100644
index 00000000000..68e1d3b9ddc
--- /dev/null
+++ b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs
@@ -0,0 +1,22 @@
+//! Ensure ABI-incompatible features cannot be enabled via `-Ctarget-feature`.
+// These are just warnings for now.
+//@ check-pass
+//@ compile-flags: --crate-type=lib
+//@ revisions: x86 riscv
+//@[x86] compile-flags: --target=x86_64-unknown-linux-gnu -Ctarget-feature=+soft-float
+//@[x86] needs-llvm-components: x86
+//@[riscv] compile-flags: --target=riscv32e-unknown-none-elf -Ctarget-feature=+d
+//@[riscv] needs-llvm-components: riscv
+
+#![feature(no_core, lang_items, riscv_target_feature)]
+#![no_core]
+
+#[lang = "sized"]
+pub trait Sized {}
+#[lang = "freeze"]
+pub trait Freeze {}
+
+//~? WARN must be disabled to ensure that the ABI of the current target can be implemented correctly
+//~? WARN unstable feature specified for `-Ctarget-feature`
+//[riscv]~? WARN unstable feature specified for `-Ctarget-feature`
+//[riscv]~? WARN unstable feature specified for `-Ctarget-feature`
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.x86.stderr
index e49672f33b9..e49672f33b9 100644
--- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.stderr
+++ b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.x86.stderr
diff --git a/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs b/tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.rs
index 7368ef120fa..0013d033b9c 100644
--- a/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs
+++ b/tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.rs
@@ -1,3 +1,6 @@
+//! `x87` is a required target feature on some x86 targets, but not on this one as this one
+//! uses soft-floats. So ensure disabling the target feature here (which is a NOP) does
+//! not trigger a warning.
 //@ compile-flags: --target=x86_64-unknown-none --crate-type=lib
 //@ needs-llvm-components: x86
 //@ compile-flags: -Ctarget-feature=-x87
diff --git a/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.stderr b/tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.stderr
index 309b64afd92..309b64afd92 100644
--- a/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.stderr
+++ b/tests/ui/target-feature/abi-irrelevant-target-feature-flag-disable.stderr
diff --git a/tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs b/tests/ui/target-feature/abi-required-target-feature-attribute.rs
index 8b60820cc9b..95723c57f94 100644
--- a/tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs
+++ b/tests/ui/target-feature/abi-required-target-feature-attribute.rs
@@ -1,3 +1,5 @@
+//! Enabling a target feature that is anyway required changes nothing, so this is allowed
+//! for `#[target_feature]`.
 //@ compile-flags: --target=x86_64-unknown-none --crate-type=lib
 //@ needs-llvm-components: x86
 //@ build-pass
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.stderr b/tests/ui/target-feature/abi-required-target-feature-flag-disable.aarch64.stderr
index b1186d5d5dc..b1186d5d5dc 100644
--- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.stderr
+++ b/tests/ui/target-feature/abi-required-target-feature-flag-disable.aarch64.stderr
diff --git a/tests/ui/target-feature/abi-required-target-feature-flag-disable.loongarch.stderr b/tests/ui/target-feature/abi-required-target-feature-flag-disable.loongarch.stderr
new file mode 100644
index 00000000000..35102e0571f
--- /dev/null
+++ b/tests/ui/target-feature/abi-required-target-feature-flag-disable.loongarch.stderr
@@ -0,0 +1,11 @@
+warning: target feature `d` must be enabled to ensure that the ABI of the current target can be implemented correctly
+   |
+   = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
+
+warning: unstable feature specified for `-Ctarget-feature`: `d`
+   |
+   = note: this feature is not stably supported; its behavior can change in the future
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/target-feature/abi-required-target-feature-flag-disable.riscv.stderr b/tests/ui/target-feature/abi-required-target-feature-flag-disable.riscv.stderr
new file mode 100644
index 00000000000..35102e0571f
--- /dev/null
+++ b/tests/ui/target-feature/abi-required-target-feature-flag-disable.riscv.stderr
@@ -0,0 +1,11 @@
+warning: target feature `d` must be enabled to ensure that the ABI of the current target can be implemented correctly
+   |
+   = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
+
+warning: unstable feature specified for `-Ctarget-feature`: `d`
+   |
+   = note: this feature is not stably supported; its behavior can change in the future
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs b/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs
new file mode 100644
index 00000000000..c3ce05baa64
--- /dev/null
+++ b/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs
@@ -0,0 +1,27 @@
+//! Ensure ABI-required features cannot be disabled via `-Ctarget-feature`.
+//! Also covers the case of a feature indirectly disabling another via feature implications.
+//@ compile-flags: --crate-type=lib
+//@ revisions: x86 x86-implied aarch64 riscv loongarch
+//@[x86] compile-flags: --target=x86_64-unknown-linux-gnu -Ctarget-feature=-x87
+//@[x86] needs-llvm-components: x86
+//@[x86-implied] compile-flags: --target=x86_64-unknown-linux-gnu -Ctarget-feature=-sse
+//@[x86-implied] needs-llvm-components: x86
+//@[aarch64] compile-flags: --target=aarch64-unknown-linux-gnu -Ctarget-feature=-neon
+//@[aarch64] needs-llvm-components: aarch64
+//@[riscv] compile-flags: --target=riscv64gc-unknown-none-elf -Ctarget-feature=-d
+//@[riscv] needs-llvm-components: riscv
+//@[loongarch] compile-flags: --target=loongarch64-unknown-none -Ctarget-feature=-d
+//@[loongarch] needs-llvm-components: loongarch
+// For now this is just a warning.
+//@ build-pass
+// Remove some LLVM warnings that only show up sometimes.
+//@ normalize-stderr: "\n[^\n]*(target-abi|lp64f)[^\n]*" -> ""
+
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+//~? WARN must be enabled to ensure that the ABI of the current target can be implemented correctly
+//[x86,riscv,loongarch]~? WARN unstable feature specified for `-Ctarget-feature`
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.stderr b/tests/ui/target-feature/abi-required-target-feature-flag-disable.x86-implied.stderr
index 7ec8b04cfce..7ec8b04cfce 100644
--- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.stderr
+++ b/tests/ui/target-feature/abi-required-target-feature-flag-disable.x86-implied.stderr
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.stderr b/tests/ui/target-feature/abi-required-target-feature-flag-disable.x86.stderr
index 02398d27501..02398d27501 100644
--- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.stderr
+++ b/tests/ui/target-feature/abi-required-target-feature-flag-disable.x86.stderr
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs
deleted file mode 100644
index 12e7e3bc45b..00000000000
--- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-//! Ensure that if disabling a target feature implies disabling an ABI-required target feature,
-//! we complain.
-//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib
-//@ needs-llvm-components: x86
-//@ compile-flags: -Ctarget-feature=-sse
-// For now this is just a warning.
-//@ build-pass
-
-#![feature(no_core, lang_items)]
-#![no_core]
-
-#[lang = "sized"]
-pub trait Sized {}
-
-//~? WARN target feature `sse2` must be enabled to ensure that the ABI of the current target can be implemented correctly
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs
deleted file mode 100644
index 33e4f12694f..00000000000
--- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-//@ compile-flags: --target=aarch64-unknown-linux-gnu --crate-type=lib
-//@ needs-llvm-components: aarch64
-//@ compile-flags: -Ctarget-feature=-neon
-// For now this is just a warning.
-//@ build-pass
-
-#![feature(no_core, lang_items)]
-#![no_core]
-
-#[lang = "sized"]
-pub trait Sized {}
-
-//~? WARN target feature `neon` must be enabled to ensure that the ABI of the current target can be implemented correctly
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs
deleted file mode 100644
index e1bd25ffad1..00000000000
--- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-//! Ensure ABI-required features cannot be disabled via `-Ctarget-feature`.
-//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib
-//@ needs-llvm-components: x86
-//@ compile-flags: -Ctarget-feature=-x87
-// For now this is just a warning.
-//@ build-pass
-
-#![feature(no_core, lang_items)]
-#![no_core]
-
-#[lang = "sized"]
-pub trait Sized {}
-
-//~? WARN target feature `x87` must be enabled to ensure that the ABI of the current target can be implemented correctly
-//~? WARN unstable feature specified for `-Ctarget-feature`: `x87`
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs
deleted file mode 100644
index 4ccc6e0e941..00000000000
--- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-//! Ensure ABI-incompatible features cannot be enabled via `-Ctarget-feature`.
-//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib
-//@ needs-llvm-components: x86
-//@ compile-flags: -Ctarget-feature=+soft-float
-// For now this is just a warning.
-//@ build-pass
-
-#![feature(no_core, lang_items, riscv_target_feature)]
-#![no_core]
-
-#[lang = "sized"]
-pub trait Sized {}
-
-//~? WARN target feature `soft-float` must be disabled to ensure that the ABI of the current target can be implemented correctl
-//~? WARN unstable feature specified for `-Ctarget-feature`: `soft-float`
diff --git a/tests/ui/target_modifiers/auxiliary/fixed_x18.rs b/tests/ui/target_modifiers/auxiliary/fixed_x18.rs
new file mode 100644
index 00000000000..32eff76ec54
--- /dev/null
+++ b/tests/ui/target_modifiers/auxiliary/fixed_x18.rs
@@ -0,0 +1,7 @@
+//@ no-prefer-dynamic
+//@ compile-flags: --target aarch64-unknown-none -Zfixed-x18
+//@ needs-llvm-components: aarch64
+
+#![feature(no_core)]
+#![crate_type = "rlib"]
+#![no_core]
diff --git a/tests/ui/target_modifiers/incompatible_fixedx18.error_generated.stderr b/tests/ui/target_modifiers/incompatible_fixedx18.error_generated.stderr
new file mode 100644
index 00000000000..096d7cb5f25
--- /dev/null
+++ b/tests/ui/target_modifiers/incompatible_fixedx18.error_generated.stderr
@@ -0,0 +1,13 @@
+error: mixing `-Zfixed-x18` will cause an ABI mismatch in crate `incompatible_fixedx18`
+  --> $DIR/incompatible_fixedx18.rs:12:1
+   |
+LL | #![feature(no_core)]
+   | ^
+   |
+   = help: the `-Zfixed-x18` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
+   = note: unset `-Zfixed-x18` in this crate is incompatible with `-Zfixed-x18=` in dependency `fixed_x18`
+   = help: set `-Zfixed-x18=` in this crate or unset `-Zfixed-x18` in `fixed_x18`
+   = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=fixed-x18` to silence this error
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/target_modifiers/incompatible_fixedx18.rs b/tests/ui/target_modifiers/incompatible_fixedx18.rs
new file mode 100644
index 00000000000..6c13984f608
--- /dev/null
+++ b/tests/ui/target_modifiers/incompatible_fixedx18.rs
@@ -0,0 +1,17 @@
+//@ aux-build:fixed_x18.rs
+//@ compile-flags: --target aarch64-unknown-none
+//@ needs-llvm-components: aarch64
+
+//@ revisions:allow_match allow_mismatch error_generated
+//@[allow_match] compile-flags: -Zfixed-x18
+//@[allow_mismatch] compile-flags: -Cunsafe-allow-abi-mismatch=fixed-x18
+//@[error_generated] compile-flags:
+//@[allow_mismatch] check-pass
+//@[allow_match] check-pass
+
+#![feature(no_core)]
+//[error_generated]~^ ERROR mixing `-Zfixed-x18` will cause an ABI mismatch in crate `incompatible_fixedx18`
+#![crate_type = "rlib"]
+#![no_core]
+
+extern crate fixed_x18;
diff --git a/tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr b/tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr
index e26cb22163f..f8a6252f991 100644
--- a/tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr
+++ b/tests/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr
@@ -10,26 +10,53 @@ LL |     fn foo<'a, K>(self, _: T, _: K) where T: 'a, K: 'a;
 LL |     fn foo<'a, K>(self, _: (), _: K) where {
    |           ^^^^^^^ lifetimes do not match method in trait
 
-error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
-  --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:23:11
+error[E0195]: lifetime parameters do not match the trait definition
+  --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:23:12
    |
-LL |     fn foo<'a>(&self, state: &'a State) -> &'a T
-   |           ---- lifetimes in impl do not match this method in trait
-LL |     where
-LL |         T: 'a;
-   |            -- this bound might be missing in the impl
-...
 LL |     fn foo<'a>(&self, state: &'a State) -> &'a T {
-   |           ^^^^ lifetimes do not match method in trait
+   |            ^^
+   |
+   = note: lifetime parameters differ in whether they are early- or late-bound
+note: `'a` differs between the trait and impl
+  --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:14:12
+   |
+LL |   trait Foo<T> {
+   |   ------------ in this trait...
+LL |       fn foo<'a>(&self, state: &'a State) -> &'a T
+   |              ^^ `'a` is early-bound
+LL |       where
+LL |           T: 'a;
+   |              -- this lifetime bound makes `'a` early-bound
+...
+LL | / impl<F, T> Foo<T> for F
+LL | | where
+LL | |     F: Fn(&State) -> &T,
+   | |________________________- in this impl...
+LL |   {
+LL |       fn foo<'a>(&self, state: &'a State) -> &'a T {
+   |              ^^ `'a` is late-bound
 
-error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
-  --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:33:11
+error[E0195]: lifetime parameters do not match the trait definition
+  --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:33:12
+   |
+LL |     fn foo<'a: 'a>(&'a self) {}
+   |            ^^
+   |
+   = note: lifetime parameters differ in whether they are early- or late-bound
+note: `'a` differs between the trait and impl
+  --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:29:12
    |
+LL | trait Bar {
+   | --------- in this trait...
 LL |     fn foo<'a>(&'a self) {}
-   |           ---- lifetimes in impl do not match this method in trait
+   |            ^^ `'a` is late-bound
 ...
+LL | impl Bar for () {
+   | --------------- in this impl...
 LL |     fn foo<'a: 'a>(&'a self) {}
-   |           ^^^^^^^^ lifetimes do not match method in trait
+   |            ^^  -- this lifetime bound makes `'a` early-bound
+   |            |
+   |            `'a` is early-bound
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/traits/bound/on-structs-and-enums-locals.stderr b/tests/ui/traits/bound/on-structs-and-enums-locals.stderr
index 01cf76c62d5..88077f4e4d7 100644
--- a/tests/ui/traits/bound/on-structs-and-enums-locals.stderr
+++ b/tests/ui/traits/bound/on-structs-and-enums-locals.stderr
@@ -1,8 +1,8 @@
-error[E0277]: the trait bound `usize: Trait` is not satisfied
-  --> $DIR/on-structs-and-enums-locals.rs:15:14
+error[E0277]: the trait bound `{integer}: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums-locals.rs:11:12
    |
-LL |     let baz: Foo<usize> = loop { };
-   |              ^^^^^^^^^^ the trait `Trait` is not implemented for `usize`
+LL |         x: 3
+   |            ^ the trait `Trait` is not implemented for `{integer}`
    |
 help: this trait has no implementations, consider adding one
   --> $DIR/on-structs-and-enums-locals.rs:1:1
@@ -15,11 +15,11 @@ note: required by a bound in `Foo`
 LL | struct Foo<T:Trait> {
    |              ^^^^^ required by this bound in `Foo`
 
-error[E0277]: the trait bound `{integer}: Trait` is not satisfied
-  --> $DIR/on-structs-and-enums-locals.rs:11:12
+error[E0277]: the trait bound `usize: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums-locals.rs:15:14
    |
-LL |         x: 3
-   |            ^ the trait `Trait` is not implemented for `{integer}`
+LL |     let baz: Foo<usize> = loop { };
+   |              ^^^^^^^^^^ the trait `Trait` is not implemented for `usize`
    |
 help: this trait has no implementations, consider adding one
   --> $DIR/on-structs-and-enums-locals.rs:1:1
diff --git a/tests/ui/traits/bound/on-structs-and-enums-xc1.stderr b/tests/ui/traits/bound/on-structs-and-enums-xc1.stderr
index 3fb5decb723..1f46415e243 100644
--- a/tests/ui/traits/bound/on-structs-and-enums-xc1.stderr
+++ b/tests/ui/traits/bound/on-structs-and-enums-xc1.stderr
@@ -1,15 +1,3 @@
-error[E0277]: the trait bound `f64: Trait` is not satisfied
-  --> $DIR/on-structs-and-enums-xc1.rs:12:14
-   |
-LL |     let bar: Bar<f64> = return;
-   |              ^^^^^^^^ the trait `Trait` is not implemented for `f64`
-   |
-note: required by a bound in `Bar`
-  --> $DIR/auxiliary/on_structs_and_enums_xc.rs:9:16
-   |
-LL | pub enum Bar<T:Trait> {
-   |                ^^^^^ required by this bound in `Bar`
-
 error[E0277]: the trait bound `{integer}: Trait` is not satisfied
   --> $DIR/on-structs-and-enums-xc1.rs:9:12
    |
@@ -22,6 +10,18 @@ note: required by a bound in `Foo`
 LL | pub struct Foo<T:Trait> {
    |                  ^^^^^ required by this bound in `Foo`
 
+error[E0277]: the trait bound `f64: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums-xc1.rs:12:14
+   |
+LL |     let bar: Bar<f64> = return;
+   |              ^^^^^^^^ the trait `Trait` is not implemented for `f64`
+   |
+note: required by a bound in `Bar`
+  --> $DIR/auxiliary/on_structs_and_enums_xc.rs:9:16
+   |
+LL | pub enum Bar<T:Trait> {
+   |                ^^^^^ required by this bound in `Bar`
+
 error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/next-solver/dont-ice-on-bad-transmute-in-typeck.stderr b/tests/ui/traits/next-solver/dont-ice-on-bad-transmute-in-typeck.stderr
index 2d42fedae43..e1ae981b249 100644
--- a/tests/ui/traits/next-solver/dont-ice-on-bad-transmute-in-typeck.stderr
+++ b/tests/ui/traits/next-solver/dont-ice-on-bad-transmute-in-typeck.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `for<'a> (): Trait<'a>` is not satisfied
-  --> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:7:11
+  --> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:7:22
    |
 LL | fn foo(x: for<'a> fn(<() as Trait<'a>>::Assoc)) {
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait<'a>` is not implemented for `()`
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait<'a>` is not implemented for `()`
    |
 help: this trait has no implementations, consider adding one
   --> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:3:1
diff --git a/tests/ui/traits/next-solver/global-param-env-after-norm.rs b/tests/ui/traits/next-solver/global-param-env-after-norm.rs
new file mode 100644
index 00000000000..0d098db67d3
--- /dev/null
+++ b/tests/ui/traits/next-solver/global-param-env-after-norm.rs
@@ -0,0 +1,15 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+
+struct NewSolver;
+struct OldSolver;
+
+fn foo<T>()
+where
+    T: Iterator<Item = NewSolver>,
+    OldSolver: Into<T::Item>,
+{
+    let x: OldSolver = OldSolver.into();
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.rs b/tests/ui/traits/next-solver/issue-118950-root-region.rs
index 8fe53d6773b..fe336766891 100644
--- a/tests/ui/traits/next-solver/issue-118950-root-region.rs
+++ b/tests/ui/traits/next-solver/issue-118950-root-region.rs
@@ -19,5 +19,6 @@ impl<T> Overlap<T> for T {}
 impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
 //~^ ERROR cannot find type `Missing` in this scope
 //~| ERROR the trait bound `T: Overlap<for<'a> fn(Assoc<'a, T>)>` is not satisfied
+//~| ERROR the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied
 
 fn main() {}
diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
index d2a58e95629..45fa33dff52 100644
--- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr
+++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
@@ -26,6 +26,18 @@ LL | trait ToUnit<'a> {
    | ^^^^^^^^^^^^^^^^
 
  WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
+error[E0277]: the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied
+  --> $DIR/issue-118950-root-region.rs:19:9
+   |
+LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `*const T`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/issue-118950-root-region.rs:8:1
+   |
+LL | trait ToUnit<'a> {
+   | ^^^^^^^^^^^^^^^^
+
 error[E0277]: the trait bound `T: Overlap<for<'a> fn(Assoc<'a, T>)>` is not satisfied
   --> $DIR/issue-118950-root-region.rs:19:47
    |
@@ -37,7 +49,7 @@ help: consider further restricting type parameter `T` with trait `Overlap`
 LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T>, T: Overlap<for<'a> fn(Assoc<'a, T>)> {}
    |                                                                          ++++++++++++++++++++++++++++++++++++++
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 4 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0277, E0412.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/next-solver/non-wf-in-coerce-pointers.stderr b/tests/ui/traits/next-solver/non-wf-in-coerce-pointers.stderr
index 32a7766a638..72be10367da 100644
--- a/tests/ui/traits/next-solver/non-wf-in-coerce-pointers.stderr
+++ b/tests/ui/traits/next-solver/non-wf-in-coerce-pointers.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `(): Wf` is not satisfied
-  --> $DIR/non-wf-in-coerce-pointers.rs:8:17
+  --> $DIR/non-wf-in-coerce-pointers.rs:8:8
    |
 LL |     f: &'static <() as Wf>::Assoc,
-   |                 ^^^^^^^^^^^^^^^^^ the trait `Wf` is not implemented for `()`
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Wf` is not implemented for `()`
    |
 help: this trait has no implementations, consider adding one
   --> $DIR/non-wf-in-coerce-pointers.rs:3:1
diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr
index e91a48f62ae..f5fd9ce9864 100644
--- a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr
+++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr
@@ -4,24 +4,6 @@ error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc: Trait`
 LL |     <T as Trait>::Assoc: Trait,
    |                          ^^^^^
 
-error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc well-formed`
-  --> $DIR/normalize-param-env-4.rs:19:26
-   |
-LL |     <T as Trait>::Assoc: Trait,
-   |                          ^^^^^
-
-error[E0275]: overflow evaluating the requirement `T: Trait`
-  --> $DIR/normalize-param-env-4.rs:32:19
-   |
-LL |     impls_trait::<T>();
-   |                   ^
-   |
-note: required by a bound in `impls_trait`
-  --> $DIR/normalize-param-env-4.rs:15:19
-   |
-LL | fn impls_trait<T: Trait>() {}
-   |                   ^^^^^ required by this bound in `impls_trait`
-
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/next-solver/opaques/duplicate-opaque-type-entries.rs b/tests/ui/traits/next-solver/opaques/duplicate-opaque-type-entries.rs
new file mode 100644
index 00000000000..e0668ac3d39
--- /dev/null
+++ b/tests/ui/traits/next-solver/opaques/duplicate-opaque-type-entries.rs
@@ -0,0 +1,25 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+//@ check-pass
+#![crate_type = "lib"]
+trait Eq<T> {}
+impl<T> Eq<T> for T {}
+trait ConstrainAndEq<T> {}
+impl<T, U> ConstrainAndEq<T> for U
+where
+    T: FnOnce() -> u32,
+    U: FnOnce() -> u32,
+    T: Eq<U>,
+{}
+
+fn constrain_and_eq<T: ConstrainAndEq<U>, U>(_: T, _: U) {}
+fn foo<'a>() -> impl Sized + use<'a> {
+    // This proves `foo<'a>: FnOnce() -> u32` and `foo<'1>: FnOnce() -> u32`,
+    // We constrain both `opaque<'a>` and `opaque<'1>` to `u32`, resulting in
+    // two distinct opaque type uses. Proving `foo<'a>: Eq<foo<'1>>` then
+    // equates the two regions at which point the two opaque type keys are now
+    // equal. This previously caused an ICE.
+    constrain_and_eq(foo::<'a>, foo::<'_>);
+    1u32
+}
diff --git a/tests/ui/traits/next-solver/overflow-plus-ambiguity-normalizes-to-response.rs b/tests/ui/traits/next-solver/overflow-plus-ambiguity-normalizes-to-response.rs
new file mode 100644
index 00000000000..4b20cd11b0d
--- /dev/null
+++ b/tests/ui/traits/next-solver/overflow-plus-ambiguity-normalizes-to-response.rs
@@ -0,0 +1,56 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+
+// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/201>.
+// See comment below on `fn main`.
+
+trait Intersect<U> {
+    type Output;
+}
+
+impl<T, U> Intersect<Vec<U>> for T
+where
+    T: Intersect<U>,
+{
+    type Output = T;
+}
+
+impl Intersect<Cuboid> for Cuboid {
+    type Output = Cuboid;
+}
+
+fn intersect<T, U>(_: &T, _: &U) -> T::Output
+where
+    T: Intersect<U>,
+{
+    todo!()
+}
+
+struct Cuboid;
+impl Cuboid {
+    fn method(&self) {}
+}
+
+fn main() {
+    let x = vec![];
+    // Here we end up trying to normalize `<Cuboid as Intersect<Vec<?0>>>::Output`
+    // for the return type of the function, to constrain `y`. The impl then requires
+    // `Cuboid: Intersect<?0>`, which has two candidates. One that constrains
+    // `?0 = Vec<?1>`, which itself has the same two candidates and ends up leading
+    // to a recursion depth overflow. In the second impl, we constrain `?0 = Cuboid`.
+    //
+    // Floundering leads to us combining the overflow candidate and yes candidate to
+    // overflow. Because the response was overflow, we used to bubble it up to the
+    // parent normalizes-to goal, which caused us to drop its constraint that would
+    // guide us to normalize the associated type mentioned before.
+    //
+    // After this PR, we implement a new floundering "algebra" such that `Overflow OR Maybe`
+    // returns anew `Overflow { keep_constraints: true }`, which means that we don't
+    // need to drop constraints in the parent normalizes-to goal. This allows us to
+    // normalize `y` to `Cuboid`, and allows us to call the method successfully. We
+    // then constrain the `?0` in `let x: Vec<Cuboid> = x` below, so that we don't have
+    // a left over ambiguous goal.
+    let y = intersect(&Cuboid, &x);
+    y.method();
+    let x: Vec<Cuboid> = x;
+}
diff --git a/tests/ui/traits/object/constrain-via-unnecessary-bound.rs b/tests/ui/traits/object/constrain-via-unnecessary-bound.rs
new file mode 100644
index 00000000000..4640d6b3ed5
--- /dev/null
+++ b/tests/ui/traits/object/constrain-via-unnecessary-bound.rs
@@ -0,0 +1,24 @@
+//@ check-pass
+
+// Regression test for <https://github.com/rust-lang/rust/issues/140645>.
+// Test that we lower impossible-to-satisfy associated type bounds, which
+// may for example constrain impl parameters.
+
+pub trait Other {}
+
+pub trait Trait {
+    type Assoc
+    where
+        Self: Sized;
+}
+
+impl Other for dyn Trait {}
+// `dyn Trait<Assoc = ()>` is a different "nominal type" than `dyn Trait`.
+impl Other for dyn Trait<Assoc = ()> {}
+//~^ WARN unnecessary associated type bound for dyn-incompatible associated type
+
+// I hope it's clear that `dyn Trait` (w/o `Assoc`) wouldn't match this impl.
+impl<T> dyn Trait<Assoc = T> {}
+//~^ WARN unnecessary associated type bound for dyn-incompatible associated type
+
+fn main() {}
diff --git a/tests/ui/traits/object/constrain-via-unnecessary-bound.stderr b/tests/ui/traits/object/constrain-via-unnecessary-bound.stderr
new file mode 100644
index 00000000000..4383ca869ea
--- /dev/null
+++ b/tests/ui/traits/object/constrain-via-unnecessary-bound.stderr
@@ -0,0 +1,19 @@
+warning: unnecessary associated type bound for dyn-incompatible associated type
+  --> $DIR/constrain-via-unnecessary-bound.rs:17:26
+   |
+LL | impl Other for dyn Trait<Assoc = ()> {}
+   |                          ^^^^^^^^^^ help: remove this bound
+   |
+   = note: this associated type has a `where Self: Sized` bound, and while the associated type can be specified, it cannot be used because trait objects are never `Sized`
+   = note: `#[warn(unused_associated_type_bounds)]` on by default
+
+warning: unnecessary associated type bound for dyn-incompatible associated type
+  --> $DIR/constrain-via-unnecessary-bound.rs:21:19
+   |
+LL | impl<T> dyn Trait<Assoc = T> {}
+   |                   ^^^^^^^^^ help: remove this bound
+   |
+   = note: this associated type has a `where Self: Sized` bound, and while the associated type can be specified, it cannot be used because trait objects are never `Sized`
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/traits/object/pretty.stderr b/tests/ui/traits/object/pretty.stderr
index 37fe142951d..2f9fdf151f0 100644
--- a/tests/ui/traits/object/pretty.stderr
+++ b/tests/ui/traits/object/pretty.stderr
@@ -154,12 +154,12 @@ error[E0308]: mismatched types
   --> $DIR/pretty.rs:41:56
    |
 LL | fn dyn_has_gat(x: &dyn HasGat<u8, Assoc<bool> = ()>) { x }
-   |                                                     -  ^ expected `()`, found `&dyn HasGat<u8>`
+   |                                                     -  ^ expected `()`, found `&dyn HasGat<u8, Assoc<bool> = ()>`
    |                                                     |
-   |                                                     help: try adding a return type: `-> &dyn HasGat<u8>`
+   |                                                     help: try adding a return type: `-> &dyn HasGat<u8, Assoc<bool> = ()>`
    |
    = note: expected unit type `()`
-              found reference `&dyn HasGat<u8>`
+              found reference `&dyn HasGat<u8, Assoc<bool> = ()>`
 
 error: aborting due to 14 previous errors; 1 warning emitted
 
diff --git a/tests/ui/traits/suggest-remove-deref-issue-140166.rs b/tests/ui/traits/suggest-remove-deref-issue-140166.rs
new file mode 100644
index 00000000000..1b832c7eba5
--- /dev/null
+++ b/tests/ui/traits/suggest-remove-deref-issue-140166.rs
@@ -0,0 +1,18 @@
+trait Trait {}
+
+struct Chars;
+impl Trait for Chars {}
+
+struct FlatMap<T>(T);
+impl<T: Trait> std::fmt::Debug for FlatMap<T> {
+    fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        unimplemented!()
+    }
+}
+
+fn lol() {
+    format_args!("{:?}", FlatMap(&Chars));
+    //~^ ERROR the trait bound `&Chars: Trait` is not satisfied [E0277]
+}
+
+fn main() {}
diff --git a/tests/ui/traits/suggest-remove-deref-issue-140166.stderr b/tests/ui/traits/suggest-remove-deref-issue-140166.stderr
new file mode 100644
index 00000000000..90f24d86d53
--- /dev/null
+++ b/tests/ui/traits/suggest-remove-deref-issue-140166.stderr
@@ -0,0 +1,22 @@
+error[E0277]: the trait bound `&Chars: Trait` is not satisfied
+  --> $DIR/suggest-remove-deref-issue-140166.rs:14:26
+   |
+LL |     format_args!("{:?}", FlatMap(&Chars));
+   |                   ----   ^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `&Chars`
+   |                   |
+   |                   required by a bound introduced by this call
+   |
+   = help: the trait `Trait` is implemented for `Chars`
+note: required for `FlatMap<&Chars>` to implement `Debug`
+  --> $DIR/suggest-remove-deref-issue-140166.rs:7:16
+   |
+LL | impl<T: Trait> std::fmt::Debug for FlatMap<T> {
+   |         -----  ^^^^^^^^^^^^^^^     ^^^^^^^^^^
+   |         |
+   |         unsatisfied trait bound introduced here
+note: required by a bound in `core::fmt::rt::Argument::<'_>::new_debug`
+  --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/transmute/unnecessary-transmutation.fixed b/tests/ui/transmute/unnecessary-transmutation.fixed
index 1a0df143cc5..bf7d769348a 100644
--- a/tests/ui/transmute/unnecessary-transmutation.fixed
+++ b/tests/ui/transmute/unnecessary-transmutation.fixed
@@ -49,6 +49,10 @@ fn main() {
         //~^ ERROR
         let y: char = char::from_u32_unchecked(y);
         //~^ ERROR
+        let y: i32 = u32::from('🐱').cast_signed();
+        //~^ ERROR
+        let y: char = char::from_u32_unchecked(i32::cast_unsigned(y));
+        //~^ ERROR
 
         let x: u16 = i16::cast_unsigned(8i16);
         //~^ ERROR
@@ -72,6 +76,11 @@ fn main() {
         let y: u64 = f64::to_bits(2.0);
         //~^ ERROR
 
+        let y: f64 = f64::from_bits(i64::cast_unsigned(1i64));
+        //~^ ERROR
+        let y: i64 = f64::to_bits(1f64).cast_signed();
+        //~^ ERROR
+
         let z: bool = (1u8 == 1);
         //~^ ERROR
         let z: u8 = (z) as u8;
diff --git a/tests/ui/transmute/unnecessary-transmutation.rs b/tests/ui/transmute/unnecessary-transmutation.rs
index 6b979263c56..b9de529f1cc 100644
--- a/tests/ui/transmute/unnecessary-transmutation.rs
+++ b/tests/ui/transmute/unnecessary-transmutation.rs
@@ -49,6 +49,10 @@ fn main() {
         //~^ ERROR
         let y: char = transmute(y);
         //~^ ERROR
+        let y: i32 = transmute('🐱');
+        //~^ ERROR
+        let y: char = transmute(y);
+        //~^ ERROR
 
         let x: u16 = transmute(8i16);
         //~^ ERROR
@@ -72,6 +76,11 @@ fn main() {
         let y: u64 = transmute(2.0);
         //~^ ERROR
 
+        let y: f64 = transmute(1i64);
+        //~^ ERROR
+        let y: i64 = transmute(1f64);
+        //~^ ERROR
+
         let z: bool = transmute(1u8);
         //~^ ERROR
         let z: u8 = transmute(z);
diff --git a/tests/ui/transmute/unnecessary-transmutation.stderr b/tests/ui/transmute/unnecessary-transmutation.stderr
index b661aa13c98..a19f1bebf16 100644
--- a/tests/ui/transmute/unnecessary-transmutation.stderr
+++ b/tests/ui/transmute/unnecessary-transmutation.stderr
@@ -154,82 +154,108 @@ LL |         let y: char = transmute(y);
    = help: consider `char::from_u32(…).unwrap()`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:53:22
+  --> $DIR/unnecessary-transmutation.rs:52:22
+   |
+LL |         let y: i32 = transmute('🐱');
+   |                      ^^^^^^^^^^^^^^^ help: replace this with: `u32::from('🐱').cast_signed()`
+
+error: unnecessary transmute
+  --> $DIR/unnecessary-transmutation.rs:54:23
+   |
+LL |         let y: char = transmute(y);
+   |                       ^^^^^^^^^^^^ help: replace this with: `char::from_u32_unchecked(i32::cast_unsigned(y))`
+   |
+   = help: consider `char::from_u32(i32::cast_unsigned(…)).unwrap()`
+
+error: unnecessary transmute
+  --> $DIR/unnecessary-transmutation.rs:57:22
    |
 LL |         let x: u16 = transmute(8i16);
    |                      ^^^^^^^^^^^^^^^ help: replace this with: `i16::cast_unsigned(8i16)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:55:22
+  --> $DIR/unnecessary-transmutation.rs:59:22
    |
 LL |         let x: i16 = transmute(x);
    |                      ^^^^^^^^^^^^ help: replace this with: `u16::cast_signed(x)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:57:22
+  --> $DIR/unnecessary-transmutation.rs:61:22
    |
 LL |         let x: u32 = transmute(4i32);
    |                      ^^^^^^^^^^^^^^^ help: replace this with: `i32::cast_unsigned(4i32)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:59:22
+  --> $DIR/unnecessary-transmutation.rs:63:22
    |
 LL |         let x: i32 = transmute(x);
    |                      ^^^^^^^^^^^^ help: replace this with: `u32::cast_signed(x)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:61:22
+  --> $DIR/unnecessary-transmutation.rs:65:22
    |
 LL |         let x: u64 = transmute(7i64);
    |                      ^^^^^^^^^^^^^^^ help: replace this with: `i64::cast_unsigned(7i64)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:63:22
+  --> $DIR/unnecessary-transmutation.rs:67:22
    |
 LL |         let x: i64 = transmute(x);
    |                      ^^^^^^^^^^^^ help: replace this with: `u64::cast_signed(x)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:66:22
+  --> $DIR/unnecessary-transmutation.rs:70:22
    |
 LL |         let y: f32 = transmute(1u32);
    |                      ^^^^^^^^^^^^^^^ help: replace this with: `f32::from_bits(1u32)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:68:22
+  --> $DIR/unnecessary-transmutation.rs:72:22
    |
 LL |         let y: u32 = transmute(y);
    |                      ^^^^^^^^^^^^ help: replace this with: `f32::to_bits(y)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:70:22
+  --> $DIR/unnecessary-transmutation.rs:74:22
    |
 LL |         let y: f64 = transmute(3u64);
    |                      ^^^^^^^^^^^^^^^ help: replace this with: `f64::from_bits(3u64)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:72:22
+  --> $DIR/unnecessary-transmutation.rs:76:22
    |
 LL |         let y: u64 = transmute(2.0);
    |                      ^^^^^^^^^^^^^^ help: replace this with: `f64::to_bits(2.0)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:75:23
+  --> $DIR/unnecessary-transmutation.rs:79:22
+   |
+LL |         let y: f64 = transmute(1i64);
+   |                      ^^^^^^^^^^^^^^^ help: replace this with: `f64::from_bits(i64::cast_unsigned(1i64))`
+
+error: unnecessary transmute
+  --> $DIR/unnecessary-transmutation.rs:81:22
+   |
+LL |         let y: i64 = transmute(1f64);
+   |                      ^^^^^^^^^^^^^^^ help: replace this with: `f64::to_bits(1f64).cast_signed()`
+
+error: unnecessary transmute
+  --> $DIR/unnecessary-transmutation.rs:84:23
    |
 LL |         let z: bool = transmute(1u8);
    |                       ^^^^^^^^^^^^^^ help: replace this with: `(1u8 == 1)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:77:21
+  --> $DIR/unnecessary-transmutation.rs:86:21
    |
 LL |         let z: u8 = transmute(z);
    |                     ^^^^^^^^^^^^ help: replace this with: `(z) as u8`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:82:21
+  --> $DIR/unnecessary-transmutation.rs:91:21
    |
 LL |         let z: i8 = transmute(z);
    |                     ^^^^^^^^^^^^ help: replace this with: `(z) as i8`
 
-error: aborting due to 32 previous errors
+error: aborting due to 36 previous errors
 
diff --git a/tests/ui/treat-err-as-bug/err.rs b/tests/ui/treat-err-as-bug/err.rs
index 9f0e293b4cb..7868c06fee1 100644
--- a/tests/ui/treat-err-as-bug/err.rs
+++ b/tests/ui/treat-err-as-bug/err.rs
@@ -1,7 +1,5 @@
 //@ compile-flags: -Ztreat-err-as-bug
 //@ failure-status: 101
-//@ error-pattern: aborting due to `-Z treat-err-as-bug=1`
-//@ error-pattern: [eval_static_initializer] evaluating initializer of static `C`
 //@ normalize-stderr: "note: .*\n\n" -> ""
 //@ normalize-stderr: "thread 'rustc' panicked.*:\n.*\n" -> ""
 //@ rustc-env:RUST_BACKTRACE=0
@@ -10,3 +8,6 @@
 
 pub static C: u32 = 0 - 1;
 //~^ ERROR could not evaluate static initializer
+
+//~? RAW aborting due to `-Z treat-err-as-bug=1`
+//~? RAW [eval_static_initializer] evaluating initializer of static `C`
diff --git a/tests/ui/treat-err-as-bug/err.stderr b/tests/ui/treat-err-as-bug/err.stderr
index df5fed3fb8e..2049df22000 100644
--- a/tests/ui/treat-err-as-bug/err.stderr
+++ b/tests/ui/treat-err-as-bug/err.stderr
@@ -1,5 +1,5 @@
 error: internal compiler error[E0080]: could not evaluate static initializer
-  --> $DIR/err.rs:11:21
+  --> $DIR/err.rs:9:21
    |
 LL | pub static C: u32 = 0 - 1;
    |                     ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
diff --git a/tests/ui/treat-err-as-bug/panic-causes-oom-112708.rs b/tests/ui/treat-err-as-bug/panic-causes-oom-112708.rs
index cfb2d7c5218..3f963888c30 100644
--- a/tests/ui/treat-err-as-bug/panic-causes-oom-112708.rs
+++ b/tests/ui/treat-err-as-bug/panic-causes-oom-112708.rs
@@ -1,6 +1,5 @@
 //@ compile-flags: -Ztreat-err-as-bug
 //@ dont-check-failure-status
-//@ error-pattern: aborting due to `-Z treat-err-as-bug=1`
 //@ dont-check-compiler-stderr
 //@ rustc-env:RUST_BACKTRACE=0
 
@@ -8,3 +7,5 @@ fn main() {
     #[deny(while_true)]
     while true {} //~ ERROR denote infinite loops with `loop { ... }`
 }
+
+//~? RAW aborting due to `-Z treat-err-as-bug=1`
diff --git a/tests/ui/treat-err-as-bug/span_delayed_bug.rs b/tests/ui/treat-err-as-bug/span_delayed_bug.rs
index a242d11129f..4681a8fc1ee 100644
--- a/tests/ui/treat-err-as-bug/span_delayed_bug.rs
+++ b/tests/ui/treat-err-as-bug/span_delayed_bug.rs
@@ -1,7 +1,5 @@
 //@ compile-flags: -Ztreat-err-as-bug -Zeagerly-emit-delayed-bugs
 //@ failure-status: 101
-//@ error-pattern: aborting due to `-Z treat-err-as-bug=1`
-//@ error-pattern: [trigger_delayed_bug] triggering a delayed bug for testing incremental
 //@ normalize-stderr: "note: .*\n\n" -> ""
 //@ normalize-stderr: "thread 'rustc' panicked.*:\n.*\n" -> ""
 //@ rustc-env:RUST_BACKTRACE=0
@@ -10,3 +8,6 @@
 
 #[rustc_delayed_bug_from_inside_query]
 fn main() {} //~ ERROR delayed bug triggered by #[rustc_delayed_bug_from_inside_query]
+
+//~? RAW aborting due to `-Z treat-err-as-bug=1`
+//~? RAW [trigger_delayed_bug] triggering a delayed bug for testing incremental
diff --git a/tests/ui/treat-err-as-bug/span_delayed_bug.stderr b/tests/ui/treat-err-as-bug/span_delayed_bug.stderr
index 1c8d279c14c..88983e95cee 100644
--- a/tests/ui/treat-err-as-bug/span_delayed_bug.stderr
+++ b/tests/ui/treat-err-as-bug/span_delayed_bug.stderr
@@ -1,5 +1,5 @@
 error: internal compiler error: delayed bug triggered by #[rustc_delayed_bug_from_inside_query]
-  --> $DIR/span_delayed_bug.rs:12:1
+  --> $DIR/span_delayed_bug.rs:10:1
    |
 LL | fn main() {}
    | ^^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.rs b/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.rs
new file mode 100644
index 00000000000..bfaa48585ef
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.rs
@@ -0,0 +1,16 @@
+// https://github.com/rust-lang/rust/issues/140731
+// This tests that there's no def path conflict between the
+// remapped lifetime and the lifetime present in the source.
+
+#![feature(impl_trait_in_assoc_type)]
+
+trait Trait<'a> {}
+
+impl<'a> Trait<'a> for u32 {
+    type Opq2 = impl for<'a> Trait<'a>;
+    //~^ ERROR: unconstrained opaque type
+    //~| ERROR: type `Opq2` is not a member of trait `Trait`
+    //~| ERROR: lifetime name `'a` shadows a lifetime name that is already in scope
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.stderr b/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.stderr
new file mode 100644
index 00000000000..e1544c5911b
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.stderr
@@ -0,0 +1,26 @@
+error[E0437]: type `Opq2` is not a member of trait `Trait`
+  --> $DIR/lifetime-def-path-conflict-40731.rs:10:5
+   |
+LL |     type Opq2 = impl for<'a> Trait<'a>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `Trait`
+
+error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope
+  --> $DIR/lifetime-def-path-conflict-40731.rs:10:26
+   |
+LL | impl<'a> Trait<'a> for u32 {
+   |      -- first declared here
+LL |     type Opq2 = impl for<'a> Trait<'a>;
+   |                          ^^ lifetime `'a` already in scope
+
+error: unconstrained opaque type
+  --> $DIR/lifetime-def-path-conflict-40731.rs:10:17
+   |
+LL |     type Opq2 = impl for<'a> Trait<'a>;
+   |                 ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `Opq2` must be used in combination with a concrete type within the same impl
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0437, E0496.
+For more information about an error, try `rustc --explain E0437`.
diff --git a/tests/ui/type-inference/regression-issue-81317.rs b/tests/ui/type-inference/regression-issue-81317.rs
new file mode 100644
index 00000000000..0b1266e6a0f
--- /dev/null
+++ b/tests/ui/type-inference/regression-issue-81317.rs
@@ -0,0 +1,71 @@
+// Regression test for #81317: type can no longer be infered as of 1.49
+//
+// The problem is that the xor operator and the index.into() call
+// each have two candidate impls that could apply
+// { S as BitXor<S>, S as BitXor<&'a S> } for xor and
+// { T::I as Into<u64>, T::I as Into<S> } for index.into()
+// previously inference was able to infer that the only valid combination was
+// S as BitXor<S> and T::I as Into<S>
+//
+// after rust-lang/rust#73905 this is no longer infered
+//
+// the error message could be better e.g.
+// when iv is unused or has an an explicitly specified type S
+// there is currently the following help message
+//
+// error[E0284]: type annotations needed
+//   --> src/main.rs:13:24
+//    |
+// 44 |     let iv = S ^ index.into();
+//    |                -       ^^^^
+//    |                |
+//    |                type must be known at this point
+//    |
+//    = note: cannot satisfy `<S as BitXor<_>>::Output == _`
+// help: try using a fully qualified path to specify the expected types
+//    |
+// 44 -     let iv = S ^ index.into();
+// 44 +     let iv = S ^ <<T as P>::I as Into<T>>::into(index);
+//
+// this is better as it's actually sufficent to fix the problem,
+// while just specifying the type of iv as currently suggested is insufficent
+//
+//@ check-fail
+
+use std::ops::BitXor;
+
+pub struct S;
+
+pub trait P {
+    type I: Into<u64> + Into<S>;
+}
+
+pub fn decrypt_portion<T: P>(index: T::I) {
+    let iv = S ^ index.into();
+    //~^ ERROR type annotations needed
+    &iv.to_bytes_be();
+}
+
+impl S {
+    fn to_bytes_be(&self) -> &[u8] {
+        &[]
+    }
+}
+
+impl BitXor for S {
+    type Output = S;
+
+    fn bitxor(self, _rhs: Self) -> Self::Output {
+        S
+    }
+}
+
+impl<'a> BitXor<&'a S> for S {
+    type Output = S;
+
+    fn bitxor(self, _rhs: &'a S) -> Self::Output {
+        S
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/type-inference/regression-issue-81317.stderr b/tests/ui/type-inference/regression-issue-81317.stderr
new file mode 100644
index 00000000000..fcd3fca06e1
--- /dev/null
+++ b/tests/ui/type-inference/regression-issue-81317.stderr
@@ -0,0 +1,17 @@
+error[E0282]: type annotations needed
+  --> $DIR/regression-issue-81317.rs:44:9
+   |
+LL |     let iv = S ^ index.into();
+   |         ^^
+LL |
+LL |     &iv.to_bytes_be();
+   |      -- type must be known at this point
+   |
+help: consider giving `iv` an explicit type
+   |
+LL |     let iv: /* Type */ = S ^ index.into();
+   |           ++++++++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/type/type-check/point-at-inference-4.rs b/tests/ui/type/type-check/point-at-inference-4.rs
index 258374f299e..504e6aa6db0 100644
--- a/tests/ui/type/type-check/point-at-inference-4.rs
+++ b/tests/ui/type/type-check/point-at-inference-4.rs
@@ -3,7 +3,6 @@ struct S<A, B>(Option<(A, B)>);
 impl<A, B> S<A, B> {
     fn infer(&self, a: A, b: B) {}
     //~^ NOTE method defined here
-    //~| NOTE
 }
 
 fn main() {
diff --git a/tests/ui/type/type-check/point-at-inference-4.stderr b/tests/ui/type/type-check/point-at-inference-4.stderr
index adfb0cebf26..8630f75d119 100644
--- a/tests/ui/type/type-check/point-at-inference-4.stderr
+++ b/tests/ui/type/type-check/point-at-inference-4.stderr
@@ -1,5 +1,5 @@
 error[E0061]: this method takes 2 arguments but 1 argument was supplied
-  --> $DIR/point-at-inference-4.rs:11:7
+  --> $DIR/point-at-inference-4.rs:10:7
    |
 LL |     s.infer(0i32);
    |       ^^^^^------ argument #2 is missing
@@ -15,7 +15,7 @@ LL |     s.infer(0i32, /* b */);
    |                 +++++++++
 
 error[E0308]: mismatched types
-  --> $DIR/point-at-inference-4.rs:18:24
+  --> $DIR/point-at-inference-4.rs:17:24
    |
 LL |     s.infer(0i32);
    |     -       ---- this argument has type `i32`...
diff --git a/tests/ui/unboxed-closures/arg-constrained-after-closure-inference.rs b/tests/ui/unboxed-closures/arg-constrained-after-closure-inference.rs
new file mode 100644
index 00000000000..343a27616d1
--- /dev/null
+++ b/tests/ui/unboxed-closures/arg-constrained-after-closure-inference.rs
@@ -0,0 +1,16 @@
+#![feature(unboxed_closures)]
+
+//@ check-pass
+
+// Regression test for #131758. We only know the type of `x` after closure upvar
+// inference is done, even if we don't need to structurally resolve the type of `x`.
+
+trait Foo {}
+
+impl<T: Fn<(i32,)>> Foo for T {}
+
+fn baz<T: Foo>(_: T) {}
+
+fn main() {
+    baz(|x| ());
+}
diff --git a/tests/ui/unpretty/exhaustive-asm.hir.stdout b/tests/ui/unpretty/exhaustive-asm.hir.stdout
index 5a642dff6f2..810db69bff1 100644
--- a/tests/ui/unpretty/exhaustive-asm.hir.stdout
+++ b/tests/ui/unpretty/exhaustive-asm.hir.stdout
@@ -27,5 +27,6 @@ mod expressions {
 mod items {
     /// ItemKind::GlobalAsm
     mod item_global_asm {/// ItemKind::GlobalAsm
-        global_asm! (".globl my_asm_func") }
+        global_asm! (".globl my_asm_func");
     }
+}
diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout
index d2c379d4366..c20f123b16e 100644
--- a/tests/ui/unpretty/exhaustive.hir.stdout
+++ b/tests/ui/unpretty/exhaustive.hir.stdout
@@ -8,7 +8,28 @@
 // Note: the HIR revision includes a `.stderr` file because there are some
 // errors that only occur once we get past the AST.
 
-#![feature(auto_traits)]#![feature(box_patterns)]#![feature(builtin_syntax)]#![feature(concat_idents)]#![feature(const_trait_impl)]#![feature(decl_macro)]#![feature(deref_patterns)]#![feature(dyn_star)]#![feature(explicit_tail_calls)]#![feature(gen_blocks)]#![feature(more_qualified_paths)]#![feature(never_patterns)]#![feature(never_type)]#![feature(pattern_types)]#![feature(pattern_type_macro)]#![feature(prelude_import)]#![feature(specialization)]#![feature(trace_macros)]#![feature(trait_alias)]#![feature(try_blocks)]#![feature(yeet_expr)]#![allow(incomplete_features)]
+#![feature(auto_traits)]
+#![feature(box_patterns)]
+#![feature(builtin_syntax)]
+#![feature(concat_idents)]
+#![feature(const_trait_impl)]
+#![feature(decl_macro)]
+#![feature(deref_patterns)]
+#![feature(dyn_star)]
+#![feature(explicit_tail_calls)]
+#![feature(gen_blocks)]
+#![feature(more_qualified_paths)]
+#![feature(never_patterns)]
+#![feature(never_type)]
+#![feature(pattern_types)]
+#![feature(pattern_type_macro)]
+#![feature(prelude_import)]
+#![feature(specialization)]
+#![feature(trace_macros)]
+#![feature(trait_alias)]
+#![feature(try_blocks)]
+#![feature(yeet_expr)]
+#![allow(incomplete_features)]
 #[prelude_import]
 use std::prelude::rust_2024::*;
 #[macro_use]
@@ -33,20 +54,25 @@ mod prelude {
 /*!
      * inner multi-line doc comment
      */
-#[doc = "inner doc attribute"]#[allow(dead_code, unused_variables)]#[no_std]
+#[doc = "inner doc attribute"]
+#[allow(dead_code, unused_variables)]
+#[no_std]
 mod attributes {//! inner single-line doc comment
     /*!
      * inner multi-line doc comment
      */
-    #![doc =
-    "inner doc attribute"]#![allow(dead_code, unused_variables)]#![no_std]
+    #![doc = "inner doc attribute"]
+    #![allow(dead_code, unused_variables)]
+    #![no_std]
 
     /// outer single-line doc comment
     /**
      * outer multi-line doc comment
      */
-    #[doc =
-    "outer doc attribute"]#[doc = "macro"]#[allow()]#[attr = Repr([ReprC])]
+    #[doc = "outer doc attribute"]
+    #[doc = "macro"]
+    #[allow()]
+    #[attr = Repr([ReprC])]
     struct Struct;
 }
 
@@ -147,32 +173,31 @@ mod expressions {
     fn expr_for_loop() {
         let x;
         {
-                let _t =
-                    match #[lang = "into_iter"](x) {
-                            mut iter =>
-                                loop {
-                                        match #[lang = "next"](&mut iter) {
-                                                #[lang = "None"] {} => break,
-                                                #[lang = "Some"] {  0: _ } => { }
-                                            }
-                                    },
-                        };
-                _t
-            };
+            let _t =
+                match #[lang = "into_iter"](x) {
+                    mut iter =>
+                        loop {
+                            match #[lang = "next"](&mut iter) {
+                                #[lang = "None"] {} => break,
+                                #[lang = "Some"] {  0: _ } => { }
+                            }
+                        },
+                };
+            _t
+        };
         {
-                let _t =
-                    match #[lang = "into_iter"](x) {
-                            mut iter =>
-                                'a:
-                                    loop {
-                                        match #[lang = "next"](&mut iter) {
-                                                #[lang = "None"] {} => break,
-                                                #[lang = "Some"] {  0: _ } => { }
-                                            }
-                                    },
-                        };
-                _t
-            }
+            let _t =
+                match #[lang = "into_iter"](x) {
+                    mut iter =>
+                        'a: loop {
+                            match #[lang = "next"](&mut iter) {
+                                #[lang = "None"] {} => break,
+                                #[lang = "Some"] {  0: _ } => { }
+                            }
+                        },
+                };
+            _t
+        }
     }
 
     /// ExprKind::Loop
@@ -357,12 +382,11 @@ mod expressions {
     fn expr_try() {
         let expr;
         match #[lang = "branch"](expr) {
-                #[lang = "Break"] {  0: residual } =>
-                    #[allow(unreachable_code)]
-                    return #[lang = "from_residual"](residual),
-                #[lang = "Continue"] {  0: val } => #[allow(unreachable_code)]
-                    val,
-            };
+            #[lang = "Break"] {  0: residual } => #[allow(unreachable_code)]
+                return #[lang = "from_residual"](residual),
+            #[lang = "Continue"] {  0: val } => #[allow(unreachable_code)]
+                val,
+        };
     }
     /// ExprKind::Yield
     fn expr_yield() { yield (); yield true; }
diff --git a/tests/ui/unpretty/hir-tree.rs b/tests/ui/unpretty/hir-tree.rs
index 3388c60c425..41ac51641c5 100644
--- a/tests/ui/unpretty/hir-tree.rs
+++ b/tests/ui/unpretty/hir-tree.rs
@@ -3,8 +3,9 @@
 //@ check-stdout
 //@ dont-check-compiler-stdout
 //@ dont-check-compiler-stderr
-//@ regex-error-pattern: Hello, Rustaceans!
 
 fn main() {
     println!("Hello, Rustaceans!");
 }
+
+//~? RAW Hello, Rustaceans!
diff --git a/tests/ui/use/import_trait_associated_item_bad.rs b/tests/ui/use/import_trait_associated_item_bad.rs
new file mode 100644
index 00000000000..d3d2a8e83cd
--- /dev/null
+++ b/tests/ui/use/import_trait_associated_item_bad.rs
@@ -0,0 +1,18 @@
+#![feature(import_trait_associated_functions)]
+#![feature(min_generic_const_args)]
+#![allow(incomplete_features)]
+
+trait Trait {
+    type AssocTy;
+    const CONST: usize;
+}
+
+use Trait::AssocTy;
+type Alias1 = AssocTy; //~ ERROR ambiguous associated type
+type Alias2 = self::AssocTy; //~ ERROR ambiguous associated type
+
+use Trait::CONST;
+type Alias3 = [u8; CONST]; //~ ERROR ambiguous associated constant
+type Alias4 = [u8; self::CONST]; //~ ERROR ambiguous associated constant
+
+fn main() {}
diff --git a/tests/ui/use/import_trait_associated_item_bad.stderr b/tests/ui/use/import_trait_associated_item_bad.stderr
new file mode 100644
index 00000000000..d5cd5d37bd7
--- /dev/null
+++ b/tests/ui/use/import_trait_associated_item_bad.stderr
@@ -0,0 +1,49 @@
+error[E0223]: ambiguous associated type
+  --> $DIR/import_trait_associated_item_bad.rs:11:15
+   |
+LL | type Alias1 = AssocTy;
+   |               ^^^^^^^
+   |
+help: if there were a type named `Example` that implemented `Trait`, you could use the fully-qualified path
+   |
+LL | type Alias1 = <Example as Trait>::AssocTy;
+   |               ++++++++++++++++++++
+
+error[E0223]: ambiguous associated type
+  --> $DIR/import_trait_associated_item_bad.rs:12:15
+   |
+LL | type Alias2 = self::AssocTy;
+   |               ^^^^^^^^^^^^^
+   |
+help: if there were a type named `Example` that implemented `Trait`, you could use the fully-qualified path
+   |
+LL - type Alias2 = self::AssocTy;
+LL + type Alias2 = <Example as Trait>::AssocTy;
+   |
+
+error[E0223]: ambiguous associated constant
+  --> $DIR/import_trait_associated_item_bad.rs:15:20
+   |
+LL | type Alias3 = [u8; CONST];
+   |                    ^^^^^
+   |
+help: if there were a type named `Example` that implemented `Trait`, you could use the fully-qualified path
+   |
+LL | type Alias3 = [u8; <Example as Trait>::CONST];
+   |                    ++++++++++++++++++++
+
+error[E0223]: ambiguous associated constant
+  --> $DIR/import_trait_associated_item_bad.rs:16:20
+   |
+LL | type Alias4 = [u8; self::CONST];
+   |                    ^^^^^^^^^^^
+   |
+help: if there were a type named `Example` that implemented `Trait`, you could use the fully-qualified path
+   |
+LL - type Alias4 = [u8; self::CONST];
+LL + type Alias4 = [u8; <Example as Trait>::CONST];
+   |
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0223`.
diff --git a/tests/ui/use/import_trait_associated_item_glob.rs b/tests/ui/use/import_trait_associated_item_glob.rs
new file mode 100644
index 00000000000..8a712514ed5
--- /dev/null
+++ b/tests/ui/use/import_trait_associated_item_glob.rs
@@ -0,0 +1,17 @@
+//@ check-pass
+
+#![feature(import_trait_associated_functions)]
+
+trait Trait: Default {
+    fn f() -> Self { Default::default() }
+    fn g() -> Self { Default::default() }
+}
+
+impl Trait for u8 {}
+
+use Trait::*;
+
+fn main() {
+    let _: u8 = f();
+    let _: u8 = g();
+}
diff --git a/tests/ui/use/use-from-trait-xc.rs b/tests/ui/use/use-from-trait-xc.rs
index b030892aa26..220bf8cad46 100644
--- a/tests/ui/use/use-from-trait-xc.rs
+++ b/tests/ui/use/use-from-trait-xc.rs
@@ -6,7 +6,7 @@ use use_from_trait_xc::Trait::foo;
 //~^ ERROR `use` associated items of traits is unstable [E0658]
 
 use use_from_trait_xc::Trait::Assoc;
-//~^ ERROR `Assoc` is not directly importable
+//~^ ERROR `use` associated items of traits is unstable [E0658]
 
 use use_from_trait_xc::Trait::CONST;
 //~^ ERROR `use` associated items of traits is unstable [E0658]
diff --git a/tests/ui/use/use-from-trait-xc.stderr b/tests/ui/use/use-from-trait-xc.stderr
index 0f8440aa530..c8ee29b18d0 100644
--- a/tests/ui/use/use-from-trait-xc.stderr
+++ b/tests/ui/use/use-from-trait-xc.stderr
@@ -8,11 +8,15 @@ LL | use use_from_trait_xc::Trait::foo;
    = help: add `#![feature(import_trait_associated_functions)]` 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[E0253]: `Assoc` is not directly importable
+error[E0658]: `use` associated items of traits is unstable
   --> $DIR/use-from-trait-xc.rs:8:5
    |
 LL | use use_from_trait_xc::Trait::Assoc;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
+   = help: add `#![feature(import_trait_associated_functions)]` 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]: `use` associated items of traits is unstable
   --> $DIR/use-from-trait-xc.rs:11:5
@@ -74,5 +78,5 @@ LL | struct Foo;
 
 error: aborting due to 9 previous errors
 
-Some errors have detailed explanations: E0253, E0432, E0603, E0658.
-For more information about an error, try `rustc --explain E0253`.
+Some errors have detailed explanations: E0432, E0603, E0658.
+For more information about an error, try `rustc --explain E0432`.
diff --git a/tests/ui/use/use-from-trait.rs b/tests/ui/use/use-from-trait.rs
index 89b7aaa4ba3..cab661a29e8 100644
--- a/tests/ui/use/use-from-trait.rs
+++ b/tests/ui/use/use-from-trait.rs
@@ -1,5 +1,5 @@
 use Trait::foo; //~ ERROR `use` associated items of traits is unstable [E0658]
-use Trait::Assoc; //~ ERROR `Assoc` is not directly importable
+use Trait::Assoc; //~ ERROR `use` associated items of traits is unstable [E0658]
 use Trait::C; //~ ERROR `use` associated items of traits is unstable [E0658]
 
 use Foo::new; //~ ERROR unresolved import `Foo` [E0432]
diff --git a/tests/ui/use/use-from-trait.stderr b/tests/ui/use/use-from-trait.stderr
index 2dd78a35452..63cfcc20750 100644
--- a/tests/ui/use/use-from-trait.stderr
+++ b/tests/ui/use/use-from-trait.stderr
@@ -8,11 +8,15 @@ LL | use Trait::foo;
    = help: add `#![feature(import_trait_associated_functions)]` 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[E0253]: `Assoc` is not directly importable
+error[E0658]: `use` associated items of traits is unstable
   --> $DIR/use-from-trait.rs:2:5
    |
 LL | use Trait::Assoc;
-   |     ^^^^^^^^^^^^ cannot be imported directly
+   |     ^^^^^^^^^^^^
+   |
+   = note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
+   = help: add `#![feature(import_trait_associated_functions)]` 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]: `use` associated items of traits is unstable
   --> $DIR/use-from-trait.rs:3:5
@@ -38,5 +42,5 @@ LL | use Foo::C2;
 
 error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0253, E0432, E0658.
-For more information about an error, try `rustc --explain E0253`.
+Some errors have detailed explanations: E0432, E0658.
+For more information about an error, try `rustc --explain E0432`.
diff --git a/tests/ui/wf/check-wf-of-normalized-signature.rs b/tests/ui/wf/check-wf-of-normalized-signature.rs
new file mode 100644
index 00000000000..5fda69601d9
--- /dev/null
+++ b/tests/ui/wf/check-wf-of-normalized-signature.rs
@@ -0,0 +1,24 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@ check-pass
+
+// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/194>.
+// Ensure that we check the well-formedness of `<Check as Mode>::Output<T>` after normalizing
+// the type to `()`, since we only imply outlives bounds from the normalized signature, so we
+// don't know (e.g.) that `&mut T` is WF.
+
+
+trait Mode {
+    type Output<T>;
+    fn from_mut<T>(_r: &mut Self::Output<T>) -> Self::Output<&mut T>;
+}
+
+struct Check;
+
+impl Mode for Check {
+    type Output<T> = ();
+    fn from_mut<T>(_r: &mut Self::Output<T>) -> Self::Output<&mut T> {}
+}
+
+fn main() {}
diff --git a/tests/ui/wf/wf-normalization-sized.next.stderr b/tests/ui/wf/wf-normalization-sized.next.stderr
index 66c4f214415..804dd0a252d 100644
--- a/tests/ui/wf/wf-normalization-sized.next.stderr
+++ b/tests/ui/wf/wf-normalization-sized.next.stderr
@@ -8,7 +8,7 @@ LL | const _: <[[[[[[u8]]]]]] as WellUnformed>::RequestNormalize = ();
    = note: slice and array elements must have `Sized` type
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
-  --> $DIR/wf-normalization-sized.rs:22:11
+  --> $DIR/wf-normalization-sized.rs:21:11
    |
 LL | const _: <Vec<str> as WellUnformed>::RequestNormalize = ();
    |           ^^^^^^^^ doesn't have a size known at compile-time
@@ -17,27 +17,6 @@ LL | const _: <Vec<str> as WellUnformed>::RequestNormalize = ();
 note: required by an implicit `Sized` bound in `Vec`
   --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
 
-error[E0277]: the size for values of type `[[[[[u8]]]]]` cannot be known at compilation time
-  --> $DIR/wf-normalization-sized.rs:19:11
-   |
-LL | const _: <[[[[[[u8]]]]]] as WellUnformed>::RequestNormalize = ();
-   |           ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `[[[[[u8]]]]]`
-   = note: slice and array elements must have `Sized` type
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0277]: the size for values of type `str` cannot be known at compilation time
-  --> $DIR/wf-normalization-sized.rs:22:11
-   |
-LL | const _: <Vec<str> as WellUnformed>::RequestNormalize = ();
-   |           ^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `str`
-note: required by an implicit `Sized` bound in `Vec`
-  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/wf/wf-normalization-sized.rs b/tests/ui/wf/wf-normalization-sized.rs
index 5396cc8b32a..e695fd93fb0 100644
--- a/tests/ui/wf/wf-normalization-sized.rs
+++ b/tests/ui/wf/wf-normalization-sized.rs
@@ -18,9 +18,7 @@ impl<T: ?Sized> WellUnformed for T {
 
 const _: <[[[[[[u8]]]]]] as WellUnformed>::RequestNormalize = ();
 //[next]~^ ERROR the size for values of type `[[[[[u8]]]]]` cannot be known at compilation time
-//[next]~| ERROR the size for values of type `[[[[[u8]]]]]` cannot be known at compilation time
 const _: <Vec<str> as WellUnformed>::RequestNormalize = ();
 //[next]~^ ERROR the size for values of type `str` cannot be known at compilation time
-//[next]~| ERROR the size for values of type `str` cannot be known at compilation time
 
 fn main() {}
diff --git a/triagebot.toml b/triagebot.toml
index 422996cb200..1f0afdc4442 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -1001,7 +1001,15 @@ message = "This PR changes how GCC is built. Consider updating src/bootstrap/dow
 message = "This PR changes a file inside `tests/crashes`. If a crash was fixed, please move into the corresponding `ui` subdir and add 'Fixes #<issueNr>' to the PR description to autoclose the issue upon merge."
 
 [mentions."tests/rustdoc-json"]
-cc = ["@aDotInTheVoid"]
+message = """
+These commits modify `tests/rustdoc-json`.
+rustdoc-json is a **public** (but unstable) interface.
+
+Please ensure that if you've changed the output:
+- It's intentional.
+- The `FORMAT_VERSION` in `src/librustdoc-json-types` is bumped if necessary.
+"""
+cc = ["@aDotInTheVoid", "@obi1kenobi"]
 
 [mentions."tests/ui/deriving/deriving-all-codegen.stdout"]
 message = "Changes to the code generated for builtin derived traits."
@@ -1161,7 +1169,6 @@ compiler = [
     "@BoxyUwU",
     "@compiler-errors",
     "@davidtwco",
-    "@estebank",
     "@fee1-dead",
     "@fmease",
     "@jieyouxu",
@@ -1221,14 +1228,12 @@ incremental = [
 diagnostics = [
     "@compiler-errors",
     "@davidtwco",
-    "@estebank",
     "@oli-obk",
     "@chenyukang",
 ]
 parser = [
     "@compiler-errors",
     "@davidtwco",
-    "@estebank",
     "@nnethercote",
     "@petrochenkov",
     "@spastorino",
@@ -1236,7 +1241,6 @@ parser = [
 lexer = [
     "@nnethercote",
     "@petrochenkov",
-    "@estebank",
     "@chenyukang",
 ]
 arena = [
@@ -1268,7 +1272,6 @@ borrowck = [
 ]
 ast_lowering = [
     "@compiler-errors",
-    "@estebank",
     "@spastorino",
 ]
 debuginfo = [
@@ -1394,3 +1397,7 @@ compiletest = [
 # Enable issue transfers within the org
 # Documentation at: https://forge.rust-lang.org/triagebot/transfer.html
 [transfer]
+
+# Enable `@rustbot note` functionality
+# Documentation at: https://forge.rust-lang.org/triagebot/note.html
+[note]