about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-02-26 17:17:25 +0000
committerbors <bors@rust-lang.org>2023-02-26 17:17:25 +0000
commit56ac6bfc87cce22feffc079c0540c8774b00a5ca (patch)
treee430c91fb4e29070945f79df7a47639e5cf4f9b1
parentffd12f67cfa28891bbd1fa81d5e80a128f346ace (diff)
parentcb45103358c0fef99d7659e0949b3c65b3eabdd6 (diff)
downloadrust-56ac6bfc87cce22feffc079c0540c8774b00a5ca.tar.gz
rust-56ac6bfc87cce22feffc079c0540c8774b00a5ca.zip
Auto merge of #2803 - RalfJung:rustup, r=RalfJung
Rustup
-rw-r--r--.git-blame-ignore-revs2
-rw-r--r--Cargo.lock87
-rw-r--r--compiler/rustc_ast/Cargo.toml2
-rw-r--r--compiler/rustc_ast/src/ast.rs94
-rw-r--r--compiler/rustc_ast/src/attr/mod.rs10
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs44
-rw-r--r--compiler/rustc_ast_lowering/Cargo.toml2
-rw-r--r--compiler/rustc_ast_lowering/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl)3
-rw-r--r--compiler/rustc_ast_lowering/src/errors.rs10
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs25
-rw-r--r--compiler/rustc_ast_lowering/src/format.rs19
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs39
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs170
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs4
-rw-r--r--compiler/rustc_ast_passes/Cargo.toml5
-rw-r--r--compiler/rustc_ast_passes/locales/en-US.ftl236
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs599
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs489
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs60
-rw-r--r--compiler/rustc_ast_passes/src/lib.rs8
-rw-r--r--compiler/rustc_ast_passes/src/show_span.rs8
-rw-r--r--compiler/rustc_ast_pretty/Cargo.toml1
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs9
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/tests.rs7
-rw-r--r--compiler/rustc_attr/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/attr.ftl)0
-rw-r--r--compiler/rustc_attr/src/lib.rs5
-rw-r--r--compiler/rustc_attr/src/session_diagnostics.rs19
-rw-r--r--compiler/rustc_borrowck/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/borrowck.ftl)0
-rw-r--r--compiler/rustc_borrowck/src/constraint_generation.rs4
-rw-r--r--compiler/rustc_borrowck/src/constraints/mod.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs9
-rw-r--r--compiler/rustc_borrowck/src/lib.rs104
-rw-r--r--compiler/rustc_borrowck/src/nll.rs12
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs81
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs43
-rw-r--r--compiler/rustc_borrowck/src/region_infer/values.rs2
-rw-r--r--compiler/rustc_borrowck/src/renumber.rs71
-rw-r--r--compiler/rustc_borrowck/src/session_diagnostics.rs4
-rw-r--r--compiler/rustc_borrowck/src/type_check/canonical.rs6
-rw-r--r--compiler/rustc_borrowck/src/type_check/constraint_conversion.rs4
-rw-r--r--compiler/rustc_borrowck/src/type_check/free_region_relations.rs5
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/trace.rs6
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs53
-rw-r--r--compiler/rustc_borrowck/src/type_check/relate_tys.rs57
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs125
-rw-r--r--compiler/rustc_builtin_macros/Cargo.toml2
-rw-r--r--compiler/rustc_builtin_macros/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl)0
-rw-r--r--compiler/rustc_builtin_macros/src/alloc_error_handler.rs17
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/assert.rs3
-rw-r--r--compiler/rustc_builtin_macros/src/assert/context.rs20
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/clone.rs8
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/debug.rs21
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/decodable.rs16
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/default.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/encodable.rs32
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs44
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/ty.rs9
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/hash.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/mod.rs11
-rw-r--r--compiler/rustc_builtin_macros/src/env.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/global_allocator.rs14
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/proc_macro_harness.rs14
-rw-r--r--compiler/rustc_builtin_macros/src/test.rs22
-rw-r--r--compiler/rustc_builtin_macros/src/test_harness.rs13
-rw-r--r--compiler/rustc_codegen_cranelift/src/abi/mod.rs6
-rw-r--r--compiler/rustc_codegen_cranelift/src/codegen_i128.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/common.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/lib.rs7
-rw-r--r--compiler/rustc_codegen_cranelift/src/main_shim.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/num.rs2
-rw-r--r--compiler/rustc_codegen_gcc/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl)0
-rw-r--r--compiler/rustc_codegen_gcc/src/callee.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/context.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs9
-rw-r--r--compiler/rustc_codegen_gcc/src/mono_item.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/type_of.rs2
-rw-r--r--compiler/rustc_codegen_llvm/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl)0
-rw-r--r--compiler/rustc_codegen_llvm/src/callee.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs11
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/errors.rs7
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs9
-rw-r--r--compiler/rustc_codegen_llvm/src/mono_item.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/type_of.rs2
-rw-r--r--compiler/rustc_codegen_ssa/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl)0
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs16
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/backend.rs4
-rw-r--r--compiler/rustc_const_eval/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/const_eval.ftl)0
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs2
-rw-r--r--compiler/rustc_const_eval/src/errors.rs18
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/intern.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/operator.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs3
-rw-r--r--compiler/rustc_const_eval/src/interpret/util.rs6
-rw-r--r--compiler/rustc_const_eval/src/lib.rs4
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/promote_consts.rs4
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs4
-rw-r--r--compiler/rustc_data_structures/Cargo.toml3
-rw-r--r--compiler/rustc_data_structures/src/graph/scc/mod.rs18
-rw-r--r--compiler/rustc_data_structures/src/sync.rs4
-rw-r--r--compiler/rustc_data_structures/src/sync/vec.rs41
-rw-r--r--compiler/rustc_driver_impl/Cargo.toml21
-rw-r--r--compiler/rustc_driver_impl/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/driver.ftl)0
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs51
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs13
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0476.md21
-rw-r--r--compiler/rustc_error_codes/src/lib.rs7
-rw-r--r--compiler/rustc_error_messages/locales/en-US.ftl1
-rw-r--r--compiler/rustc_error_messages/locales/en-US/ast_passes.ftl92
-rw-r--r--compiler/rustc_error_messages/locales/en-US/errors.ftl13
-rw-r--r--compiler/rustc_error_messages/src/lib.rs51
-rw-r--r--compiler/rustc_errors/locales/en-US.ftl19
-rw-r--r--compiler/rustc_errors/src/diagnostic_impls.rs6
-rw-r--r--compiler/rustc_errors/src/json.rs2
-rw-r--r--compiler/rustc_errors/src/json/tests.rs2
-rw-r--r--compiler/rustc_errors/src/lib.rs26
-rw-r--r--compiler/rustc_errors/src/registry.rs12
-rw-r--r--compiler/rustc_errors/src/translation.rs30
-rw-r--r--compiler/rustc_expand/Cargo.toml2
-rw-r--r--compiler/rustc_expand/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/expand.ftl)4
-rw-r--r--compiler/rustc_expand/src/base.rs7
-rw-r--r--compiler/rustc_expand/src/build.rs62
-rw-r--r--compiler/rustc_expand/src/config.rs3
-rw-r--r--compiler/rustc_expand/src/errors.rs29
-rw-r--r--compiler/rustc_expand/src/lib.rs5
-rw-r--r--compiler/rustc_expand/src/module.rs4
-rw-r--r--compiler/rustc_expand/src/parse/tests.rs5
-rw-r--r--compiler/rustc_expand/src/proc_macro.rs12
-rw-r--r--compiler/rustc_expand/src/tests.rs16
-rw-r--r--compiler/rustc_hir/src/def.rs9
-rw-r--r--compiler/rustc_hir/src/definitions.rs6
-rw-r--r--compiler/rustc_hir/src/hir.rs14
-rw-r--r--compiler/rustc_hir/src/intravisit.rs4
-rw-r--r--compiler/rustc_hir/src/lang_items.rs2
-rw-r--r--compiler/rustc_hir_analysis/Cargo.toml3
-rw-r--r--compiler/rustc_hir_analysis/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl)83
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/errors.rs7
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/generics.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs63
-rw-r--r--compiler/rustc_hir_analysis/src/autoderef.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs7
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs19
-rw-r--r--compiler/rustc_hir_analysis/src/check/dropck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs69
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/mod.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/orphan.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs48
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs21
-rw-r--r--compiler/rustc_hir_analysis/src/constrained_generic_params.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs119
-rw-r--r--compiler/rustc_hir_analysis/src/hir_wf_check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs103
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/variance/mod.rs6
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs4
-rw-r--r--compiler/rustc_hir_typeck/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl)44
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs22
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs48
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs26
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs20
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs121
-rw-r--r--compiler/rustc_hir_typeck/src/expr_use_visitor.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fallback.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs19
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs94
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs9
-rw-r--r--compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/generator_interior/mod.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/inherited.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/intrinsicck.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs15
-rw-r--r--compiler/rustc_hir_typeck/src/mem_categorization.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs67
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs20
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs16
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs256
-rw-r--r--compiler/rustc_hir_typeck/src/place_op.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs10
-rw-r--r--compiler/rustc_incremental/Cargo.toml17
-rw-r--r--compiler/rustc_incremental/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/incremental.ftl)0
-rw-r--r--compiler/rustc_incremental/src/assert_module_sources.rs3
-rw-r--r--compiler/rustc_incremental/src/lib.rs5
-rw-r--r--compiler/rustc_incremental/src/persist/dirty_clean.rs8
-rw-r--r--compiler/rustc_infer/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/infer.ftl)0
-rw-r--r--compiler/rustc_infer/src/errors/mod.rs35
-rw-r--r--compiler/rustc_infer/src/errors/note_and_explain.rs5
-rw-r--r--compiler/rustc_infer/src/infer/at.rs2
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs20
-rw-r--r--compiler/rustc_infer/src/infer/canonical/mod.rs6
-rw-r--r--compiler/rustc_infer/src/infer/canonical/query_response.rs42
-rw-r--r--compiler/rustc_infer/src/infer/canonical/substitute.rs10
-rw-r--r--compiler/rustc_infer/src/infer/combine.rs14
-rw-r--r--compiler/rustc_infer/src/infer/equate.rs7
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs39
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs3
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note.rs3
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/suggest.rs2
-rw-r--r--compiler/rustc_infer/src/infer/freshen.rs4
-rw-r--r--compiler/rustc_infer/src/infer/fudge.rs4
-rw-r--r--compiler/rustc_infer/src/infer/glb.rs7
-rw-r--r--compiler/rustc_infer/src/infer/higher_ranked/mod.rs4
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs4
-rw-r--r--compiler/rustc_infer/src/infer/lub.rs7
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs24
-rw-r--r--compiler/rustc_infer/src/infer/nll_relate/mod.rs19
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs15
-rw-r--r--compiler/rustc_infer/src/infer/outlives/components.rs2
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs2
-rw-r--r--compiler/rustc_infer/src/infer/outlives/test_type_match.rs5
-rw-r--r--compiler/rustc_infer/src/infer/resolve.rs9
-rw-r--r--compiler/rustc_infer/src/infer/sub.rs9
-rw-r--r--compiler/rustc_infer/src/lib.rs6
-rw-r--r--compiler/rustc_infer/src/traits/structural_impls.rs17
-rw-r--r--compiler/rustc_infer/src/traits/util.rs31
-rw-r--r--compiler/rustc_interface/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/interface.ftl)4
-rw-r--r--compiler/rustc_interface/src/errors.rs4
-rw-r--r--compiler/rustc_interface/src/interface.rs2
-rw-r--r--compiler/rustc_interface/src/lib.rs5
-rw-r--r--compiler/rustc_interface/src/passes.rs34
-rw-r--r--compiler/rustc_interface/src/queries.rs6
-rw-r--r--compiler/rustc_interface/src/tests.rs4
-rw-r--r--compiler/rustc_interface/src/util.rs5
-rw-r--r--compiler/rustc_lint/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/lint.ftl)7
-rw-r--r--compiler/rustc_lint/src/array_into_iter.rs6
-rw-r--r--compiler/rustc_lint/src/builtin.rs19
-rw-r--r--compiler/rustc_lint/src/enum_intrinsics_non_enums.rs2
-rw-r--r--compiler/rustc_lint/src/errors.rs6
-rw-r--r--compiler/rustc_lint/src/levels.rs17
-rw-r--r--compiler/rustc_lint/src/lib.rs10
-rw-r--r--compiler/rustc_lint/src/lints.rs149
-rw-r--r--compiler/rustc_lint/src/map_unit_fn.rs120
-rw-r--r--compiler/rustc_lint/src/non_fmt_panic.rs18
-rw-r--r--compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs2
-rw-r--r--compiler/rustc_lint/src/types.rs21
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs30
-rw-r--r--compiler/rustc_macros/src/diagnostics/diagnostic.rs4
-rw-r--r--compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs6
-rw-r--r--compiler/rustc_macros/src/diagnostics/fluent.rs449
-rw-r--r--compiler/rustc_macros/src/diagnostics/subdiagnostic.rs4
-rw-r--r--compiler/rustc_macros/src/lib.rs8
-rw-r--r--compiler/rustc_macros/src/type_foldable.rs6
-rw-r--r--compiler/rustc_macros/src/type_visitable.rs6
-rw-r--r--compiler/rustc_metadata/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/metadata.ftl)0
-rw-r--r--compiler/rustc_metadata/src/errors.rs23
-rw-r--r--compiler/rustc_metadata/src/lib.rs4
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs9
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs13
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs1
-rw-r--r--compiler/rustc_middle/Cargo.toml2
-rw-r--r--compiler/rustc_middle/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/middle.ftl)0
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs7
-rw-r--r--compiler/rustc_middle/src/hir/mod.rs6
-rw-r--r--compiler/rustc_middle/src/infer/canonical.rs8
-rw-r--r--compiler/rustc_middle/src/lib.rs5
-rw-r--r--compiler/rustc_middle/src/macros.rs10
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs4
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs2
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs25
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs6
-rw-r--r--compiler/rustc_middle/src/mir/type_foldable.rs17
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs4
-rw-r--r--compiler/rustc_middle/src/query/mod.rs27
-rw-r--r--compiler/rustc_middle/src/traits/query.rs4
-rw-r--r--compiler/rustc_middle/src/traits/solve.rs32
-rw-r--r--compiler/rustc_middle/src/traits/specialization_graph.rs2
-rw-r--r--compiler/rustc_middle/src/ty/_match.rs4
-rw-r--r--compiler/rustc_middle/src/ty/abstract_const.rs5
-rw-r--r--compiler/rustc_middle/src/ty/adt.rs2
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs38
-rw-r--r--compiler/rustc_middle/src/ty/consts/kind.rs2
-rw-r--r--compiler/rustc_middle/src/ty/context.rs316
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs17
-rw-r--r--compiler/rustc_middle/src/ty/erase_regions.rs8
-rw-r--r--compiler/rustc_middle/src/ty/fast_reject.rs2
-rw-r--r--compiler/rustc_middle/src/ty/fold.rs51
-rw-r--r--compiler/rustc_middle/src/ty/generics.rs2
-rw-r--r--compiler/rustc_middle/src/ty/impls_ty.rs2
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs12
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs24
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs34
-rw-r--r--compiler/rustc_middle/src/ty/normalize_erasing_regions.rs19
-rw-r--r--compiler/rustc_middle/src/ty/opaque_types.rs10
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs26
-rw-r--r--compiler/rustc_middle/src/ty/query.rs5
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs19
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs177
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs48
-rw-r--r--compiler/rustc_middle/src/ty/subst.rs81
-rw-r--r--compiler/rustc_middle/src/ty/trait_def.rs2
-rw-r--r--compiler/rustc_middle/src/ty/util.rs42
-rw-r--r--compiler/rustc_middle/src/ty/visit.rs44
-rw-r--r--compiler/rustc_middle/src/ty/vtable.rs2
-rw-r--r--compiler/rustc_middle/src/values.rs9
-rw-r--r--compiler/rustc_mir_build/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/mir_build.ftl)0
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_constant.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_operand.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/matches/util.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs6
-rw-r--r--compiler/rustc_mir_build/src/errors.rs39
-rw-r--r--compiler/rustc_mir_build/src/lib.rs5
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/mod.rs5
-rw-r--r--compiler/rustc_mir_dataflow/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/mir_dataflow.ftl)0
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/direction.rs31
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/engine.rs32
-rw-r--r--compiler/rustc_mir_dataflow/src/lib.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs6
-rw-r--r--compiler/rustc_mir_transform/src/const_prop.rs239
-rw-r--r--compiler/rustc_mir_transform/src/const_prop_lint.rs4
-rw-r--r--compiler/rustc_mir_transform/src/copy_prop.rs2
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs25
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_box_derefs.rs4
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drops.rs57
-rw-r--r--compiler/rustc_mir_transform/src/generator.rs19
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs2
-rw-r--r--compiler/rustc_mir_transform/src/inline/cycle.rs2
-rw-r--r--compiler/rustc_mir_transform/src/instcombine.rs11
-rw-r--r--compiler/rustc_mir_transform/src/large_enums.rs7
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs4
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs8
-rw-r--r--compiler/rustc_mir_transform/src/sroa.rs2
-rw-r--r--compiler/rustc_monomorphize/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/monomorphize.ftl)0
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs8
-rw-r--r--compiler/rustc_monomorphize/src/errors.rs3
-rw-r--r--compiler/rustc_monomorphize/src/lib.rs4
-rw-r--r--compiler/rustc_monomorphize/src/partitioning/default.rs2
-rw-r--r--compiler/rustc_monomorphize/src/polymorphize.rs2
-rw-r--r--compiler/rustc_parse/Cargo.toml2
-rw-r--r--compiler/rustc_parse/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/parse.ftl)28
-rw-r--r--compiler/rustc_parse/src/errors.rs188
-rw-r--r--compiler/rustc_parse/src/lib.rs4
-rw-r--r--compiler/rustc_parse/src/parser/attr.rs26
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs16
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs257
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs17
-rw-r--r--compiler/rustc_parse/src/parser/item.rs28
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs23
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs16
-rw-r--r--compiler/rustc_parse/src/parser/path.rs8
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs23
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs30
-rw-r--r--compiler/rustc_passes/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/passes.ftl)6
-rw-r--r--compiler/rustc_passes/src/check_attr.rs41
-rw-r--r--compiler/rustc_passes/src/dead.rs7
-rw-r--r--compiler/rustc_passes/src/errors.rs104
-rw-r--r--compiler/rustc_passes/src/lib.rs4
-rw-r--r--compiler/rustc_passes/src/liveness.rs6
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs2
-rw-r--r--compiler/rustc_passes/src/stability.rs9
-rw-r--r--compiler/rustc_plugin_impl/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/plugin_impl.ftl)0
-rw-r--r--compiler/rustc_plugin_impl/src/lib.rs4
-rw-r--r--compiler/rustc_privacy/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/privacy.ftl)0
-rw-r--r--compiler/rustc_privacy/src/errors.rs4
-rw-r--r--compiler/rustc_privacy/src/lib.rs13
-rw-r--r--compiler/rustc_query_impl/Cargo.toml2
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs4
-rw-r--r--compiler/rustc_query_system/Cargo.toml2
-rw-r--r--compiler/rustc_query_system/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/query_system.ftl)0
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs61
-rw-r--r--compiler/rustc_query_system/src/ich/hcx.rs2
-rw-r--r--compiler/rustc_query_system/src/lib.rs5
-rw-r--r--compiler/rustc_query_system/src/query/caches.rs6
-rw-r--r--compiler/rustc_query_system/src/query/config.rs4
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs61
-rw-r--r--compiler/rustc_resolve/Cargo.toml2
-rw-r--r--compiler/rustc_resolve/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/resolve.ftl)0
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs75
-rw-r--r--compiler/rustc_resolve/src/errors.rs14
-rw-r--r--compiler/rustc_resolve/src/imports.rs143
-rw-r--r--compiler/rustc_resolve/src/lib.rs15
-rw-r--r--compiler/rustc_resolve/src/macros.rs3
-rw-r--r--compiler/rustc_serialize/Cargo.toml2
-rw-r--r--compiler/rustc_session/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/session.ftl)0
-rw-r--r--compiler/rustc_session/src/cstore.rs6
-rw-r--r--compiler/rustc_session/src/lib.rs5
-rw-r--r--compiler/rustc_session/src/options.rs4
-rw-r--r--compiler/rustc_session/src/parse.rs6
-rw-r--r--compiler/rustc_session/src/session.rs8
-rw-r--r--compiler/rustc_span/src/lib.rs14
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_symbol_mangling/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/symbol_mangling.ftl)0
-rw-r--r--compiler/rustc_symbol_mangling/src/legacy.rs2
-rw-r--r--compiler/rustc_symbol_mangling/src/lib.rs4
-rw-r--r--compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs5
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs6
-rw-r--r--compiler/rustc_trait_selection/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/trait_selection.ftl)0
-rw-r--r--compiler/rustc_trait_selection/src/errors.rs11
-rw-r--r--compiler/rustc_trait_selection/src/infer.rs16
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs5
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly.rs26
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt.rs175
-rw-r--r--compiler/rustc_trait_selection/src/solve/infcx_ext.rs78
-rw-r--r--compiler/rustc_trait_selection/src/solve/mod.rs35
-rw-r--r--compiler/rustc_trait_selection/src/solve/project_goals.rs145
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs94
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs150
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs9
-rw-r--r--compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/engine.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs13
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs32
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/misc.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs17
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs17
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs71
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs14
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs17
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs24
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/structural_match.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/vtable.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs2
-rw-r--r--compiler/rustc_traits/src/chalk/db.rs4
-rw-r--r--compiler/rustc_traits/src/chalk/lowering.rs27
-rw-r--r--compiler/rustc_traits/src/chalk/mod.rs41
-rw-r--r--compiler/rustc_traits/src/implied_outlives_bounds.rs2
-rw-r--r--compiler/rustc_traits/src/normalize_erasing_regions.rs4
-rw-r--r--compiler/rustc_traits/src/type_op.rs2
-rw-r--r--compiler/rustc_transmute/src/lib.rs2
-rw-r--r--compiler/rustc_ty_utils/locales/en-US.ftl (renamed from compiler/rustc_error_messages/locales/en-US/ty_utils.ftl)0
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs12
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs103
-rw-r--r--compiler/rustc_ty_utils/src/consts.rs4
-rw-r--r--compiler/rustc_ty_utils/src/errors.rs2
-rw-r--r--compiler/rustc_ty_utils/src/implied_bounds.rs6
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs2
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs42
-rw-r--r--compiler/rustc_ty_utils/src/lib.rs4
-rw-r--r--compiler/rustc_ty_utils/src/needs_drop.rs4
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs19
-rw-r--r--config.toml.example3
-rw-r--r--library/alloc/src/collections/vec_deque/mod.rs117
-rw-r--r--library/alloc/src/collections/vec_deque/tests.rs42
-rw-r--r--library/alloc/src/vec/mod.rs4
-rw-r--r--library/core/src/convert/mod.rs2
-rw-r--r--library/core/src/iter/mod.rs1
-rw-r--r--library/core/src/iter/traits/iterator.rs77
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/slice/sort.rs24
-rw-r--r--library/core/src/sync/atomic.rs12
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--library/std/src/fs/tests.rs16
-rw-r--r--library/std/src/keyword_docs.rs2
-rw-r--r--library/std/src/os/fd/owned.rs9
-rw-r--r--library/std/src/os/fd/raw.rs10
-rw-r--r--library/std/src/os/hermit/io/mod.rs13
-rw-r--r--library/std/src/os/hermit/io/net.rs46
-rw-r--r--library/std/src/os/hermit/mod.rs5
-rw-r--r--library/std/src/os/mod.rs12
-rw-r--r--library/std/src/panicking.rs16
-rw-r--r--library/std/src/sys/hermit/args.rs2
-rw-r--r--library/std/src/sys/hermit/fd.rs77
-rw-r--r--library/std/src/sys/hermit/fs.rs57
-rw-r--r--library/std/src/sys/hermit/mod.rs87
-rw-r--r--library/std/src/sys/hermit/net.rs639
-rw-r--r--library/std/src/sys/hermit/os.rs2
-rw-r--r--library/std/src/sys/hermit/time.rs98
-rw-r--r--library/std/src/sys/unix/fd.rs5
-rw-r--r--library/std/src/sys/windows/args.rs11
-rw-r--r--library/std/src/sys/windows/c.rs8
-rw-r--r--library/std/src/sys/windows/io.rs32
-rw-r--r--library/std/src/sys_common/mod.rs1
-rw-r--r--library/std/src/sys_common/thread_parking/id.rs6
-rw-r--r--library/std/src/time.rs6
-rw-r--r--library/std/tests/common/mod.rs58
-rw-r--r--library/std/tests/create_dir_all_bare.rs39
-rw-r--r--library/std/tests/env.rs14
-rw-r--r--library/test/Cargo.toml2
-rw-r--r--src/bootstrap/builder.rs9
-rw-r--r--src/bootstrap/compile.rs66
-rw-r--r--src/bootstrap/config.rs3
-rw-r--r--src/bootstrap/download.rs19
-rw-r--r--src/bootstrap/flags.rs13
-rw-r--r--src/bootstrap/format.rs4
-rw-r--r--src/bootstrap/lib.rs11
-rw-r--r--src/bootstrap/native.rs2
-rw-r--r--src/bootstrap/setup.rs120
-rw-r--r--src/bootstrap/tool.rs6
-rw-r--r--src/ci/docker/host-x86_64/mingw-check/Dockerfile4
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version2
-rwxr-xr-xsrc/ci/docker/scripts/fuchsia-test-runner.py82
-rw-r--r--src/doc/index.md228
-rw-r--r--src/doc/rustc/src/platform-support/fuchsia.md94
-rw-r--r--src/librustdoc/Cargo.toml1
-rw-r--r--src/librustdoc/clean/cfg/tests.rs5
-rw-r--r--src/librustdoc/clean/mod.rs34
-rw-r--r--src/librustdoc/clean/render_macro_matchers.rs3
-rw-r--r--src/librustdoc/clean/utils.rs6
-rw-r--r--src/librustdoc/core.rs7
-rw-r--r--src/librustdoc/doctest.rs13
-rw-r--r--src/librustdoc/html/format.rs2
-rw-r--r--src/librustdoc/html/markdown.rs5
-rw-r--r--src/librustdoc/lib.rs1
-rw-r--r--src/librustdoc/passes/lint/check_code_block_syntax.rs6
-rw-r--r--src/librustdoc/visit_ast.rs20
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/derive.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/doc.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/eta_reduction.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/never_loop.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/needless_collect.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/mut_key.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_slicing.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/types/vec_box.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs50
-rw-r--r--src/tools/clippy/clippy_lints/src/useless_conversion.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/eager_or_lazy.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/sugg.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/visitors.rs2
-rw-r--r--src/tools/clippy/src/driver.rs5
-rw-r--r--src/tools/clippy/tests/ui/missing_doc_impl.stderr4
-rw-r--r--src/tools/compiletest/Cargo.toml4
-rw-r--r--src/tools/compiletest/src/errors.rs8
-rw-r--r--src/tools/compiletest/src/main.rs3
-rw-r--r--src/tools/compiletest/src/runtest.rs71
-rw-r--r--src/tools/error_index_generator/Cargo.toml1
-rw-r--r--src/tools/error_index_generator/main.rs58
-rw-r--r--src/tools/jsondoclint/src/validator.rs28
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/eval.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/layout.rs2
-rw-r--r--src/tools/rustfmt/src/chains.rs4
-rw-r--r--src/tools/rustfmt/src/closures.rs3
-rw-r--r--src/tools/rustfmt/src/lib.rs1
-rw-r--r--src/tools/rustfmt/src/modules.rs13
-rw-r--r--src/tools/rustfmt/src/parse/parser.rs3
-rw-r--r--src/tools/rustfmt/src/parse/session.rs6
-rw-r--r--src/tools/tidy/src/deps.rs1
-rw-r--r--src/tools/tidy/src/error_codes.rs26
-rw-r--r--tests/mir-opt/casts.redundant.InstCombine.diff25
-rw-r--r--tests/mir-opt/casts.redundant.PreCodegen.after.mir14
-rw-r--r--tests/mir-opt/casts.roundtrip.PreCodegen.after.mir15
-rw-r--r--tests/mir-opt/casts.rs17
-rw-r--r--tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.diff82
-rw-r--r--tests/mir-opt/dataflow-const-prop/enum.rs16
-rw-r--r--tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff6
-rw-r--r--tests/mir-opt/issue_41110.main.ElaborateDrops.after.mir70
-rw-r--r--tests/mir-opt/issue_41110.main.ElaborateDrops.diff75
-rw-r--r--tests/mir-opt/issue_41110.rs4
-rw-r--r--tests/mir-opt/issue_41110.test.ElaborateDrops.after.mir101
-rw-r--r--tests/mir-opt/issue_41110.test.ElaborateDrops.diff109
-rw-r--r--tests/mir-opt/issue_41888.main.ElaborateDrops.after.mir152
-rw-r--r--tests/mir-opt/issue_41888.main.ElaborateDrops.diff158
-rw-r--r--tests/mir-opt/issue_41888.rs2
-rw-r--r--tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs2
-rw-r--r--tests/run-make-fulldeps/issue-19371/foo.rs1
-rw-r--r--tests/run-make/translation/Makefile18
-rw-r--r--tests/rustdoc-gui/help-page.goml3
-rw-r--r--tests/rustdoc-ui/auxiliary/panic-handler.rs9
-rw-r--r--tests/rustdoc-ui/issue-107918.rs12
-rw-r--r--tests/rustdoc-ui/proc_macro_bug.rs12
-rw-r--r--tests/rustdoc-ui/proc_macro_bug.stderr8
-rw-r--r--tests/rustdoc-ui/unable-fulfill-trait.stderr2
-rw-r--r--tests/rustdoc-ui/z-help.stdout354
-rw-r--r--tests/rustdoc/intra-doc/basic.rs16
-rw-r--r--tests/rustdoc/issue-108281.rs25
-rw-r--r--tests/rustdoc/item-desc-list-at-start.item-table.html1
-rw-r--r--tests/rustdoc/item-desc-list-at-start.rs9
-rw-r--r--tests/rustdoc/reexports-of-same-name.rs26
-rw-r--r--tests/ui-fulldeps/create-dir-all-bare.rs11
-rw-r--r--tests/ui-fulldeps/fluent-messages/duplicate.ftl3
-rw-r--r--tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl2
-rw-r--r--tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl2
-rw-r--r--tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl2
-rw-r--r--tests/ui-fulldeps/fluent-messages/missing-message.ftl2
-rw-r--r--tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl2
-rw-r--r--tests/ui-fulldeps/fluent-messages/test.rs69
-rw-r--r--tests/ui-fulldeps/fluent-messages/test.stderr97
-rw-r--r--tests/ui-fulldeps/fluent-messages/valid.ftl2
-rw-r--r--tests/ui-fulldeps/internal-lints/diagnostics.ftl (renamed from compiler/rustc_error_messages/locales/en-US/compiletest.ftl)2
-rw-r--r--tests/ui-fulldeps/internal-lints/diagnostics.rs16
-rw-r--r--tests/ui-fulldeps/internal-lints/diagnostics.stderr12
-rw-r--r--tests/ui-fulldeps/mod_dir_path_canonicalized.rs5
-rw-r--r--tests/ui-fulldeps/pprust-expr-roundtrip.rs16
-rw-r--r--tests/ui-fulldeps/rename-directory.rs30
-rw-r--r--tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs298
-rw-r--r--tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr338
-rw-r--r--tests/ui-fulldeps/session-diagnostic/example.ftl5
-rw-r--r--tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs152
-rw-r--r--tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr264
-rw-r--r--tests/ui-fulldeps/std/issue-15149.rs (renamed from tests/ui-fulldeps/issue-15149.rs)0
-rw-r--r--tests/ui-fulldeps/std/issue-81357-unsound-file-methods.rs (renamed from tests/ui-fulldeps/issue-81357-unsound-file-methods.rs)0
-rw-r--r--tests/ui-fulldeps/std/stdio-from.rs (renamed from tests/ui-fulldeps/stdio-from.rs)0
-rw-r--r--tests/ui-fulldeps/std/switch-stdout.rs (renamed from tests/ui-fulldeps/switch-stdout.rs)0
-rw-r--r--tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr5
-rw-r--r--tests/ui/argument-suggestions/extra_arguments.rs8
-rw-r--r--tests/ui/argument-suggestions/extra_arguments.stderr69
-rw-r--r--tests/ui/argument-suggestions/issue-100154.stderr2
-rw-r--r--tests/ui/argument-suggestions/too-long.stderr2
-rw-r--r--tests/ui/associated-consts/issue-105330.stderr2
-rw-r--r--tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs14
-rw-r--r--tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr8
-rw-r--r--tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs13
-rw-r--r--tests/ui/associated-type-bounds/bad-universal-in-impl-sig.stderr8
-rw-r--r--tests/ui/associated-type-bounds/inside-adt.rs22
-rw-r--r--tests/ui/associated-type-bounds/inside-adt.stderr105
-rw-r--r--tests/ui/associated-types/associated-type-projection-from-supertrait.stderr4
-rw-r--r--tests/ui/associated-types/associated-types-eq-hr.stderr4
-rw-r--r--tests/ui/associated-types/defaults-suitability.stderr6
-rw-r--r--tests/ui/associated-types/hr-associated-type-bound-1.stderr2
-rw-r--r--tests/ui/associated-types/hr-associated-type-bound-object.stderr2
-rw-r--r--tests/ui/associated-types/hr-associated-type-bound-param-1.stderr2
-rw-r--r--tests/ui/associated-types/hr-associated-type-bound-param-2.stderr6
-rw-r--r--tests/ui/associated-types/hr-associated-type-bound-param-3.stderr2
-rw-r--r--tests/ui/associated-types/hr-associated-type-bound-param-4.stderr2
-rw-r--r--tests/ui/associated-types/hr-associated-type-bound-param-5.stderr4
-rw-r--r--tests/ui/associated-types/hr-associated-type-projection-1.stderr2
-rw-r--r--tests/ui/associated-types/point-at-type-on-obligation-failure-2.stderr4
-rw-r--r--tests/ui/async-await/in-trait/fn-not-async-err2.rs2
-rw-r--r--tests/ui/async-await/in-trait/fn-not-async-err2.stderr2
-rw-r--r--tests/ui/async-await/issues/issue-62097.rs2
-rw-r--r--tests/ui/async-await/issues/issue-62097.stderr6
-rw-r--r--tests/ui/async-await/issues/issue-65159.rs2
-rw-r--r--tests/ui/async-await/issues/issue-65159.stderr2
-rw-r--r--tests/ui/async-await/issues/issue-72312.stderr6
-rw-r--r--tests/ui/attributes/invalid_macro_export_argument.rs26
-rw-r--r--tests/ui/attributes/invalid_macro_export_argument.stderr16
-rw-r--r--tests/ui/auto-traits/auto-trait-validation.stderr6
-rw-r--r--tests/ui/auto-traits/issue-23080-2.stderr2
-rw-r--r--tests/ui/auto-traits/issue-23080.stderr2
-rw-r--r--tests/ui/auto-traits/issue-84075.stderr2
-rw-r--r--tests/ui/auto-traits/str-contains-slice-conceptually.rs13
-rw-r--r--tests/ui/auto-traits/str-contains-slice-conceptually.stderr16
-rw-r--r--tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr4
-rw-r--r--tests/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr2
-rw-r--r--tests/ui/borrowck/issue-103624.rs2
-rw-r--r--tests/ui/borrowck/issue-103624.stderr6
-rw-r--r--tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs4
-rw-r--r--tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr4
-rw-r--r--tests/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr2
-rw-r--r--tests/ui/const-generics/defaults/wfness.stderr2
-rw-r--r--tests/ui/const-generics/ensure_is_evaluatable.stderr2
-rw-r--r--tests/ui/const-generics/fn_with_two_const_inputs.stderr2
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-102768.rs4
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-102768.stderr4
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-105608.stderr2
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr4
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-76595.stderr2
-rw-r--r--tests/ui/const-generics/generic_const_exprs/obligation-cause.stderr2
-rw-r--r--tests/ui/const-generics/incorrect-number-of-const-args.stderr4
-rw-r--r--tests/ui/const-generics/infer/method-chain.stderr2
-rw-r--r--tests/ui/const-generics/infer/uninferred-consts.stderr2
-rw-r--r--tests/ui/const-generics/invalid-const-arg-for-type-param.rs4
-rw-r--r--tests/ui/const-generics/invalid-const-arg-for-type-param.stderr4
-rw-r--r--tests/ui/const-generics/invalid-constant-in-args.rs2
-rw-r--r--tests/ui/const-generics/invalid-constant-in-args.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-67185-2.stderr8
-rw-r--r--tests/ui/const-generics/issues/issue-73260.stderr4
-rw-r--r--tests/ui/const-generics/issues/issue-79674.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-86530.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-87493.rs2
-rw-r--r--tests/ui/const-generics/issues/issue-87493.stderr2
-rw-r--r--tests/ui/const-generics/occurs-check/unused-substs-1.stderr2
-rw-r--r--tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs2
-rw-r--r--tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr2
-rw-r--r--tests/ui/const-generics/parser-error-recovery/issue-89013.rs2
-rw-r--r--tests/ui/const-generics/parser-error-recovery/issue-89013.stderr2
-rw-r--r--tests/ui/const-generics/unify_with_nested_expr.stderr2
-rw-r--r--tests/ui/constructor-lifetime-args.rs8
-rw-r--r--tests/ui/constructor-lifetime-args.stderr8
-rw-r--r--tests/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr10
-rw-r--r--tests/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr10
-rw-r--r--tests/ui/consts/ct-var-in-collect_all_mismatches.stderr2
-rw-r--r--tests/ui/consts/gate-do-not-const-check.rs5
-rw-r--r--tests/ui/consts/gate-do-not-const-check.stderr11
-rw-r--r--tests/ui/deprecation/deprecation-lint.rs96
-rw-r--r--tests/ui/deprecation/deprecation-lint.stderr140
-rw-r--r--tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed4
-rw-r--r--tests/ui/deprecation/issue-84637-deprecated-associated-function.rs4
-rw-r--r--tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr8
-rw-r--r--tests/ui/deprecation/suggestion.stderr4
-rw-r--r--tests/ui/error-codes/E0107.rs20
-rw-r--r--tests/ui/error-codes/E0107.stderr20
-rw-r--r--tests/ui/error-codes/E0476.rs13
-rw-r--r--tests/ui/error-codes/E0476.stderr31
-rw-r--r--tests/ui/error-codes/E0624.rs2
-rw-r--r--tests/ui/error-codes/E0624.stderr6
-rw-r--r--tests/ui/explore-issue-38412.stderr36
-rw-r--r--tests/ui/expr/malformed_closure/missing_braces_around_block.fixed9
-rw-r--r--tests/ui/expr/malformed_closure/missing_braces_around_block.rs9
-rw-r--r--tests/ui/expr/malformed_closure/missing_braces_around_block.stderr33
-rw-r--r--tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr6
-rw-r--r--tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr4
-rw-r--r--tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr6
-rw-r--r--tests/ui/fn/issue-3044.stderr2
-rw-r--r--tests/ui/generator/generator-yielding-or-returning-itself.stderr4
-rw-r--r--tests/ui/generator/issue-102645.stderr2
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-88460.stderr2
-rw-r--r--tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs6
-rw-r--r--tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr6
-rw-r--r--tests/ui/generic-associated-types/issue-101020.stderr2
-rw-r--r--tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.rs (renamed from tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs)0
-rw-r--r--tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.stderr (renamed from tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr)4
-rw-r--r--tests/ui/generic-associated-types/missing_lifetime_args.rs4
-rw-r--r--tests/ui/generic-associated-types/missing_lifetime_args.stderr4
-rw-r--r--tests/ui/generic-associated-types/missing_lifetime_const.rs2
-rw-r--r--tests/ui/generic-associated-types/missing_lifetime_const.stderr2
-rw-r--r--tests/ui/generic-associated-types/parameter_number_and_kind.rs6
-rw-r--r--tests/ui/generic-associated-types/parameter_number_and_kind.stderr6
-rw-r--r--tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs4
-rw-r--r--tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr4
-rw-r--r--tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.rs (renamed from tests/ui/generic-associated-types/unsatified-item-lifetime-bound.rs)2
-rw-r--r--tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.stderr (renamed from tests/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr)19
-rw-r--r--tests/ui/generics/bad-mid-path-type-params.rs10
-rw-r--r--tests/ui/generics/bad-mid-path-type-params.stderr10
-rw-r--r--tests/ui/generics/generic-arg-mismatch-recover.rs6
-rw-r--r--tests/ui/generics/generic-arg-mismatch-recover.stderr6
-rw-r--r--tests/ui/generics/generic-impl-less-params-with-defaults.rs2
-rw-r--r--tests/ui/generics/generic-impl-less-params-with-defaults.stderr2
-rw-r--r--tests/ui/generics/generic-impl-more-params-with-defaults.rs2
-rw-r--r--tests/ui/generics/generic-impl-more-params-with-defaults.stderr2
-rw-r--r--tests/ui/generics/generic-type-more-params-with-defaults.rs2
-rw-r--r--tests/ui/generics/generic-type-more-params-with-defaults.stderr2
-rw-r--r--tests/ui/generics/wrong-number-of-args.rs106
-rw-r--r--tests/ui/generics/wrong-number-of-args.stderr106
-rw-r--r--tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr2
-rw-r--r--tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr4
-rw-r--r--tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr4
-rw-r--r--tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr6
-rw-r--r--tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr2
-rw-r--r--tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr2
-rw-r--r--tests/ui/impl-trait/equal-hidden-lifetimes.rs1
-rw-r--r--tests/ui/impl-trait/equal-hidden-lifetimes.stderr10
-rw-r--r--tests/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr2
-rw-r--r--tests/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr2
-rw-r--r--tests/ui/impl-trait/in-trait/default-method-constraint.rs17
-rw-r--r--tests/ui/impl-trait/in-trait/default-method-constraint.stderr11
-rw-r--r--tests/ui/impl-trait/issues/issue-54600.stderr2
-rw-r--r--tests/ui/impl-trait/issues/issue-54840.stderr2
-rw-r--r--tests/ui/impl-trait/issues/issue-58504.stderr2
-rw-r--r--tests/ui/impl-trait/issues/issue-58956.stderr4
-rw-r--r--tests/ui/impl-trait/issues/issue-70971.stderr2
-rw-r--r--tests/ui/impl-trait/issues/issue-79099.stderr2
-rw-r--r--tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr4
-rw-r--r--tests/ui/impl-trait/issues/issue-84919.stderr2
-rw-r--r--tests/ui/impl-trait/issues/issue-86642.stderr2
-rw-r--r--tests/ui/impl-trait/issues/issue-87295.stderr2
-rw-r--r--tests/ui/impl-trait/nested_impl_trait.stderr2
-rw-r--r--tests/ui/impl-trait/normalize-tait-in-const.rs1
-rw-r--r--tests/ui/impl-trait/normalize-tait-in-const.stderr2
-rw-r--r--tests/ui/impl-trait/where-allowed.stderr78
-rw-r--r--tests/ui/implied-bounds/issue-100690.stderr2
-rw-r--r--tests/ui/inference/inference_unstable.rs8
-rw-r--r--tests/ui/inference/inference_unstable.stderr8
-rw-r--r--tests/ui/inference/inference_unstable_featured.stderr4
-rw-r--r--tests/ui/inference/issue-71732.stderr2
-rw-r--r--tests/ui/inference/question-mark-type-infer.stderr2
-rw-r--r--tests/ui/infinite/auxiliary/alias.rs2
-rw-r--r--tests/ui/infinite/infinite-alias.rs9
-rw-r--r--tests/ui/infinite/infinite-alias.stderr14
-rw-r--r--tests/ui/issues/issue-106755.rs19
-rw-r--r--tests/ui/issues/issue-106755.stderr22
-rw-r--r--tests/ui/issues/issue-11374.stderr2
-rw-r--r--tests/ui/issues/issue-17337.stderr2
-rw-r--r--tests/ui/issues/issue-18423.rs2
-rw-r--r--tests/ui/issues/issue-18423.stderr2
-rw-r--r--tests/ui/issues/issue-18446.stderr2
-rw-r--r--tests/ui/issues/issue-21202.rs2
-rw-r--r--tests/ui/issues/issue-21202.stderr6
-rw-r--r--tests/ui/issues/issue-23041.stderr2
-rw-r--r--tests/ui/issues/issue-26094.rs5
-rw-r--r--tests/ui/issues/issue-26094.stderr5
-rw-r--r--tests/ui/issues/issue-30438-c.rs1
-rw-r--r--tests/ui/issues/issue-30438-c.stderr12
-rw-r--r--tests/ui/issues/issue-3214.rs2
-rw-r--r--tests/ui/issues/issue-3214.stderr2
-rw-r--r--tests/ui/issues/issue-3702-2.stderr4
-rw-r--r--tests/ui/issues/issue-3763.rs4
-rw-r--r--tests/ui/issues/issue-3763.stderr12
-rw-r--r--tests/ui/issues/issue-47715.stderr8
-rw-r--r--tests/ui/issues/issue-48364.stderr2
-rw-r--r--tests/ui/issues/issue-53251.rs4
-rw-r--r--tests/ui/issues/issue-53251.stderr4
-rw-r--r--tests/ui/issues/issue-60218.stderr2
-rw-r--r--tests/ui/issues/issue-60622.rs2
-rw-r--r--tests/ui/issues/issue-60622.stderr4
-rw-r--r--tests/ui/issues/issue-65634-raw-ident-suggestion.edition2015.stderr4
-rw-r--r--tests/ui/issues/issue-65634-raw-ident-suggestion.edition2018.stderr4
-rw-r--r--tests/ui/issues/issue-69455.stderr4
-rw-r--r--tests/ui/issues/issue-69683.stderr2
-rw-r--r--tests/ui/issues/issue-70093/issue-70093-link-directives.rs10
-rw-r--r--tests/ui/issues/issue-70093/issue-70093.rs (renamed from tests/ui/issues/issue-70093.rs)0
-rw-r--r--tests/ui/lang-items/bad-add-impl.rs18
-rw-r--r--tests/ui/lang-items/bad-add-impl.stderr11
-rw-r--r--tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_item.stderr18
-rw-r--r--tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_sig.stderr18
-rw-r--r--tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_item.stderr18
-rw-r--r--tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_sig.stderr18
-rw-r--r--tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_item.stderr18
-rw-r--r--tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_sig.stderr18
-rw-r--r--tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_item.stderr18
-rw-r--r--tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_sig.stderr18
-rw-r--r--tests/ui/lang-items/fn-fn_mut-call-ill-formed.rs34
-rw-r--r--tests/ui/lang-items/fn-fn_mut-call-ill-formed.stderr14
-rw-r--r--tests/ui/lang-items/issue-86238.stderr2
-rw-r--r--tests/ui/late-bound-lifetimes/mismatched_arg_count.rs2
-rw-r--r--tests/ui/late-bound-lifetimes/mismatched_arg_count.stderr2
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr2
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr2
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr2
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr2
-rw-r--r--tests/ui/lint/dead-code/in-closure.rs16
-rw-r--r--tests/ui/lint/dead-code/in-closure.stderr20
-rw-r--r--tests/ui/lint/dead-code/issue-85255.rs12
-rw-r--r--tests/ui/lint/dead-code/issue-85255.stderr12
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-3.rs2
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-3.stderr2
-rw-r--r--tests/ui/lint/invalid_value.stderr40
-rw-r--r--tests/ui/lint/issue-106991.rs13
-rw-r--r--tests/ui/lint/issue-106991.stderr11
-rw-r--r--tests/ui/lint/lint-missing-doc.rs6
-rw-r--r--tests/ui/lint/lint-missing-doc.stderr46
-rw-r--r--tests/ui/lint/lint-stability-deprecated.rs144
-rw-r--r--tests/ui/lint/lint-stability-deprecated.stderr224
-rw-r--r--tests/ui/lint/lint_map_unit_fn.rs20
-rw-r--r--tests/ui/lint/lint_map_unit_fn.stderr66
-rw-r--r--tests/ui/match/match-ref-mut-invariance.stderr2
-rw-r--r--tests/ui/match/match-ref-mut-let-invariance.stderr2
-rw-r--r--tests/ui/methods/issues/issue-105732.stderr2
-rw-r--r--tests/ui/methods/issues/issue-61525.stderr2
-rw-r--r--tests/ui/methods/method-ambig-two-traits-cross-crate.stderr4
-rw-r--r--tests/ui/methods/method-ambig-two-traits-from-bounds.stderr4
-rw-r--r--tests/ui/methods/method-ambig-two-traits-from-impls.stderr4
-rw-r--r--tests/ui/methods/method-ambig-two-traits-with-default-method.stderr4
-rw-r--r--tests/ui/methods/method-call-err-msg.stderr8
-rw-r--r--tests/ui/methods/method-call-lifetime-args-fail.rs8
-rw-r--r--tests/ui/methods/method-call-lifetime-args-fail.stderr16
-rw-r--r--tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr6
-rw-r--r--tests/ui/methods/method-self-arg-1.stderr4
-rw-r--r--tests/ui/mismatched_types/issue-47706.stderr2
-rw-r--r--tests/ui/nll/outlives-suggestion-simple.stderr4
-rw-r--r--tests/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr5
-rw-r--r--tests/ui/privacy/privacy1.rs2
-rw-r--r--tests/ui/privacy/privacy1.stderr6
-rw-r--r--tests/ui/privacy/private-impl-method.rs2
-rw-r--r--tests/ui/privacy/private-impl-method.stderr6
-rw-r--r--tests/ui/privacy/private-method-cross-crate.rs2
-rw-r--r--tests/ui/privacy/private-method-cross-crate.stderr6
-rw-r--r--tests/ui/privacy/private-method-inherited.rs2
-rw-r--r--tests/ui/privacy/private-method-inherited.stderr6
-rw-r--r--tests/ui/privacy/private-method.rs2
-rw-r--r--tests/ui/privacy/private-method.stderr6
-rw-r--r--tests/ui/privacy/restricted/test.stderr18
-rw-r--r--tests/ui/recursion_limit/issue-105700.rs (renamed from tests/ui/recursion_limit/issue_21102.rs)0
-rw-r--r--tests/ui/recursion_limit/issue-105700.stderr (renamed from tests/ui/recursion_limit/issue_21102.stderr)4
-rw-r--r--tests/ui/regions/regions-early-bound-error-method.stderr2
-rw-r--r--tests/ui/regions/regions-free-region-ordering-incorrect.stderr2
-rw-r--r--tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs2
-rw-r--r--tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.stderr7
-rw-r--r--tests/ui/regions/regions-static-bound-rpass.rs2
-rw-r--r--tests/ui/regions/regions-static-bound-rpass.stderr11
-rw-r--r--tests/ui/regions/regions-static-bound.rs8
-rw-r--r--tests/ui/regions/regions-static-bound.stderr30
-rw-r--r--tests/ui/regions/resolve-re-error-ice.rs22
-rw-r--r--tests/ui/regions/resolve-re-error-ice.stderr15
-rw-r--r--tests/ui/rfc-2091-track-caller/error-with-main.stderr2
-rw-r--r--tests/ui/rfc-2457/mod_file_nonascii_forbidden.stderr2
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/do-not-const-check-override.rs19
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/do-not-const-check.rs18
-rw-r--r--tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr6
-rw-r--r--tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr6
-rw-r--r--tests/ui/self/elision/lt-ref-self-async.stderr12
-rw-r--r--tests/ui/self/elision/lt-ref-self.stderr12
-rw-r--r--tests/ui/self/elision/ref-mut-self-async.stderr12
-rw-r--r--tests/ui/self/elision/ref-mut-self.stderr12
-rw-r--r--tests/ui/self/elision/ref-mut-struct-async.stderr10
-rw-r--r--tests/ui/self/elision/ref-mut-struct.stderr10
-rw-r--r--tests/ui/self/elision/ref-self-async.stderr14
-rw-r--r--tests/ui/self/elision/ref-self.stderr14
-rw-r--r--tests/ui/self/elision/ref-struct-async.stderr10
-rw-r--r--tests/ui/self/elision/ref-struct.stderr10
-rw-r--r--tests/ui/seq-args.rs4
-rw-r--r--tests/ui/seq-args.stderr4
-rw-r--r--tests/ui/span/issue-37767.stderr12
-rw-r--r--tests/ui/span/issue-42234-unknown-receiver-type.full.stderr2
-rw-r--r--tests/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr2
-rw-r--r--tests/ui/span/missing-unit-argument.stderr4
-rw-r--r--tests/ui/span/type-annotations-needed-expr.stderr2
-rw-r--r--tests/ui/stability-attribute/unresolved_stability_lint.rs8
-rw-r--r--tests/ui/stability-attribute/unresolved_stability_lint.stderr9
-rw-r--r--tests/ui/static/static-lifetime-bound.rs2
-rw-r--r--tests/ui/static/static-lifetime-bound.stderr10
-rw-r--r--tests/ui/statics/uninhabited-static.stderr10
-rw-r--r--tests/ui/stats/hir-stats.stderr208
-rw-r--r--tests/ui/structs/struct-path-associated-type.rs4
-rw-r--r--tests/ui/structs/struct-path-associated-type.stderr4
-rw-r--r--tests/ui/structs/structure-constructor-type-mismatch.rs4
-rw-r--r--tests/ui/structs/structure-constructor-type-mismatch.stderr4
-rw-r--r--tests/ui/suggestions/assoc-ct-for-assoc-method.stderr2
-rw-r--r--tests/ui/suggestions/fn-or-tuple-struct-without-args.stderr8
-rw-r--r--tests/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr2
-rw-r--r--tests/ui/suggestions/issue-101421.rs2
-rw-r--r--tests/ui/suggestions/issue-101421.stderr4
-rw-r--r--tests/ui/suggestions/issue-104287.rs2
-rw-r--r--tests/ui/suggestions/issue-104287.stderr4
-rw-r--r--tests/ui/suggestions/issue-84973.stderr2
-rw-r--r--tests/ui/suggestions/issue-85347.rs2
-rw-r--r--tests/ui/suggestions/issue-85347.stderr2
-rw-r--r--tests/ui/suggestions/issue-89064.stderr8
-rw-r--r--tests/ui/suggestions/missing-lifetime-specifier.rs20
-rw-r--r--tests/ui/suggestions/missing-lifetime-specifier.stderr20
-rw-r--r--tests/ui/suggestions/missing-type-param-used-in-param.stderr2
-rw-r--r--tests/ui/suggestions/move-generic-to-trait-in-method-with-params.rs2
-rw-r--r--tests/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr4
-rw-r--r--tests/ui/suggestions/sugg-else-for-closure.stderr2
-rw-r--r--tests/ui/suggestions/trait-with-missing-associated-type-restriction.stderr2
-rw-r--r--tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr2
-rw-r--r--tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs2
-rw-r--r--tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr2
-rw-r--r--tests/ui/tool-attributes/auxiliary/p1.rs3
-rw-r--r--tests/ui/tool-attributes/auxiliary/p2.rs3
-rw-r--r--tests/ui/tool-attributes/duplicate-diagnostic.rs13
-rw-r--r--tests/ui/tool-attributes/duplicate-diagnostic.stderr12
-rw-r--r--tests/ui/traits/alias/ambiguous.stderr4
-rw-r--r--tests/ui/traits/inductive-overflow/supertrait-auto-trait.stderr2
-rw-r--r--tests/ui/traits/issue-52893.stderr2
-rw-r--r--tests/ui/traits/issue-77982.stderr4
-rw-r--r--tests/ui/traits/item-privacy.rs4
-rw-r--r--tests/ui/traits/item-privacy.stderr12
-rw-r--r--tests/ui/traits/method-private.stderr6
-rw-r--r--tests/ui/traits/multidispatch-convert-ambig-dest.stderr2
-rw-r--r--tests/ui/traits/new-solver/higher-ranked-dyn-bounds.rs17
-rw-r--r--tests/ui/traits/new-solver/more-object-bound.rs27
-rw-r--r--tests/ui/traits/new-solver/more-object-bound.stderr19
-rw-r--r--tests/ui/traits/new-solver/object-unsafety.rs20
-rw-r--r--tests/ui/traits/new-solver/object-unsafety.stderr19
-rw-r--r--tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr6
-rw-r--r--tests/ui/traits/non_lifetime_binders/fail.stderr4
-rw-r--r--tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.rs14
-rw-r--r--tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr11
-rw-r--r--tests/ui/traits/object/enforce-supertrait-projection.stderr2
-rw-r--r--tests/ui/traits/object/vs-lifetime.rs4
-rw-r--r--tests/ui/traits/object/vs-lifetime.stderr4
-rw-r--r--tests/ui/traits/test-2.rs4
-rw-r--r--tests/ui/traits/test-2.stderr8
-rw-r--r--tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr12
-rw-r--r--tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr40
-rw-r--r--tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr12
-rw-r--r--tests/ui/transmutability/enums/should_pad_variants.stderr2
-rw-r--r--tests/ui/transmutability/enums/should_respect_endianness.stderr2
-rw-r--r--tests/ui/transmutability/issue-101739-2.rs2
-rw-r--r--tests/ui/transmutability/issue-101739-2.stderr2
-rw-r--r--tests/ui/transmutability/primitives/bool.stderr2
-rw-r--r--tests/ui/transmutability/primitives/numbers.stderr114
-rw-r--r--tests/ui/transmutability/primitives/unit.stderr2
-rw-r--r--tests/ui/transmutability/references.stderr2
-rw-r--r--tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr24
-rw-r--r--tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr4
-rw-r--r--tests/ui/transmutability/unions/should_pad_variants.stderr2
-rw-r--r--tests/ui/transmutability/unions/should_reject_contraction.stderr2
-rw-r--r--tests/ui/transmutability/unions/should_reject_disjoint.stderr4
-rw-r--r--tests/ui/transmutability/unions/should_reject_intersecting.stderr4
-rw-r--r--tests/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr2
-rw-r--r--tests/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr2
-rw-r--r--tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr2
-rw-r--r--tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr2
-rw-r--r--tests/ui/transmute/transmute-padding-ice.stderr2
-rw-r--r--tests/ui/tuple/wrong_argument_ice-3.stderr2
-rw-r--r--tests/ui/tuple/wrong_argument_ice.stderr2
-rw-r--r--tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs12
-rw-r--r--tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/bounds-are-checked.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/bounds-are-checked.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr34
-rw-r--r--tests/ui/type-alias-impl-trait/match-unification.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr2
-rw-r--r--tests/ui/type-inference/sort_by_key.stderr2
-rw-r--r--tests/ui/type/type-check/point-at-inference-3.fixed2
-rw-r--r--tests/ui/type/type-check/point-at-inference-3.rs2
-rw-r--r--tests/ui/type/type-check/point-at-inference-3.stderr2
-rw-r--r--tests/ui/type/type-check/point-at-inference-4.rs2
-rw-r--r--tests/ui/type/type-check/point-at-inference-4.stderr2
-rw-r--r--tests/ui/type/wrong-call-return-type-due-to-generic-arg.stderr2
-rw-r--r--tests/ui/typeck/bad-type-in-vec-push.stderr4
-rw-r--r--tests/ui/typeck/issue-104513-ice.stderr2
-rw-r--r--tests/ui/typeck/issue-75883.rs4
-rw-r--r--tests/ui/typeck/issue-75883.stderr4
-rw-r--r--tests/ui/typeck/issue-84768.stderr2
-rw-r--r--tests/ui/typeck/lazy-norm/cast-checks-handling-projections.rs6
-rw-r--r--tests/ui/typeck/lazy-norm/cast-checks-handling-projections.stderr9
-rw-r--r--tests/ui/typeck/typeck-builtin-bound-type-parameters.rs12
-rw-r--r--tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr12
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item.rs4
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item.stderr34
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_lifetime_1.rs2
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_lifetime_1.stderr2
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_lifetime_2.rs2
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_lifetime_2.stderr2
-rw-r--r--tests/ui/ufcs/ufcs-qpath-missing-params.rs2
-rw-r--r--tests/ui/ufcs/ufcs-qpath-missing-params.stderr4
-rw-r--r--tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr4
-rw-r--r--tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs2
-rw-r--r--tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr2
-rw-r--r--tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs2
-rw-r--r--tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr2
-rw-r--r--tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs2
-rw-r--r--tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr2
-rw-r--r--tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs2
-rw-r--r--tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr2
-rw-r--r--tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.rs10
-rw-r--r--tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.stderr10
-rw-r--r--tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.rs2
-rw-r--r--tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.stderr2
-rw-r--r--tests/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr2
-rw-r--r--tests/ui/unsized/issue-71659.stderr2
-rw-r--r--tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr2
-rw-r--r--tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr2
-rw-r--r--tests/ui/xc-private-method2.rs4
-rw-r--r--tests/ui/xc-private-method2.stderr12
1081 files changed, 12022 insertions, 8319 deletions
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index d20f19e60e8..353bfcb6ac1 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -1,3 +1,5 @@
+# Use `git config blame.ignorerevsfile .git-blame-ignore-revs` to make `git blame` ignore the following commits.
+
 # format the world
 a06baa56b95674fc626b3c3fd680d6a65357fe60
 # format libcore
diff --git a/Cargo.lock b/Cargo.lock
index 6c17edd3020..9e5deedb66f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -90,15 +90,6 @@ dependencies = [
 
 [[package]]
 name = "ansi_term"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
-dependencies = [
- "winapi",
-]
-
-[[package]]
-name = "ansi_term"
 version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
@@ -390,7 +381,6 @@ dependencies = [
  "os_info",
  "pasetors",
  "pathdiff",
- "percent-encoding",
  "pretty_env_logger",
  "rustc-workspace-hack",
  "rustfix",
@@ -891,11 +881,11 @@ dependencies = [
  "diff",
  "getopts",
  "glob",
- "lazy_static",
  "lazycell",
  "libc",
- "miow 0.3.7",
+ "miow 0.5.0",
  "miropt-test-tools",
+ "once_cell",
  "regex",
  "rustfix",
  "serde",
@@ -1217,12 +1207,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
 
 [[package]]
-name = "difference"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
-
-[[package]]
 name = "digest"
 version = "0.10.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1379,6 +1363,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "elsa"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f74077c3c3aedb99a2683919698285596662518ea13e5eedcf8bdd43b0d0453b"
+dependencies = [
+ "stable_deref_trait",
+]
+
+[[package]]
 name = "ena"
 version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1452,6 +1445,7 @@ name = "error_index_generator"
 version = "0.0.0"
 dependencies = [
  "mdbook",
+ "rustc_error_codes",
 ]
 
 [[package]]
@@ -1934,8 +1928,16 @@ version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
 dependencies = [
- "compiler_builtins",
  "libc",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "856b5cb0902c2b6d65d5fd97dfa30f9b70c7538e770b98eab5ed52d8db923e01"
+dependencies = [
+ "compiler_builtins",
  "rustc-std-workspace-alloc",
  "rustc-std-workspace-core",
 ]
@@ -3184,14 +3186,14 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
 
 [[package]]
 name = "pretty_assertions"
-version = "0.6.1"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427"
+checksum = "a25e9bcb20aa780fd0bb16b72403a9064d6b3f22f026946029acb941a50af755"
 dependencies = [
- "ansi_term 0.11.0",
  "ctor",
- "difference",
+ "diff",
  "output_vt100",
+ "yansi",
 ]
 
 [[package]]
@@ -3689,6 +3691,7 @@ dependencies = [
  "rustc_session",
  "rustc_span",
  "rustc_target",
+ "thin-vec",
  "tracing",
 ]
 
@@ -3698,6 +3701,7 @@ version = "0.0.0"
 dependencies = [
  "rustc_ast",
  "rustc_span",
+ "thin-vec",
 ]
 
 [[package]]
@@ -3882,6 +3886,7 @@ dependencies = [
  "arrayvec 0.7.0",
  "bitflags",
  "cfg-if",
+ "elsa",
  "ena",
  "indexmap",
  "jobserver",
@@ -3918,26 +3923,47 @@ version = "0.0.0"
 dependencies = [
  "libc",
  "rustc_ast",
+ "rustc_ast_lowering",
+ "rustc_ast_passes",
  "rustc_ast_pretty",
+ "rustc_attr",
+ "rustc_borrowck",
+ "rustc_builtin_macros",
  "rustc_codegen_ssa",
+ "rustc_const_eval",
  "rustc_data_structures",
  "rustc_error_codes",
+ "rustc_error_messages",
  "rustc_errors",
+ "rustc_expand",
  "rustc_feature",
  "rustc_hir",
  "rustc_hir_analysis",
  "rustc_hir_pretty",
+ "rustc_hir_typeck",
+ "rustc_incremental",
+ "rustc_infer",
  "rustc_interface",
  "rustc_lint",
  "rustc_log",
  "rustc_macros",
  "rustc_metadata",
  "rustc_middle",
+ "rustc_mir_build",
+ "rustc_mir_dataflow",
+ "rustc_monomorphize",
  "rustc_parse",
+ "rustc_passes",
  "rustc_plugin_impl",
+ "rustc_privacy",
+ "rustc_query_system",
+ "rustc_resolve",
  "rustc_session",
  "rustc_span",
+ "rustc_symbol_mangling",
  "rustc_target",
+ "rustc_trait_selection",
+ "rustc_ty_utils",
  "serde_json",
  "tracing",
  "winapi",
@@ -4071,6 +4097,7 @@ dependencies = [
  "rustc_trait_selection",
  "rustc_type_ir",
  "smallvec",
+ "thin-vec",
  "tracing",
 ]
 
@@ -4127,6 +4154,7 @@ dependencies = [
  "rustc_serialize",
  "rustc_session",
  "rustc_span",
+ "thin-vec",
  "tracing",
 ]
 
@@ -4826,7 +4854,6 @@ dependencies = [
  "serde_json",
  "smallvec",
  "tempfile",
- "thin-vec",
  "tracing",
  "tracing-subscriber",
  "tracing-tree",
@@ -5276,7 +5303,7 @@ dependencies = [
  "dlmalloc",
  "fortanix-sgx-abi",
  "hashbrown 0.12.3",
- "hermit-abi 0.2.6",
+ "hermit-abi 0.3.0",
  "libc",
  "miniz_oxide",
  "object 0.29.0",
@@ -5471,10 +5498,8 @@ dependencies = [
 name = "test"
 version = "0.0.0"
 dependencies = [
- "cfg-if",
  "core",
  "getopts",
- "libc",
  "panic_abort",
  "panic_unwind",
  "proc_macro",
@@ -5502,9 +5527,9 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
 
 [[package]]
 name = "thin-vec"
-version = "0.2.9"
+version = "0.2.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ceb05e71730d396f960f8f3901cdb41be2d339b303e9d7d3a07c5ff0536e671b"
+checksum = "aac81b6fd6beb5884b0cf3321b8117e6e5d47ecb6fc89f414cfdcca8b2fe2dd8"
 
 [[package]]
 name = "thiserror"
@@ -5749,7 +5774,7 @@ version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "245da694cc7fc4729f3f418b304cb57789f1bed2a78c575407ab8a23f53cb4d3"
 dependencies = [
- "ansi_term 0.12.1",
+ "ansi_term",
  "lazy_static",
  "matchers",
  "parking_lot 0.11.2",
@@ -5768,7 +5793,7 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3ce989c9962c7f61fe084dd4a230eec784649dfc2392467c790007c3a6e134e7"
 dependencies = [
- "ansi_term 0.12.1",
+ "ansi_term",
  "atty",
  "tracing-core",
  "tracing-log",
diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml
index 10d7fa1db60..f0632ac92e9 100644
--- a/compiler/rustc_ast/Cargo.toml
+++ b/compiler/rustc_ast/Cargo.toml
@@ -15,5 +15,5 @@ rustc_macros = { path = "../rustc_macros" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_span = { path = "../rustc_span" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-thin-vec = "0.2.9"
+thin-vec = "0.2.12"
 tracing = "0.1"
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index f2258fecfea..03c375c4666 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -209,7 +209,7 @@ pub struct AngleBracketedArgs {
     /// The overall span.
     pub span: Span,
     /// The comma separated parts in the `<...>`.
-    pub args: Vec<AngleBracketedArg>,
+    pub args: ThinVec<AngleBracketedArg>,
 }
 
 /// Either an argument for a parameter e.g., `'a`, `Vec<u8>`, `0`,
@@ -253,7 +253,7 @@ pub struct ParenthesizedArgs {
     pub span: Span,
 
     /// `(A, B)`
-    pub inputs: Vec<P<Ty>>,
+    pub inputs: ThinVec<P<Ty>>,
 
     /// ```text
     /// Foo(A, B) -> C
@@ -384,7 +384,7 @@ impl GenericParam {
 /// a function, enum, trait, etc.
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Generics {
-    pub params: Vec<GenericParam>,
+    pub params: ThinVec<GenericParam>,
     pub where_clause: WhereClause,
     pub span: Span,
 }
@@ -392,7 +392,7 @@ pub struct Generics {
 impl Default for Generics {
     /// Creates an instance of `Generics`.
     fn default() -> Generics {
-        Generics { params: Vec::new(), where_clause: Default::default(), span: DUMMY_SP }
+        Generics { params: ThinVec::new(), where_clause: Default::default(), span: DUMMY_SP }
     }
 }
 
@@ -403,13 +403,13 @@ pub struct WhereClause {
     /// if we parsed no predicates (e.g. `struct Foo where {}`).
     /// This allows us to pretty-print accurately.
     pub has_where_token: bool,
-    pub predicates: Vec<WherePredicate>,
+    pub predicates: ThinVec<WherePredicate>,
     pub span: Span,
 }
 
 impl Default for WhereClause {
     fn default() -> WhereClause {
-        WhereClause { has_where_token: false, predicates: Vec::new(), span: DUMMY_SP }
+        WhereClause { has_where_token: false, predicates: ThinVec::new(), span: DUMMY_SP }
     }
 }
 
@@ -441,7 +441,7 @@ impl WherePredicate {
 pub struct WhereBoundPredicate {
     pub span: Span,
     /// Any generics from a `for` binding.
-    pub bound_generic_params: Vec<GenericParam>,
+    pub bound_generic_params: ThinVec<GenericParam>,
     /// The type being bounded.
     pub bounded_ty: P<Ty>,
     /// Trait and lifetime bounds (`Clone + Send + 'static`).
@@ -471,7 +471,7 @@ pub struct WhereEqPredicate {
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Crate {
     pub attrs: AttrVec,
-    pub items: Vec<P<Item>>,
+    pub items: ThinVec<P<Item>>,
     pub spans: ModSpans,
     /// Must be equal to `CRATE_NODE_ID` after the crate root is expanded, but may hold
     /// expansion placeholders or an unassigned value (`DUMMY_NODE_ID`) before that.
@@ -503,7 +503,7 @@ pub enum MetaItemKind {
     /// List meta item.
     ///
     /// E.g., `#[derive(..)]`, where the field represents the `..`.
-    List(Vec<NestedMetaItem>),
+    List(ThinVec<NestedMetaItem>),
 
     /// Name value meta item.
     ///
@@ -531,7 +531,7 @@ pub enum NestedMetaItem {
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Block {
     /// The statements in the block.
-    pub stmts: Vec<Stmt>,
+    pub stmts: ThinVec<Stmt>,
     pub id: NodeId,
     /// Distinguishes between `unsafe { ... }` and `{ ... }`.
     pub rules: BlockCheckMode,
@@ -581,7 +581,7 @@ impl Pat {
             // A tuple pattern `(P0, .., Pn)` can be reparsed as `(T0, .., Tn)`
             // assuming `T0` to `Tn` are all syntactically valid as types.
             PatKind::Tuple(pats) => {
-                let mut tys = Vec::with_capacity(pats.len());
+                let mut tys = ThinVec::with_capacity(pats.len());
                 // FIXME(#48994) - could just be collected into an Option<Vec>
                 for pat in pats {
                     tys.push(pat.to_ty()?);
@@ -722,14 +722,14 @@ pub enum PatKind {
 
     /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
     /// The `bool` is `true` in the presence of a `..`.
-    Struct(Option<P<QSelf>>, Path, Vec<PatField>, /* recovered */ bool),
+    Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, /* recovered */ bool),
 
     /// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
-    TupleStruct(Option<P<QSelf>>, Path, Vec<P<Pat>>),
+    TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>),
 
     /// An or-pattern `A | B | C`.
     /// Invariant: `pats.len() >= 2`.
-    Or(Vec<P<Pat>>),
+    Or(ThinVec<P<Pat>>),
 
     /// A possibly qualified path pattern.
     /// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants
@@ -738,7 +738,7 @@ pub enum PatKind {
     Path(Option<P<QSelf>>, Path),
 
     /// A tuple pattern (`(a, b)`).
-    Tuple(Vec<P<Pat>>),
+    Tuple(ThinVec<P<Pat>>),
 
     /// A `box` pattern.
     Box(P<Pat>),
@@ -753,7 +753,7 @@ pub enum PatKind {
     Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>),
 
     /// A slice pattern `[a, b, c]`.
-    Slice(Vec<P<Pat>>),
+    Slice(ThinVec<P<Pat>>),
 
     /// A rest pattern `..`.
     ///
@@ -1169,7 +1169,7 @@ impl Expr {
     pub fn to_bound(&self) -> Option<GenericBound> {
         match &self.kind {
             ExprKind::Path(None, path) => Some(GenericBound::Trait(
-                PolyTraitRef::new(Vec::new(), path.clone(), self.span),
+                PolyTraitRef::new(ThinVec::new(), path.clone(), self.span),
                 TraitBoundModifier::None,
             )),
             _ => None,
@@ -1204,7 +1204,7 @@ impl Expr {
             ExprKind::Array(exprs) if exprs.len() == 1 => exprs[0].to_ty().map(TyKind::Slice)?,
 
             ExprKind::Tup(exprs) => {
-                let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<Vec<_>>>()?;
+                let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
                 TyKind::Tup(tys)
             }
 
@@ -1337,7 +1337,7 @@ pub struct MethodCall {
     /// The receiver, e.g. `x`.
     pub receiver: P<Expr>,
     /// The arguments, e.g. `a, b, c`.
-    pub args: Vec<P<Expr>>,
+    pub args: ThinVec<P<Expr>>,
     /// The span of the function, without the dot and receiver e.g. `foo::<Bar,
     /// Baz>(a, b, c)`.
     pub span: Span,
@@ -1357,7 +1357,7 @@ pub enum StructRest {
 pub struct StructExpr {
     pub qself: Option<P<QSelf>>,
     pub path: Path,
-    pub fields: Vec<ExprField>,
+    pub fields: ThinVec<ExprField>,
     pub rest: StructRest,
 }
 
@@ -1366,7 +1366,7 @@ pub enum ExprKind {
     /// A `box x` expression.
     Box(P<Expr>),
     /// An array (`[a, b, c, d]`)
-    Array(Vec<P<Expr>>),
+    Array(ThinVec<P<Expr>>),
     /// Allow anonymous constants from an inline `const` block
     ConstBlock(AnonConst),
     /// A function call
@@ -1375,11 +1375,11 @@ pub enum ExprKind {
     /// and the second field is the list of arguments.
     /// This also represents calling the constructor of
     /// tuple-like ADTs such as tuple structs and enum variants.
-    Call(P<Expr>, Vec<P<Expr>>),
+    Call(P<Expr>, ThinVec<P<Expr>>),
     /// A method call (e.g. `x.foo::<Bar, Baz>(a, b, c)`).
     MethodCall(Box<MethodCall>),
     /// A tuple (e.g., `(a, b, c, d)`).
-    Tup(Vec<P<Expr>>),
+    Tup(ThinVec<P<Expr>>),
     /// A binary operation (e.g., `a + b`, `a * b`).
     Binary(BinOp, P<Expr>, P<Expr>),
     /// A unary operation (e.g., `!x`, `*x`).
@@ -1414,7 +1414,7 @@ pub enum ExprKind {
     /// `'label: loop { block }`
     Loop(P<Block>, Option<Label>, Span),
     /// A `match` block.
-    Match(P<Expr>, Vec<Arm>),
+    Match(P<Expr>, ThinVec<Arm>),
     /// A closure (e.g., `move |a, b, c| a + b + c`).
     Closure(Box<Closure>),
     /// A block (`'label: { ... }`).
@@ -1574,7 +1574,7 @@ pub enum ClosureBinder {
         /// for<'a, 'b> |_: &'a (), _: &'b ()| { ... }
         ///     ^^^^^^ -- this
         /// ```
-        generic_params: P<[GenericParam]>,
+        generic_params: ThinVec<GenericParam>,
     },
 }
 
@@ -2056,7 +2056,7 @@ impl Ty {
 pub struct BareFnTy {
     pub unsafety: Unsafe,
     pub ext: Extern,
-    pub generic_params: Vec<GenericParam>,
+    pub generic_params: ThinVec<GenericParam>,
     pub decl: P<FnDecl>,
     /// Span of the `fn(...) -> ...` part.
     pub decl_span: Span,
@@ -2078,7 +2078,7 @@ pub enum TyKind {
     /// The never type (`!`).
     Never,
     /// A tuple (`(A, B, C, D,...)`).
-    Tup(Vec<P<Ty>>),
+    Tup(ThinVec<P<Ty>>),
     /// A path (`module::module::...::Type`), optionally
     /// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
     ///
@@ -2363,7 +2363,7 @@ impl Param {
 /// which contains metadata about function safety, asyncness, constness and ABI.
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct FnDecl {
-    pub inputs: Vec<Param>,
+    pub inputs: ThinVec<Param>,
     pub output: FnRetTy,
 }
 
@@ -2475,7 +2475,7 @@ pub enum ModKind {
     /// or with definition outlined to a separate file `mod foo;` and already loaded from it.
     /// The inner span is from the first token past `{` to the last token until `}`,
     /// or from the first to the last token in the loaded file.
-    Loaded(Vec<P<Item>>, Inline, ModSpans),
+    Loaded(ThinVec<P<Item>>, Inline, ModSpans),
     /// Module with definition outlined to a separate file `mod foo;` but not yet loaded from it.
     Unloaded,
 }
@@ -2497,12 +2497,12 @@ pub struct ForeignMod {
     /// semantically by Rust.
     pub unsafety: Unsafe,
     pub abi: Option<StrLit>,
-    pub items: Vec<P<ForeignItem>>,
+    pub items: ThinVec<P<ForeignItem>>,
 }
 
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct EnumDef {
-    pub variants: Vec<Variant>,
+    pub variants: ThinVec<Variant>,
 }
 /// Enum variant.
 #[derive(Clone, Encodable, Decodable, Debug)]
@@ -2532,7 +2532,7 @@ pub enum UseTreeKind {
     /// `use prefix` or `use prefix as rename`
     Simple(Option<Ident>),
     /// `use prefix::{...}`
-    Nested(Vec<(UseTree, NodeId)>),
+    Nested(ThinVec<(UseTree, NodeId)>),
     /// `use prefix::*`
     Glob,
 }
@@ -2636,7 +2636,7 @@ pub struct TraitRef {
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct PolyTraitRef {
     /// The `'a` in `for<'a> Foo<&'a T>`.
-    pub bound_generic_params: Vec<GenericParam>,
+    pub bound_generic_params: ThinVec<GenericParam>,
 
     /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`.
     pub trait_ref: TraitRef,
@@ -2645,7 +2645,7 @@ pub struct PolyTraitRef {
 }
 
 impl PolyTraitRef {
-    pub fn new(generic_params: Vec<GenericParam>, path: Path, span: Span) -> Self {
+    pub fn new(generic_params: ThinVec<GenericParam>, path: Path, span: Span) -> Self {
         PolyTraitRef {
             bound_generic_params: generic_params,
             trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
@@ -2695,11 +2695,11 @@ pub enum VariantData {
     /// Struct variant.
     ///
     /// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`.
-    Struct(Vec<FieldDef>, bool),
+    Struct(ThinVec<FieldDef>, bool),
     /// Tuple variant.
     ///
     /// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`.
-    Tuple(Vec<FieldDef>, NodeId),
+    Tuple(ThinVec<FieldDef>, NodeId),
     /// Unit variant.
     ///
     /// E.g., `Bar = ..` as in `enum Foo { Bar = .. }`.
@@ -2826,7 +2826,7 @@ pub struct Trait {
     pub is_auto: IsAuto,
     pub generics: Generics,
     pub bounds: GenericBounds,
-    pub items: Vec<P<AssocItem>>,
+    pub items: ThinVec<P<AssocItem>>,
 }
 
 /// The location of a where clause on a `TyAlias` (`Span`) and whether there was
@@ -2874,7 +2874,7 @@ pub struct Impl {
     /// The trait being implemented, if any.
     pub of_trait: Option<TraitRef>,
     pub self_ty: P<Ty>,
-    pub items: Vec<P<AssocItem>>,
+    pub items: ThinVec<P<AssocItem>>,
 }
 
 #[derive(Clone, Encodable, Decodable, Debug)]
@@ -3112,26 +3112,26 @@ mod size_asserts {
     static_assert_size!(AssocItem, 104);
     static_assert_size!(AssocItemKind, 32);
     static_assert_size!(Attribute, 32);
-    static_assert_size!(Block, 48);
+    static_assert_size!(Block, 32);
     static_assert_size!(Expr, 72);
     static_assert_size!(ExprKind, 40);
-    static_assert_size!(Fn, 184);
+    static_assert_size!(Fn, 152);
     static_assert_size!(ForeignItem, 96);
     static_assert_size!(ForeignItemKind, 24);
     static_assert_size!(GenericArg, 24);
-    static_assert_size!(GenericBound, 72);
-    static_assert_size!(Generics, 72);
-    static_assert_size!(Impl, 184);
-    static_assert_size!(Item, 184);
-    static_assert_size!(ItemKind, 112);
+    static_assert_size!(GenericBound, 56);
+    static_assert_size!(Generics, 40);
+    static_assert_size!(Impl, 136);
+    static_assert_size!(Item, 136);
+    static_assert_size!(ItemKind, 64);
     static_assert_size!(LitKind, 24);
     static_assert_size!(Local, 72);
     static_assert_size!(MetaItemLit, 40);
     static_assert_size!(Param, 40);
-    static_assert_size!(Pat, 88);
+    static_assert_size!(Pat, 72);
     static_assert_size!(Path, 24);
     static_assert_size!(PathSegment, 24);
-    static_assert_size!(PatKind, 64);
+    static_assert_size!(PatKind, 48);
     static_assert_size!(Stmt, 32);
     static_assert_size!(StmtKind, 16);
     static_assert_size!(Ty, 64);
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index e75d2f77dbb..2e83b3e623f 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -20,7 +20,7 @@ use std::iter;
 use std::ops::BitXor;
 #[cfg(debug_assertions)]
 use std::sync::atomic::{AtomicU32, Ordering};
-use thin_vec::thin_vec;
+use thin_vec::{thin_vec, ThinVec};
 
 pub struct MarkedAttrs(GrowableBitSet<AttrId>);
 
@@ -135,7 +135,7 @@ impl Attribute {
         }
     }
 
-    pub fn meta_item_list(&self) -> Option<Vec<NestedMetaItem>> {
+    pub fn meta_item_list(&self) -> Option<ThinVec<NestedMetaItem>> {
         match &self.kind {
             AttrKind::Normal(normal) => normal.item.meta_item_list(),
             AttrKind::DocComment(..) => None,
@@ -216,7 +216,7 @@ impl AttrItem {
         self.args.span().map_or(self.path.span, |args_span| self.path.span.to(args_span))
     }
 
-    fn meta_item_list(&self) -> Option<Vec<NestedMetaItem>> {
+    fn meta_item_list(&self) -> Option<ThinVec<NestedMetaItem>> {
         match &self.args {
             AttrArgs::Delimited(args) if args.delim == MacDelimiter::Parenthesis => {
                 MetaItemKind::list_from_tokens(args.tokens.clone())
@@ -375,9 +375,9 @@ impl MetaItemKind {
         }
     }
 
-    fn list_from_tokens(tokens: TokenStream) -> Option<Vec<NestedMetaItem>> {
+    fn list_from_tokens(tokens: TokenStream) -> Option<ThinVec<NestedMetaItem>> {
         let mut tokens = tokens.into_trees().peekable();
-        let mut result = Vec::new();
+        let mut result = ThinVec::new();
         while tokens.peek().is_some() {
             let item = NestedMetaItem::from_tokens(&mut tokens)?;
             result.push(item);
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 1dd62626b8f..7dcb03b4c78 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -17,10 +17,10 @@ use rustc_data_structures::sync::Lrc;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::Ident;
 use rustc_span::Span;
-
 use smallvec::{smallvec, Array, SmallVec};
 use std::ops::DerefMut;
 use std::{panic, ptr};
+use thin_vec::ThinVec;
 
 pub trait ExpectOne<A: Array> {
     fn expect_one(self, err: &'static str) -> A::Item;
@@ -337,6 +337,17 @@ where
 
 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
 #[inline]
+pub fn visit_thin_vec<T, F>(elems: &mut ThinVec<T>, mut visit_elem: F)
+where
+    F: FnMut(&mut T),
+{
+    for elem in elems {
+        visit_elem(elem);
+    }
+}
+
+// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
+#[inline]
 pub fn visit_opt<T, F>(opt: &mut Option<T>, mut visit_elem: F)
 where
     F: FnMut(&mut T),
@@ -359,6 +370,11 @@ pub fn visit_exprs<T: MutVisitor>(exprs: &mut Vec<P<Expr>>, vis: &mut T) {
 }
 
 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
+pub fn visit_thin_exprs<T: MutVisitor>(exprs: &mut ThinVec<P<Expr>>, vis: &mut T) {
+    exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr))
+}
+
+// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
 pub fn visit_bounds<T: MutVisitor>(bounds: &mut GenericBounds, vis: &mut T) {
     visit_vec(bounds, |bound| vis.visit_param_bound(bound));
 }
@@ -474,7 +490,7 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
             vis.visit_fn_decl(decl);
             vis.visit_span(decl_span);
         }
-        TyKind::Tup(tys) => visit_vec(tys, |ty| vis.visit_ty(ty)),
+        TyKind::Tup(tys) => visit_thin_vec(tys, |ty| vis.visit_ty(ty)),
         TyKind::Paren(ty) => vis.visit_ty(ty),
         TyKind::Path(qself, path) => {
             vis.visit_qself(qself);
@@ -561,7 +577,7 @@ pub fn noop_visit_angle_bracketed_parameter_data<T: MutVisitor>(
     vis: &mut T,
 ) {
     let AngleBracketedArgs { args, span } = data;
-    visit_vec(args, |arg| match arg {
+    visit_thin_vec(args, |arg| match arg {
         AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg),
         AngleBracketedArg::Constraint(constraint) => vis.visit_constraint(constraint),
     });
@@ -573,7 +589,7 @@ pub fn noop_visit_parenthesized_parameter_data<T: MutVisitor>(
     vis: &mut T,
 ) {
     let ParenthesizedArgs { inputs, output, span, .. } = args;
-    visit_vec(inputs, |input| vis.visit_ty(input));
+    visit_thin_vec(inputs, |input| vis.visit_ty(input));
     noop_visit_fn_ret_ty(output, vis);
     vis.visit_span(span);
 }
@@ -636,7 +652,7 @@ pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) {
     let MetaItem { path: _, kind, span } = mi;
     match kind {
         MetaItemKind::Word => {}
-        MetaItemKind::List(mis) => visit_vec(mis, |mi| vis.visit_meta_list_item(mi)),
+        MetaItemKind::List(mis) => visit_thin_vec(mis, |mi| vis.visit_meta_list_item(mi)),
         MetaItemKind::NameValue(_s) => {}
     }
     vis.visit_span(span);
@@ -839,9 +855,7 @@ pub fn noop_visit_closure_binder<T: MutVisitor>(binder: &mut ClosureBinder, vis:
     match binder {
         ClosureBinder::NotPresent => {}
         ClosureBinder::For { span: _, generic_params } => {
-            let mut vec = std::mem::take(generic_params).into_vec();
-            vec.flat_map_in_place(|param| vis.flat_map_generic_param(param));
-            *generic_params = P::from_vec(vec);
+            generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
         }
     }
 }
@@ -919,7 +933,7 @@ pub fn noop_visit_generics<T: MutVisitor>(generics: &mut Generics, vis: &mut T)
 
 pub fn noop_visit_where_clause<T: MutVisitor>(wc: &mut WhereClause, vis: &mut T) {
     let WhereClause { has_where_token: _, predicates, span } = wc;
-    visit_vec(predicates, |predicate| vis.visit_where_predicate(predicate));
+    visit_thin_vec(predicates, |predicate| vis.visit_where_predicate(predicate));
     vis.visit_span(span);
 }
 
@@ -1227,7 +1241,7 @@ pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
         PatKind::TupleStruct(qself, path, elems) => {
             vis.visit_qself(qself);
             vis.visit_path(path);
-            visit_vec(elems, |elem| vis.visit_pat(elem));
+            visit_thin_vec(elems, |elem| vis.visit_pat(elem));
         }
         PatKind::Path(qself, path) => {
             vis.visit_qself(qself);
@@ -1246,7 +1260,7 @@ pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
             vis.visit_span(span);
         }
         PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => {
-            visit_vec(elems, |elem| vis.visit_pat(elem))
+            visit_thin_vec(elems, |elem| vis.visit_pat(elem))
         }
         PatKind::Paren(inner) => vis.visit_pat(inner),
         PatKind::MacCall(mac) => vis.visit_mac_call(mac),
@@ -1303,7 +1317,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
 ) {
     match kind {
         ExprKind::Box(expr) => vis.visit_expr(expr),
-        ExprKind::Array(exprs) => visit_exprs(exprs, vis),
+        ExprKind::Array(exprs) => visit_thin_exprs(exprs, vis),
         ExprKind::ConstBlock(anon_const) => {
             vis.visit_anon_const(anon_const);
         }
@@ -1311,10 +1325,10 @@ pub fn noop_visit_expr<T: MutVisitor>(
             vis.visit_expr(expr);
             vis.visit_anon_const(count);
         }
-        ExprKind::Tup(exprs) => visit_exprs(exprs, vis),
+        ExprKind::Tup(exprs) => visit_thin_exprs(exprs, vis),
         ExprKind::Call(f, args) => {
             vis.visit_expr(f);
-            visit_exprs(args, vis);
+            visit_thin_exprs(args, vis);
         }
         ExprKind::MethodCall(box MethodCall {
             seg: PathSegment { ident, id, args: seg_args },
@@ -1326,7 +1340,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
             vis.visit_id(id);
             visit_opt(seg_args, |args| vis.visit_generic_args(args));
             vis.visit_method_receiver_expr(receiver);
-            visit_exprs(call_args, vis);
+            visit_thin_exprs(call_args, vis);
             vis.visit_span(span);
         }
         ExprKind::Binary(_binop, lhs, rhs) => {
diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml
index 6e76c349a4a..eb2e82d7988 100644
--- a/compiler/rustc_ast_lowering/Cargo.toml
+++ b/compiler/rustc_ast_lowering/Cargo.toml
@@ -19,5 +19,5 @@ rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-thin-vec = "0.2.9"
+thin-vec = "0.2.12"
 tracing = "0.1"
diff --git a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl b/compiler/rustc_ast_lowering/locales/en-US.ftl
index 03c88c6c0eb..a2837deafde 100644
--- a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl
+++ b/compiler/rustc_ast_lowering/locales/en-US.ftl
@@ -19,6 +19,9 @@ ast_lowering_remove_parentheses = remove these parentheses
 ast_lowering_misplaced_impl_trait =
     `impl Trait` only allowed in function and inherent method return types, not in {$position}
 
+ast_lowering_misplaced_assoc_ty_binding =
+    associated type bounds are only allowed in where clauses and function signatures, not in {$position}
+
 ast_lowering_rustc_box_attribute_error =
     #[rustc_box] requires precisely one argument and no other attributes are allowed
 
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index 21c6a2d26f4..def74c2adee 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -79,6 +79,14 @@ pub struct MisplacedImplTrait<'a> {
     pub position: DiagnosticArgFromDisplay<'a>,
 }
 
+#[derive(Diagnostic)]
+#[diag(ast_lowering_misplaced_assoc_ty_binding)]
+pub struct MisplacedAssocTyBinding<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub position: DiagnosticArgFromDisplay<'a>,
+}
+
 #[derive(Diagnostic, Clone, Copy)]
 #[diag(ast_lowering_rustc_box_attribute_error)]
 pub struct RustcBoxAttributeError {
@@ -339,7 +347,7 @@ pub struct InclusiveRangeWithNoEnd {
 #[derive(Diagnostic, Clone, Copy)]
 #[diag(ast_lowering_trait_fn_async, code = "E0706")]
 #[note]
-#[note(note2)]
+#[note(ast_lowering_note2)]
 pub struct TraitFnAsync {
     #[primary_span]
     pub fn_span: Span,
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index c4442b34fe4..d4fafe38638 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -18,7 +18,7 @@ use rustc_session::errors::report_lit_error;
 use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned};
 use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::DUMMY_SP;
-use thin_vec::thin_vec;
+use thin_vec::{thin_vec, ThinVec};
 
 impl<'hir> LoweringContext<'_, 'hir> {
     fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> &'hir [hir::Expr<'hir>] {
@@ -88,8 +88,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             let kind = hir::ExprKind::Box(self.lower_expr(&inner));
                             return hir::Expr { hir_id, kind, span: self.lower_span(e.span) };
                         } else {
-                            self.tcx.sess.emit_err(RustcBoxAttributeError { span: e.span });
-                            hir::ExprKind::Err
+                            let guar = self.tcx.sess.emit_err(RustcBoxAttributeError { span: e.span });
+                            hir::ExprKind::Err(guar)
                         }
                     } else if let Some(legacy_args) = self.resolver.legacy_const_generic_args(f) {
                         self.lower_legacy_const_generics((**f).clone(), args.clone(), &legacy_args)
@@ -266,8 +266,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), *lims)
                 }
                 ExprKind::Underscore => {
-                    self.tcx.sess.emit_err(UnderscoreExprLhsAssign { span: e.span });
-                    hir::ExprKind::Err
+                    let guar = self.tcx.sess.emit_err(UnderscoreExprLhsAssign { span: e.span });
+                    hir::ExprKind::Err(guar)
                 }
                 ExprKind::Path(qself, path) => {
                     let qpath = self.lower_qpath(
@@ -299,8 +299,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     let rest = match &se.rest {
                         StructRest::Base(e) => Some(self.lower_expr(e)),
                         StructRest::Rest(sp) => {
-                            self.tcx.sess.emit_err(BaseExpressionDoubleDot { span: *sp });
-                            Some(&*self.arena.alloc(self.expr_err(*sp)))
+                            let guar =
+                                self.tcx.sess.emit_err(BaseExpressionDoubleDot { span: *sp });
+                            Some(&*self.arena.alloc(self.expr_err(*sp, guar)))
                         }
                         StructRest::None => None,
                     };
@@ -318,7 +319,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     )
                 }
                 ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
-                ExprKind::Err => hir::ExprKind::Err,
+                ExprKind::Err => hir::ExprKind::Err(
+                    self.tcx.sess.delay_span_bug(e.span, "lowered ExprKind::Err"),
+                ),
                 ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr),
 
                 ExprKind::Paren(_) | ExprKind::ForLoop(..) => unreachable!("already handled"),
@@ -367,7 +370,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     fn lower_legacy_const_generics(
         &mut self,
         mut f: Expr,
-        args: Vec<AstP<Expr>>,
+        args: ThinVec<AstP<Expr>>,
         legacy_args_idx: &[usize],
     ) -> hir::ExprKind<'hir> {
         let ExprKind::Path(None, path) = &mut f.kind else {
@@ -376,7 +379,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
         // Split the arguments into const generics and normal arguments
         let mut real_args = vec![];
-        let mut generic_args = vec![];
+        let mut generic_args = ThinVec::new();
         for (idx, arg) in args.into_iter().enumerate() {
             if legacy_args_idx.contains(&idx) {
                 let parent_def_id = self.current_hir_id_owner;
@@ -761,7 +764,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 self.expr_ident_mut(span, task_context_ident, task_context_hid)
             } else {
                 // Use of `await` outside of an async context, we cannot use `task_context` here.
-                self.expr_err(span)
+                self.expr_err(span, self.tcx.sess.delay_span_bug(span, "no task_context hir id"))
             };
             let new_unchecked = self.expr_call_lang_item_fn_mut(
                 span,
diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs
index e7dd0b18a03..4095e225a80 100644
--- a/compiler/rustc_ast_lowering/src/format.rs
+++ b/compiler/rustc_ast_lowering/src/format.rs
@@ -102,7 +102,12 @@ fn make_count<'hir>(
                 let value = ctx.arena.alloc_from_iter([ctx.expr_usize(sp, i)]);
                 ctx.expr_call_mut(sp, count_param, value)
             } else {
-                ctx.expr(sp, hir::ExprKind::Err)
+                ctx.expr(
+                    sp,
+                    hir::ExprKind::Err(
+                        ctx.tcx.sess.delay_span_bug(sp, "lowered bad format_args count"),
+                    ),
+                )
             }
         }
         None => ctx.expr_lang_item_type_relative(sp, hir::LangItem::FormatCount, sym::Implied),
@@ -135,7 +140,10 @@ fn make_format_spec<'hir>(
                 argmap.insert_full((arg_index, ArgumentType::Format(placeholder.format_trait)));
             ctx.expr_usize(sp, i)
         }
-        Err(_) => ctx.expr(sp, hir::ExprKind::Err),
+        Err(_) => ctx.expr(
+            sp,
+            hir::ExprKind::Err(ctx.tcx.sess.delay_span_bug(sp, "lowered bad format_args count")),
+        ),
     };
     let &FormatOptions {
         ref width,
@@ -294,7 +302,12 @@ fn expand_format_args<'hir>(
                 ));
                 make_argument(ctx, sp, arg, ty)
             } else {
-                ctx.expr(macsp, hir::ExprKind::Err)
+                ctx.expr(
+                    macsp,
+                    hir::ExprKind::Err(
+                        ctx.tcx.sess.delay_span_bug(macsp, format!("no arg at {arg_index}")),
+                    ),
+                )
             }
         }));
         let elements: Vec<_> = arguments
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 4a0e005b8b9..7325bce6055 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -7,6 +7,7 @@ use rustc_ast::ptr::P;
 use rustc_ast::visit::AssocCtxt;
 use rustc_ast::*;
 use rustc_data_structures::sorted_map::SortedMap;
+use rustc_errors::ErrorGuaranteed;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
@@ -284,7 +285,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
             },
             ItemKind::GlobalAsm(asm) => hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm)),
-            ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty: Some(ty), .. }) => {
+            ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => {
                 // We lower
                 //
                 // type Foo = impl Trait
@@ -299,18 +300,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     &generics,
                     id,
                     &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
-                    |this| this.lower_ty(ty, &ImplTraitContext::TypeAliasesOpaqueTy),
-                );
-                hir::ItemKind::TyAlias(ty, generics)
-            }
-            ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty: None, .. }) => {
-                let mut generics = generics.clone();
-                add_ty_alias_where_clause(&mut generics, *where_clauses, true);
-                let (generics, ty) = self.lower_generics(
-                    &generics,
-                    id,
-                    &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
-                    |this| this.arena.alloc(this.ty(span, hir::TyKind::Err)),
+                    |this| match ty {
+                        None => {
+                            let guar = this.tcx.sess.delay_span_bug(
+                                span,
+                                "expected to lower type alias type, but it was missing",
+                            );
+                            this.arena.alloc(this.ty(span, hir::TyKind::Err(guar)))
+                        }
+                        Some(ty) => this.lower_ty(ty, &ImplTraitContext::TypeAliasesOpaqueTy),
+                    },
                 );
                 hir::ItemKind::TyAlias(ty, generics)
             }
@@ -798,8 +797,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
     }
 
     /// Construct `ExprKind::Err` for the given `span`.
-    pub(crate) fn expr_err(&mut self, span: Span) -> hir::Expr<'hir> {
-        self.expr(span, hir::ExprKind::Err)
+    pub(crate) fn expr_err(&mut self, span: Span, guar: ErrorGuaranteed) -> hir::Expr<'hir> {
+        self.expr(span, hir::ExprKind::Err(guar))
     }
 
     fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
@@ -847,7 +846,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| match ty {
                         None => {
-                            let ty = this.arena.alloc(this.ty(i.span, hir::TyKind::Err));
+                            let guar = this.tcx.sess.delay_span_bug(
+                                i.span,
+                                "expected to lower associated type, but it was missing",
+                            );
+                            let ty = this.arena.alloc(this.ty(i.span, hir::TyKind::Err(guar)));
                             hir::ImplItemKind::Type(ty)
                         }
                         Some(ty) => {
@@ -973,7 +976,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr<'hir> {
         match block {
             Some(block) => self.lower_block_expr(block),
-            None => self.expr_err(span),
+            None => self.expr_err(span, self.tcx.sess.delay_span_bug(span, "no block")),
         }
     }
 
@@ -983,7 +986,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 &[],
                 match expr {
                     Some(expr) => this.lower_expr_mut(expr),
-                    None => this.expr_err(span),
+                    None => this.expr_err(span, this.tcx.sess.delay_span_bug(span, "no block")),
                 },
             )
         })
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index b543be3be50..5d78d914b6d 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -52,23 +52,28 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sorted_map::SortedMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::{DiagnosticArgFromDisplay, Handler, StashKey};
+use rustc_errors::{
+    DiagnosticArgFromDisplay, DiagnosticMessage, Handler, StashKey, SubdiagnosticMessage,
+};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
 use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
 use rustc_hir::definitions::DefPathData;
 use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate};
 use rustc_index::vec::{Idx, IndexVec};
-use rustc_middle::span_bug;
-use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
+use rustc_macros::fluent_messages;
+use rustc_middle::{
+    span_bug,
+    ty::{ResolverAstLowering, TyCtxt},
+};
 use rustc_session::parse::feature_err;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::source_map::DesugaringKind;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
-
 use smallvec::SmallVec;
 use std::collections::hash_map::Entry;
+use thin_vec::ThinVec;
 
 macro_rules! arena_vec {
     ($this:expr; $($x:expr),*) => (
@@ -87,6 +92,8 @@ mod lifetime_collector;
 mod pat;
 mod path;
 
+fluent_messages! { "../locales/en-US.ftl" }
+
 struct LoweringContext<'a, 'hir> {
     tcx: TyCtxt<'hir>,
     resolver: &'a mut ResolverAstLowering,
@@ -281,31 +288,31 @@ enum ImplTraitPosition {
 impl std::fmt::Display for ImplTraitPosition {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         let name = match self {
-            ImplTraitPosition::Path => "path",
-            ImplTraitPosition::Variable => "variable binding",
-            ImplTraitPosition::Trait => "trait",
-            ImplTraitPosition::AsyncBlock => "async block",
-            ImplTraitPosition::Bound => "bound",
-            ImplTraitPosition::Generic => "generic",
-            ImplTraitPosition::ExternFnParam => "`extern fn` param",
-            ImplTraitPosition::ClosureParam => "closure param",
-            ImplTraitPosition::PointerParam => "`fn` pointer param",
-            ImplTraitPosition::FnTraitParam => "`Fn` trait param",
-            ImplTraitPosition::TraitParam => "trait method param",
-            ImplTraitPosition::ImplParam => "`impl` method param",
-            ImplTraitPosition::ExternFnReturn => "`extern fn` return",
-            ImplTraitPosition::ClosureReturn => "closure return",
-            ImplTraitPosition::PointerReturn => "`fn` pointer return",
-            ImplTraitPosition::FnTraitReturn => "`Fn` trait return",
-            ImplTraitPosition::TraitReturn => "trait method return",
-            ImplTraitPosition::ImplReturn => "`impl` method return",
-            ImplTraitPosition::GenericDefault => "generic parameter default",
-            ImplTraitPosition::ConstTy => "const type",
-            ImplTraitPosition::StaticTy => "static type",
-            ImplTraitPosition::AssocTy => "associated type",
-            ImplTraitPosition::FieldTy => "field type",
-            ImplTraitPosition::Cast => "cast type",
-            ImplTraitPosition::ImplSelf => "impl header",
+            ImplTraitPosition::Path => "paths",
+            ImplTraitPosition::Variable => "variable bindings",
+            ImplTraitPosition::Trait => "traits",
+            ImplTraitPosition::AsyncBlock => "async blocks",
+            ImplTraitPosition::Bound => "bounds",
+            ImplTraitPosition::Generic => "generics",
+            ImplTraitPosition::ExternFnParam => "`extern fn` params",
+            ImplTraitPosition::ClosureParam => "closure params",
+            ImplTraitPosition::PointerParam => "`fn` pointer params",
+            ImplTraitPosition::FnTraitParam => "`Fn` trait params",
+            ImplTraitPosition::TraitParam => "trait method params",
+            ImplTraitPosition::ImplParam => "`impl` method params",
+            ImplTraitPosition::ExternFnReturn => "`extern fn` return types",
+            ImplTraitPosition::ClosureReturn => "closure return types",
+            ImplTraitPosition::PointerReturn => "`fn` pointer return types",
+            ImplTraitPosition::FnTraitReturn => "`Fn` trait return types",
+            ImplTraitPosition::TraitReturn => "trait method return types",
+            ImplTraitPosition::ImplReturn => "`impl` method return types",
+            ImplTraitPosition::GenericDefault => "generic parameter defaults",
+            ImplTraitPosition::ConstTy => "const types",
+            ImplTraitPosition::StaticTy => "static types",
+            ImplTraitPosition::AssocTy => "associated types",
+            ImplTraitPosition::FieldTy => "field types",
+            ImplTraitPosition::Cast => "cast types",
+            ImplTraitPosition::ImplSelf => "impl headers",
         };
 
         write!(f, "{name}")
@@ -995,8 +1002,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         } else {
             self.arena.alloc(hir::GenericArgs::none())
         };
-        let itctx_tait = &ImplTraitContext::TypeAliasesOpaqueTy;
-
         let kind = match &constraint.kind {
             AssocConstraintKind::Equality { term } => {
                 let term = match term {
@@ -1006,8 +1011,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 hir::TypeBindingKind::Equality { term }
             }
             AssocConstraintKind::Bound { bounds } => {
+                enum DesugarKind<'a> {
+                    ImplTrait,
+                    Error(&'a ImplTraitPosition),
+                    Bound,
+                }
+
                 // Piggy-back on the `impl Trait` context to figure out the correct behavior.
-                let (desugar_to_impl_trait, itctx) = match itctx {
+                let desugar_kind = match itctx {
                     // We are in the return position:
                     //
                     //     fn foo() -> impl Iterator<Item: Debug>
@@ -1016,7 +1027,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     //
                     //     fn foo() -> impl Iterator<Item = impl Debug>
                     ImplTraitContext::ReturnPositionOpaqueTy { .. }
-                    | ImplTraitContext::TypeAliasesOpaqueTy { .. } => (true, itctx),
+                    | ImplTraitContext::TypeAliasesOpaqueTy { .. } => DesugarKind::ImplTrait,
 
                     // We are in the argument position, but within a dyn type:
                     //
@@ -1025,15 +1036,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     // so desugar to
                     //
                     //     fn foo(x: dyn Iterator<Item = impl Debug>)
-                    ImplTraitContext::Universal if self.is_in_dyn_type => (true, itctx),
+                    ImplTraitContext::Universal if self.is_in_dyn_type => DesugarKind::ImplTrait,
 
-                    // In `type Foo = dyn Iterator<Item: Debug>` we desugar to
-                    // `type Foo = dyn Iterator<Item = impl Debug>` but we have to override the
-                    // "impl trait context" to permit `impl Debug` in this position (it desugars
-                    // then to an opaque type).
-                    //
-                    // FIXME: this is only needed until `impl Trait` is allowed in type aliases.
-                    ImplTraitContext::Disallowed(_) if self.is_in_dyn_type => (true, itctx_tait),
+                    ImplTraitContext::Disallowed(position) if self.is_in_dyn_type => {
+                        DesugarKind::Error(position)
+                    }
 
                     // We are in the parameter position, but not within a dyn type:
                     //
@@ -1042,35 +1049,47 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     // so we leave it as is and this gets expanded in astconv to a bound like
                     // `<T as Iterator>::Item: Debug` where `T` is the type parameter for the
                     // `impl Iterator`.
-                    _ => (false, itctx),
+                    _ => DesugarKind::Bound,
                 };
 
-                if desugar_to_impl_trait {
-                    // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
-                    // constructing the HIR for `impl bounds...` and then lowering that.
-
-                    let impl_trait_node_id = self.next_node_id();
-
-                    self.with_dyn_type_scope(false, |this| {
-                        let node_id = this.next_node_id();
-                        let ty = this.lower_ty(
-                            &Ty {
-                                id: node_id,
-                                kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()),
-                                span: this.lower_span(constraint.span),
-                                tokens: None,
-                            },
-                            itctx,
-                        );
+                match desugar_kind {
+                    DesugarKind::ImplTrait => {
+                        // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
+                        // constructing the HIR for `impl bounds...` and then lowering that.
 
-                        hir::TypeBindingKind::Equality { term: ty.into() }
-                    })
-                } else {
-                    // Desugar `AssocTy: Bounds` into a type binding where the
-                    // later desugars into a trait predicate.
-                    let bounds = self.lower_param_bounds(bounds, itctx);
+                        let impl_trait_node_id = self.next_node_id();
 
-                    hir::TypeBindingKind::Constraint { bounds }
+                        self.with_dyn_type_scope(false, |this| {
+                            let node_id = this.next_node_id();
+                            let ty = this.lower_ty(
+                                &Ty {
+                                    id: node_id,
+                                    kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()),
+                                    span: this.lower_span(constraint.span),
+                                    tokens: None,
+                                },
+                                itctx,
+                            );
+
+                            hir::TypeBindingKind::Equality { term: ty.into() }
+                        })
+                    }
+                    DesugarKind::Bound => {
+                        // Desugar `AssocTy: Bounds` into a type binding where the
+                        // later desugars into a trait predicate.
+                        let bounds = self.lower_param_bounds(bounds, itctx);
+
+                        hir::TypeBindingKind::Constraint { bounds }
+                    }
+                    DesugarKind::Error(position) => {
+                        let guar = self.tcx.sess.emit_err(errors::MisplacedAssocTyBinding {
+                            span: constraint.span,
+                            position: DiagnosticArgFromDisplay(position),
+                        });
+                        let err_ty =
+                            &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
+                        hir::TypeBindingKind::Equality { term: err_ty.into() }
+                    }
                 }
             }
         };
@@ -1207,7 +1226,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
                 let bound = this.lower_poly_trait_ref(
                     &PolyTraitRef {
-                        bound_generic_params: vec![],
+                        bound_generic_params: ThinVec::new(),
                         trait_ref: TraitRef { path: path.clone(), ref_id: t.id },
                         span: t.span
                     },
@@ -1237,7 +1256,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn lower_ty_direct(&mut self, t: &Ty, itctx: &ImplTraitContext) -> hir::Ty<'hir> {
         let kind = match &t.kind {
             TyKind::Infer => hir::TyKind::Infer,
-            TyKind::Err => hir::TyKind::Err,
+            TyKind::Err => {
+                hir::TyKind::Err(self.tcx.sess.delay_span_bug(t.span, "TyKind::Err lowered"))
+            }
             TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
             TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
             TyKind::Ref(region, mt) => {
@@ -1363,7 +1384,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         path
                     }
                     ImplTraitContext::FeatureGated(position, feature) => {
-                        self.tcx
+                        let guar = self
+                            .tcx
                             .sess
                             .create_feature_err(
                                 MisplacedImplTrait {
@@ -1373,24 +1395,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                                 *feature,
                             )
                             .emit();
-                        hir::TyKind::Err
+                        hir::TyKind::Err(guar)
                     }
                     ImplTraitContext::Disallowed(position) => {
-                        self.tcx.sess.emit_err(MisplacedImplTrait {
+                        let guar = self.tcx.sess.emit_err(MisplacedImplTrait {
                             span: t.span,
                             position: DiagnosticArgFromDisplay(position),
                         });
-                        hir::TyKind::Err
+                        hir::TyKind::Err(guar)
                     }
                 }
             }
             TyKind::MacCall(_) => panic!("`TyKind::MacCall` should have been expanded by now"),
             TyKind::CVarArgs => {
-                self.tcx.sess.delay_span_bug(
+                let guar = self.tcx.sess.delay_span_bug(
                     t.span,
                     "`TyKind::CVarArgs` should have been handled elsewhere",
                 );
-                hir::TyKind::Err
+                hir::TyKind::Err(guar)
             }
         };
 
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index 06d885a45fb..2509b705639 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -330,8 +330,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             ExprKind::Path(..) if allow_paths => {}
             ExprKind::Unary(UnOp::Neg, inner) if matches!(inner.kind, ExprKind::Lit(_)) => {}
             _ => {
-                self.tcx.sess.emit_err(ArbitraryExpressionInPattern { span: expr.span });
-                return self.arena.alloc(self.expr_err(expr.span));
+                let guar = self.tcx.sess.emit_err(ArbitraryExpressionInPattern { span: expr.span });
+                return self.arena.alloc(self.expr_err(expr.span, guar));
             }
         }
         self.lower_expr(expr)
diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml
index 37eff9207c1..8bd212073a6 100644
--- a/compiler/rustc_ast_passes/Cargo.toml
+++ b/compiler/rustc_ast_passes/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
 
 [dependencies]
 itertools = "0.10.1"
-tracing = "0.1"
+rustc_ast = { path = "../rustc_ast" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_attr = { path = "../rustc_attr" }
 rustc_data_structures = { path = "../rustc_data_structures" }
@@ -16,4 +16,5 @@ rustc_parse = { path = "../rustc_parse" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
-rustc_ast = { path = "../rustc_ast" }
+thin-vec = "0.2.12"
+tracing = "0.1"
diff --git a/compiler/rustc_ast_passes/locales/en-US.ftl b/compiler/rustc_ast_passes/locales/en-US.ftl
new file mode 100644
index 00000000000..747bd52b22c
--- /dev/null
+++ b/compiler/rustc_ast_passes/locales/en-US.ftl
@@ -0,0 +1,236 @@
+ast_passes_forbidden_let =
+    `let` expressions are not supported here
+    .note = only supported directly in conditions of `if` and `while` expressions
+    .not_supported_or = `||` operators are not supported in let chain expressions
+    .not_supported_parentheses = `let`s wrapped in parentheses are not supported in a context with let chains
+
+ast_passes_forbidden_let_stable =
+    expected expression, found statement (`let`)
+    .note = variable declaration using `let` is a statement
+
+ast_passes_deprecated_where_clause_location =
+    where clause not allowed here
+
+ast_passes_keyword_lifetime =
+    lifetimes cannot use keyword names
+
+ast_passes_invalid_label =
+    invalid label name `{$name}`
+
+ast_passes_invalid_visibility =
+    unnecessary visibility qualifier
+    .implied = `pub` not permitted here because it's implied
+    .individual_impl_items = place qualifiers on individual impl items instead
+    .individual_foreign_items = place qualifiers on individual foreign items instead
+
+ast_passes_trait_fn_const =
+    functions in traits cannot be declared const
+    .label = functions in traits cannot be const
+
+ast_passes_forbidden_lifetime_bound =
+    lifetime bounds cannot be used in this context
+
+ast_passes_forbidden_non_lifetime_param =
+    only lifetime parameters can be used in this context
+
+ast_passes_fn_param_too_many =
+    function can not have more than {$max_num_args} arguments
+
+ast_passes_fn_param_c_var_args_only =
+    C-variadic function must be declared with at least one named argument
+
+ast_passes_fn_param_c_var_args_not_last =
+    `...` must be the last argument of a C-variadic function
+
+ast_passes_fn_param_doc_comment =
+    documentation comments cannot be applied to function parameters
+    .label = doc comments are not allowed here
+
+ast_passes_fn_param_forbidden_attr =
+    allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters
+
+ast_passes_fn_param_forbidden_self =
+    `self` parameter is only allowed in associated functions
+    .label = not semantically valid as function parameter
+    .note = associated functions are those in `impl` or `trait` definitions
+
+ast_passes_forbidden_default =
+    `default` is only allowed on items in trait impls
+    .label = `default` because of this
+
+ast_passes_assoc_const_without_body =
+    associated constant in `impl` without body
+    .suggestion = provide a definition for the constant
+
+ast_passes_assoc_fn_without_body =
+    associated function in `impl` without body
+    .suggestion = provide a definition for the function
+
+ast_passes_assoc_type_without_body =
+    associated type in `impl` without body
+    .suggestion = provide a definition for the type
+
+ast_passes_const_without_body =
+    free constant item without body
+    .suggestion = provide a definition for the constant
+
+ast_passes_static_without_body =
+    free static item without body
+    .suggestion = provide a definition for the static
+
+ast_passes_ty_alias_without_body =
+    free type alias without body
+    .suggestion = provide a definition for the type
+
+ast_passes_fn_without_body =
+    free function without a body
+    .suggestion = provide a definition for the function
+
+ast_passes_extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block
+
+ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect
+
+ast_passes_extern_types_cannot = `type`s inside `extern` blocks cannot have {$descr}
+    .suggestion = remove the {$remove_descr}
+    .label = `extern` block begins here
+
+ast_passes_extern_keyword_link = for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block
+    .cannot_have = cannot have a body
+    .invalid = the invalid body
+    .existing = `extern` blocks define existing foreign {$kind}s and {$kind}s inside of them cannot have a body
+
+ast_passes_fn_body_extern = incorrect function inside `extern` block
+    .cannot_have = cannot have a body
+    .suggestion = remove the invalid body
+    .help = you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block
+    .label = `extern` blocks define existing foreign functions and functions inside of them cannot have a body
+
+ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have qualifiers
+    .label = in this `extern` block
+    .suggestion = remove the qualifiers
+
+ast_passes_extern_item_ascii = items in `extern` blocks cannot use non-ascii identifiers
+    .label = in this `extern` block
+    .note = this limitation may be lifted in the future; see issue #83942 <https://github.com/rust-lang/rust/issues/83942> for more information
+
+ast_passes_bad_c_variadic = only foreign or `unsafe extern "C"` functions may be C-variadic
+
+ast_passes_item_underscore = `{$kind}` items in this context need a name
+    .label = `_` is not a valid name for this `{$kind}` item
+
+ast_passes_nomangle_ascii = `#[no_mangle]` requires ASCII identifier
+
+ast_passes_module_nonascii = trying to load file for module `{$name}` with non-ascii identifier name
+    .help = consider using the `#[path]` attribute to specify filesystem path
+
+ast_passes_auto_generic = auto traits cannot have generic parameters
+    .label = auto trait cannot have generic parameters
+    .suggestion = remove the parameters
+
+ast_passes_auto_super_lifetime = auto traits cannot have super traits or lifetime bounds
+    .label = {ast_passes_auto_super_lifetime}
+    .suggestion = remove the super traits or lifetime bounds
+
+ast_passes_auto_items = auto traits cannot have associated items
+    .label = {ast_passes_auto_items}
+    .suggestion = remove these associated items
+
+ast_passes_generic_before_constraints = generic arguments must come before the first constraint
+    .constraints = {$constraint_len ->
+    [one] constraint
+    *[other] constraints
+    }
+    .args = generic {$args_len ->
+    [one] argument
+    *[other] arguments
+    }
+    .empty_string = {""},
+    .suggestion = move the {$constraint_len ->
+    [one] constraint
+    *[other] constraints
+    } after the generic {$args_len ->
+    [one] argument
+    *[other] arguments
+    }
+
+ast_passes_pattern_in_fn_pointer = patterns aren't allowed in function pointer types
+
+ast_passes_trait_object_single_bound = only a single explicit lifetime bound is permitted
+
+ast_passes_impl_trait_path = `impl Trait` is not allowed in path parameters
+
+ast_passes_nested_impl_trait = nested `impl Trait` is not allowed
+    .outer = outer `impl Trait`
+    .inner = nested `impl Trait` here
+
+ast_passes_at_least_one_trait = at least one trait must be specified
+
+ast_passes_extern_without_abi = extern declarations without an explicit ABI are deprecated
+
+ast_passes_out_of_order_params = {$param_ord} parameters must be declared prior to {$max_param} parameters
+    .suggestion = reorder the parameters: lifetimes, then consts and types
+
+ast_passes_obsolete_auto = `impl Trait for .. {"{}"}` is an obsolete syntax
+    .help = use `auto trait Trait {"{}"}` instead
+
+ast_passes_unsafe_negative_impl = negative impls cannot be unsafe
+    .negative = negative because of this
+    .unsafe = unsafe because of this
+
+ast_passes_inherent_cannot_be = inherent impls cannot be {$annotation}
+    .because = {$annotation} because of this
+    .type = inherent impl for this type
+    .only_trait = only trait implementations may be annotated with {$annotation}
+
+ast_passes_unsafe_item = {$kind} cannot be declared unsafe
+
+ast_passes_fieldless_union = unions cannot have zero fields
+
+ast_passes_where_after_type_alias = where clauses are not allowed after the type for type aliases
+    .note = see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
+
+ast_passes_generic_default_trailing = generic parameters with a default must be trailing
+
+ast_passes_nested_lifetimes = nested quantification of lifetimes
+
+ast_passes_optional_trait_supertrait = `?Trait` is not permitted in supertraits
+    .note = traits are `?{$path_str}` by default
+
+ast_passes_optional_trait_object = `?Trait` is not permitted in trait object types
+
+ast_passes_tilde_const_disallowed = `~const` is not allowed here
+    .trait = trait objects cannot have `~const` trait bounds
+    .closure = closures cannot have `~const` trait bounds
+    .function = this function is not `const`, so it cannot have `~const` trait bounds
+
+ast_passes_optional_const_exclusive = `~const` and `?` are mutually exclusive
+
+ast_passes_const_and_async = functions cannot be both `const` and `async`
+    .const = `const` because of this
+    .async = `async` because of this
+    .label = {""}
+
+ast_passes_pattern_in_foreign = patterns aren't allowed in foreign function declarations
+    .label = pattern not allowed in foreign function
+
+ast_passes_pattern_in_bodiless = patterns aren't allowed in functions without bodies
+    .label = pattern not allowed in function without body
+
+ast_passes_equality_in_where = equality constraints are not yet supported in `where` clauses
+    .label = not supported
+    .suggestion = if `{$ident}` is an associated type you're trying to set, use the associated type binding syntax
+    .suggestion_path = if `{$trait_segment}::{$potential_assoc}` is an associated type you're trying to set, use the associated type binding syntax
+    .note = see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
+
+ast_passes_stability_outside_std = stability attributes may not be used outside of the standard library
+
+ast_passes_feature_on_non_nightly = `#![feature]` may not be used on the {$channel} release channel
+    .suggestion = remove the attribute
+    .stable_since = the feature `{$name}` has been stable since `{$since}` and no longer requires an attribute to enable
+
+ast_passes_incompatbile_features = `{$f1}` and `{$f2}` are incompatible, using them at the same time is not allowed
+    .help = remove one of these features
+
+ast_passes_show_span = {$msg}
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index d1ae8c1fdbd..1c561375626 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -13,7 +13,6 @@ use rustc_ast::walk_list;
 use rustc_ast::*;
 use rustc_ast_pretty::pprust::{self, State};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{error_code, fluent, pluralize, struct_span_err, Applicability};
 use rustc_macros::Subdiagnostic;
 use rustc_parse::validate_attr;
 use rustc_session::lint::builtin::{
@@ -27,11 +26,10 @@ use rustc_span::Span;
 use rustc_target::spec::abi;
 use std::mem;
 use std::ops::{Deref, DerefMut};
+use thin_vec::thin_vec;
 
-use crate::errors::*;
-
-const MORE_EXTERN: &str =
-    "for more information, visit https://doc.rust-lang.org/std/keyword.extern.html";
+use crate::errors;
+use crate::fluent_generated as fluent;
 
 /// Is `self` allowed semantically as the first parameter in an `FnDecl`?
 enum SelfSemantic {
@@ -69,10 +67,6 @@ struct AstValidator<'a> {
     /// or `Foo::Bar<impl Trait>`
     is_impl_trait_banned: bool,
 
-    /// Used to ban associated type bounds (i.e., `Type<AssocType: Bounds>`) in
-    /// certain positions.
-    is_assoc_ty_bound_banned: bool,
-
     /// See [ForbiddenLetReason]
     forbidden_let_reason: Option<ForbiddenLetReason>,
 
@@ -136,9 +130,9 @@ impl<'a> AstValidator<'a> {
     fn ban_let_expr(&self, expr: &'a Expr, forbidden_let_reason: ForbiddenLetReason) {
         let sess = &self.session;
         if sess.opts.unstable_features.is_nightly_build() {
-            sess.emit_err(ForbiddenLet { span: expr.span, reason: forbidden_let_reason });
+            sess.emit_err(errors::ForbiddenLet { span: expr.span, reason: forbidden_let_reason });
         } else {
-            sess.emit_err(ForbiddenLetStable { span: expr.span });
+            sess.emit_err(errors::ForbiddenLetStable { span: expr.span });
         }
     }
 
@@ -178,30 +172,12 @@ impl<'a> AstValidator<'a> {
         }
     }
 
-    fn with_banned_assoc_ty_bound(&mut self, f: impl FnOnce(&mut Self)) {
-        let old = mem::replace(&mut self.is_assoc_ty_bound_banned, true);
-        f(self);
-        self.is_assoc_ty_bound_banned = old;
-    }
-
     fn with_impl_trait(&mut self, outer: Option<Span>, f: impl FnOnce(&mut Self)) {
         let old = mem::replace(&mut self.outer_impl_trait, outer);
         f(self);
         self.outer_impl_trait = old;
     }
 
-    fn visit_assoc_constraint_from_generic_args(&mut self, constraint: &'a AssocConstraint) {
-        match constraint.kind {
-            AssocConstraintKind::Equality { .. } => {}
-            AssocConstraintKind::Bound { .. } => {
-                if self.is_assoc_ty_bound_banned {
-                    self.session.emit_err(ForbiddenAssocConstraint { span: constraint.span });
-                }
-            }
-        }
-        self.visit_assoc_constraint(constraint);
-    }
-
     // Mirrors `visit::walk_ty`, but tracks relevant state.
     fn walk_ty(&mut self, t: &'a Ty) {
         match &t.kind {
@@ -254,22 +230,22 @@ impl<'a> AstValidator<'a> {
     fn check_lifetime(&self, ident: Ident) {
         let valid_names = [kw::UnderscoreLifetime, kw::StaticLifetime, kw::Empty];
         if !valid_names.contains(&ident.name) && ident.without_first_quote().is_reserved() {
-            self.session.emit_err(KeywordLifetime { span: ident.span });
+            self.session.emit_err(errors::KeywordLifetime { span: ident.span });
         }
     }
 
     fn check_label(&self, ident: Ident) {
         if ident.without_first_quote().is_reserved() {
-            self.session.emit_err(InvalidLabel { span: ident.span, name: ident.name });
+            self.session.emit_err(errors::InvalidLabel { span: ident.span, name: ident.name });
         }
     }
 
-    fn invalid_visibility(&self, vis: &Visibility, note: Option<InvalidVisibilityNote>) {
+    fn invalid_visibility(&self, vis: &Visibility, note: Option<errors::InvalidVisibilityNote>) {
         if let VisibilityKind::Inherited = vis.kind {
             return;
         }
 
-        self.session.emit_err(InvalidVisibility {
+        self.session.emit_err(errors::InvalidVisibility {
             span: vis.span,
             implied: vis.kind.is_pub().then_some(vis.span),
             note,
@@ -290,7 +266,7 @@ impl<'a> AstValidator<'a> {
 
     fn check_trait_fn_not_const(&self, constness: Const) {
         if let Const::Yes(span) = constness {
-            self.session.emit_err(TraitFnConst { span });
+            self.session.emit_err(errors::TraitFnConst { span });
         }
     }
 
@@ -307,7 +283,7 @@ impl<'a> AstValidator<'a> {
         let max_num_args: usize = u16::MAX.into();
         if fn_decl.inputs.len() > max_num_args {
             let Param { span, .. } = fn_decl.inputs[0];
-            self.session.emit_fatal(FnParamTooMany { span, max_num_args });
+            self.session.emit_fatal(errors::FnParamTooMany { span, max_num_args });
         }
     }
 
@@ -315,13 +291,13 @@ impl<'a> AstValidator<'a> {
         match &*fn_decl.inputs {
             [Param { ty, span, .. }] => {
                 if let TyKind::CVarArgs = ty.kind {
-                    self.session.emit_err(FnParamCVarArgsOnly { span: *span });
+                    self.session.emit_err(errors::FnParamCVarArgsOnly { span: *span });
                 }
             }
             [ps @ .., _] => {
                 for Param { ty, span, .. } in ps {
                     if let TyKind::CVarArgs = ty.kind {
-                        self.session.emit_err(FnParamCVarArgsNotLast { span: *span });
+                        self.session.emit_err(errors::FnParamCVarArgsNotLast { span: *span });
                     }
                 }
             }
@@ -348,9 +324,9 @@ impl<'a> AstValidator<'a> {
             })
             .for_each(|attr| {
                 if attr.is_doc_comment() {
-                    self.session.emit_err(FnParamDocComment { span: attr.span });
+                    self.session.emit_err(errors::FnParamDocComment { span: attr.span });
                 } else {
-                    self.session.emit_err(FnParamForbiddenAttr { span: attr.span });
+                    self.session.emit_err(errors::FnParamForbiddenAttr { span: attr.span });
                 }
             });
     }
@@ -358,7 +334,7 @@ impl<'a> AstValidator<'a> {
     fn check_decl_self_param(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
         if let (SelfSemantic::No, [param, ..]) = (self_semantic, &*fn_decl.inputs) {
             if param.is_self() {
-                self.session.emit_err(FnParamForbiddenSelf { span: param.span });
+                self.session.emit_err(errors::FnParamForbiddenSelf { span: param.span });
             }
         }
     }
@@ -366,7 +342,7 @@ impl<'a> AstValidator<'a> {
     fn check_defaultness(&self, span: Span, defaultness: Defaultness) {
         if let Defaultness::Default(def_span) = defaultness {
             let span = self.session.source_map().guess_head_span(span);
-            self.session.emit_err(ForbiddenDefault { span, def_span });
+            self.session.emit_err(errors::ForbiddenDefault { span, def_span });
         }
     }
 
@@ -389,27 +365,17 @@ impl<'a> AstValidator<'a> {
             [b0] => b0.span(),
             [b0, .., bl] => b0.span().to(bl.span()),
         };
-        self.err_handler()
-            .struct_span_err(span, &format!("bounds on `type`s in {} have no effect", ctx))
-            .emit();
+        self.err_handler().emit_err(errors::BoundInContext { span, ctx });
     }
 
     fn check_foreign_ty_genericless(&self, generics: &Generics, where_span: Span) {
         let cannot_have = |span, descr, remove_descr| {
-            self.err_handler()
-                .struct_span_err(
-                    span,
-                    &format!("`type`s inside `extern` blocks cannot have {}", descr),
-                )
-                .span_suggestion(
-                    span,
-                    &format!("remove the {}", remove_descr),
-                    "",
-                    Applicability::MaybeIncorrect,
-                )
-                .span_label(self.current_extern_span(), "`extern` block begins here")
-                .note(MORE_EXTERN)
-                .emit();
+            self.err_handler().emit_err(errors::ExternTypesCannotHave {
+                span,
+                descr,
+                remove_descr,
+                block_span: self.current_extern_span(),
+            });
         };
 
         if !generics.params.is_empty() {
@@ -425,20 +391,12 @@ impl<'a> AstValidator<'a> {
         let Some(body) = body else {
             return;
         };
-        self.err_handler()
-            .struct_span_err(ident.span, &format!("incorrect `{}` inside `extern` block", kind))
-            .span_label(ident.span, "cannot have a body")
-            .span_label(body, "the invalid body")
-            .span_label(
-                self.current_extern_span(),
-                format!(
-                    "`extern` blocks define existing foreign {0}s and {0}s \
-                    inside of them cannot have a body",
-                    kind
-                ),
-            )
-            .note(MORE_EXTERN)
-            .emit();
+        self.err_handler().emit_err(errors::BodyInExtern {
+            span: ident.span,
+            body,
+            block: self.current_extern_span(),
+            kind,
+        });
     }
 
     /// An `fn` in `extern { ... }` cannot have a body `{ ... }`.
@@ -446,26 +404,11 @@ impl<'a> AstValidator<'a> {
         let Some(body) = body else {
             return;
         };
-        self.err_handler()
-            .struct_span_err(ident.span, "incorrect function inside `extern` block")
-            .span_label(ident.span, "cannot have a body")
-            .span_suggestion(
-                body.span,
-                "remove the invalid body",
-                ";",
-                Applicability::MaybeIncorrect,
-            )
-            .help(
-                "you might have meant to write a function accessible through FFI, \
-                which can be done by writing `extern fn` outside of the `extern` block",
-            )
-            .span_label(
-                self.current_extern_span(),
-                "`extern` blocks define existing foreign functions and functions \
-                inside of them cannot have a body",
-            )
-            .note(MORE_EXTERN)
-            .emit();
+        self.err_handler().emit_err(errors::FnBodyInExtern {
+            span: ident.span,
+            body: body.span,
+            block: self.current_extern_span(),
+        });
     }
 
     fn current_extern_span(&self) -> Span {
@@ -475,34 +418,21 @@ impl<'a> AstValidator<'a> {
     /// An `fn` in `extern { ... }` cannot have qualifiers, e.g. `async fn`.
     fn check_foreign_fn_headerless(&self, ident: Ident, span: Span, header: FnHeader) {
         if header.has_qualifiers() {
-            self.err_handler()
-                .struct_span_err(ident.span, "functions in `extern` blocks cannot have qualifiers")
-                .span_label(self.current_extern_span(), "in this `extern` block")
-                .span_suggestion_verbose(
-                    span.until(ident.span.shrink_to_lo()),
-                    "remove the qualifiers",
-                    "fn ",
-                    Applicability::MaybeIncorrect,
-                )
-                .emit();
+            self.err_handler().emit_err(errors::FnQualifierInExtern {
+                span: ident.span,
+                block: self.current_extern_span(),
+                sugg_span: span.until(ident.span.shrink_to_lo()),
+            });
         }
     }
 
     /// An item in `extern { ... }` cannot use non-ascii identifier.
     fn check_foreign_item_ascii_only(&self, ident: Ident) {
         if !ident.as_str().is_ascii() {
-            let n = 83942;
-            self.err_handler()
-                .struct_span_err(
-                    ident.span,
-                    "items in `extern` blocks cannot use non-ascii identifiers",
-                )
-                .span_label(self.current_extern_span(), "in this `extern` block")
-                .note(&format!(
-                    "this limitation may be lifted in the future; see issue #{} <https://github.com/rust-lang/rust/issues/{}> for more information",
-                    n, n,
-                ))
-                .emit();
+            self.err_handler().emit_err(errors::ExternItemAscii {
+                span: ident.span,
+                block: self.current_extern_span(),
+            });
         }
     }
 
@@ -525,12 +455,7 @@ impl<'a> AstValidator<'a> {
 
         for Param { ty, span, .. } in &fk.decl().inputs {
             if let TyKind::CVarArgs = ty.kind {
-                self.err_handler()
-                    .struct_span_err(
-                        *span,
-                        "only foreign or `unsafe extern \"C\"` functions may be C-variadic",
-                    )
-                    .emit();
+                self.err_handler().emit_err(errors::BadCVariadic { span: *span });
             }
         }
     }
@@ -539,75 +464,32 @@ impl<'a> AstValidator<'a> {
         if ident.name != kw::Underscore {
             return;
         }
-        self.err_handler()
-            .struct_span_err(ident.span, &format!("`{}` items in this context need a name", kind))
-            .span_label(ident.span, format!("`_` is not a valid name for this `{}` item", kind))
-            .emit();
+        self.err_handler().emit_err(errors::ItemUnderscore { span: ident.span, kind });
     }
 
     fn check_nomangle_item_asciionly(&self, ident: Ident, item_span: Span) {
         if ident.name.as_str().is_ascii() {
             return;
         }
-        let head_span = self.session.source_map().guess_head_span(item_span);
-        struct_span_err!(
-            self.session,
-            head_span,
-            E0754,
-            "`#[no_mangle]` requires ASCII identifier"
-        )
-        .emit();
+        let span = self.session.source_map().guess_head_span(item_span);
+        self.session.emit_err(errors::NoMangleAscii { span });
     }
 
     fn check_mod_file_item_asciionly(&self, ident: Ident) {
         if ident.name.as_str().is_ascii() {
             return;
         }
-        struct_span_err!(
-            self.session,
-            ident.span,
-            E0754,
-            "trying to load file for module `{}` with non-ascii identifier name",
-            ident.name
-        )
-        .help("consider using `#[path]` attribute to specify filesystem path")
-        .emit();
+        self.session.emit_err(errors::ModuleNonAscii { span: ident.span, name: ident.name });
     }
 
-    fn deny_generic_params(&self, generics: &Generics, ident_span: Span) {
+    fn deny_generic_params(&self, generics: &Generics, ident: Span) {
         if !generics.params.is_empty() {
-            struct_span_err!(
-                self.session,
-                generics.span,
-                E0567,
-                "auto traits cannot have generic parameters"
-            )
-            .span_label(ident_span, "auto trait cannot have generic parameters")
-            .span_suggestion(
-                generics.span,
-                "remove the parameters",
-                "",
-                Applicability::MachineApplicable,
-            )
-            .emit();
+            self.session.emit_err(errors::AutoTraitGeneric { span: generics.span, ident });
         }
     }
 
-    fn emit_e0568(&self, span: Span, ident_span: Span) {
-        struct_span_err!(
-            self.session,
-            span,
-            E0568,
-            "auto traits cannot have super traits or lifetime bounds"
-        )
-        .span_label(ident_span, "auto trait cannot have super traits or lifetime bounds")
-        .span_suggestion(
-            span,
-            "remove the super traits or lifetime bounds",
-            "",
-            Applicability::MachineApplicable,
-        )
-        .emit();
+    fn emit_e0568(&self, span: Span, ident: Span) {
+        self.session.emit_err(errors::AutoTraitBounds { span, ident });
     }
 
     fn deny_super_traits(&self, bounds: &GenericBounds, ident_span: Span) {
@@ -623,24 +505,11 @@ impl<'a> AstValidator<'a> {
         }
     }
 
-    fn deny_items(&self, trait_items: &[P<AssocItem>], ident_span: Span) {
+    fn deny_items(&self, trait_items: &[P<AssocItem>], ident: Span) {
         if !trait_items.is_empty() {
             let spans: Vec<_> = trait_items.iter().map(|i| i.ident.span).collect();
-            let total_span = trait_items.first().unwrap().span.to(trait_items.last().unwrap().span);
-            struct_span_err!(
-                self.session,
-                spans,
-                E0380,
-                "auto traits cannot have associated items"
-            )
-            .span_suggestion(
-                total_span,
-                "remove these associated items",
-                "",
-                Applicability::MachineApplicable,
-            )
-            .span_label(ident_span, "auto trait cannot have associated items")
-            .emit();
+            let total = trait_items.first().unwrap().span.to(trait_items.last().unwrap().span);
+            self.session.emit_err(errors::AutoTraitItems { spans, total, ident });
         }
     }
 
@@ -686,29 +555,17 @@ impl<'a> AstValidator<'a> {
         let args_len = arg_spans.len();
         let constraint_len = constraint_spans.len();
         // ...and then error:
-        self.err_handler()
-            .struct_span_err(
-                arg_spans.clone(),
-                "generic arguments must come before the first constraint",
-            )
-            .span_label(constraint_spans[0], &format!("constraint{}", pluralize!(constraint_len)))
-            .span_label(
-                *arg_spans.iter().last().unwrap(),
-                &format!("generic argument{}", pluralize!(args_len)),
-            )
-            .span_labels(constraint_spans, "")
-            .span_labels(arg_spans, "")
-            .span_suggestion_verbose(
-                data.span,
-                &format!(
-                    "move the constraint{} after the generic argument{}",
-                    pluralize!(constraint_len),
-                    pluralize!(args_len)
-                ),
-                self.correct_generic_order_suggestion(&data),
-                Applicability::MachineApplicable,
-            )
-            .emit();
+        self.err_handler().emit_err(errors::ArgsBeforeConstraint {
+            arg_spans: arg_spans.clone(),
+            constraints: constraint_spans[0],
+            args: *arg_spans.iter().last().unwrap(),
+            data: data.span,
+            constraint_spans: errors::EmptyLabelManySpans(constraint_spans),
+            arg_spans2: errors::EmptyLabelManySpans(arg_spans),
+            suggestion: self.correct_generic_order_suggestion(&data),
+            constraint_len,
+            args_len,
+        });
     }
 
     fn visit_ty_common(&mut self, ty: &'a Ty) {
@@ -716,13 +573,7 @@ impl<'a> AstValidator<'a> {
             TyKind::BareFn(bfty) => {
                 self.check_fn_decl(&bfty.decl, SelfSemantic::No);
                 Self::check_decl_no_pat(&bfty.decl, |span, _, _| {
-                    struct_span_err!(
-                        self.session,
-                        span,
-                        E0561,
-                        "patterns aren't allowed in function pointer types"
-                    )
-                    .emit();
+                    self.session.emit_err(errors::PatternFnPointer { span });
                 });
                 if let Extern::Implicit(_) = bfty.ext {
                     let sig_span = self.session.source_map().next_point(ty.span.shrink_to_lo());
@@ -734,13 +585,8 @@ impl<'a> AstValidator<'a> {
                 for bound in bounds {
                     if let GenericBound::Outlives(lifetime) = bound {
                         if any_lifetime_bounds {
-                            struct_span_err!(
-                                self.session,
-                                lifetime.ident.span,
-                                E0226,
-                                "only a single explicit lifetime bound is permitted"
-                            )
-                            .emit();
+                            self.session
+                                .emit_err(errors::TraitObjectBound { span: lifetime.ident.span });
                             break;
                         }
                         any_lifetime_bounds = true;
@@ -749,29 +595,19 @@ impl<'a> AstValidator<'a> {
             }
             TyKind::ImplTrait(_, bounds) => {
                 if self.is_impl_trait_banned {
-                    struct_span_err!(
-                        self.session,
-                        ty.span,
-                        E0667,
-                        "`impl Trait` is not allowed in path parameters"
-                    )
-                    .emit();
+                    self.session.emit_err(errors::ImplTraitPath { span: ty.span });
                 }
 
                 if let Some(outer_impl_trait_sp) = self.outer_impl_trait {
-                    struct_span_err!(
-                        self.session,
-                        ty.span,
-                        E0666,
-                        "nested `impl Trait` is not allowed"
-                    )
-                    .span_label(outer_impl_trait_sp, "outer `impl Trait`")
-                    .span_label(ty.span, "nested `impl Trait` here")
-                    .emit();
+                    self.session.emit_err(errors::NestedImplTrait {
+                        span: ty.span,
+                        outer: outer_impl_trait_sp,
+                        inner: ty.span,
+                    });
                 }
 
                 if !bounds.iter().any(|b| matches!(b, GenericBound::Trait(..))) {
-                    self.err_handler().span_err(ty.span, "at least one trait must be specified");
+                    self.err_handler().emit_err(errors::AtLeastOneTrait { span: ty.span });
                 }
             }
             _ => {}
@@ -792,7 +628,7 @@ impl<'a> AstValidator<'a> {
                 MISSING_ABI,
                 id,
                 span,
-                "extern declarations without an explicit ABI are deprecated",
+                fluent::ast_passes_extern_without_abi,
                 BuiltinLintDiagnostics::MissingAbi(span, abi::Abi::FALLBACK),
             )
         }
@@ -865,20 +701,13 @@ fn validate_generic_param_order(
         ordered_params += ">";
 
         for (param_ord, (max_param, spans)) in &out_of_order {
-            let mut err = handler.struct_span_err(
-                spans.clone(),
-                &format!(
-                    "{} parameters must be declared prior to {} parameters",
-                    param_ord, max_param,
-                ),
-            );
-            err.span_suggestion(
-                span,
-                "reorder the parameters: lifetimes, then consts and types",
-                &ordered_params,
-                Applicability::MachineApplicable,
-            );
-            err.emit();
+            handler.emit_err(errors::OutOfOrderParams {
+                spans: spans.clone(),
+                sugg_span: span,
+                param_ord,
+                max_param,
+                ordered_params: &ordered_params,
+            });
         }
     }
 }
@@ -992,25 +821,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 self.with_in_trait_impl(true, Some(*constness), |this| {
                     this.invalid_visibility(&item.vis, None);
                     if let TyKind::Err = self_ty.kind {
-                        this.err_handler()
-                            .struct_span_err(
-                                item.span,
-                                "`impl Trait for .. {}` is an obsolete syntax",
-                            )
-                            .help("use `auto trait Trait {}` instead")
-                            .emit();
+                        this.err_handler().emit_err(errors::ObsoleteAuto { span: item.span });
                     }
                     if let (&Unsafe::Yes(span), &ImplPolarity::Negative(sp)) = (unsafety, polarity)
                     {
-                        struct_span_err!(
-                            this.session,
-                            sp.to(t.path.span),
-                            E0198,
-                            "negative impls cannot be unsafe"
-                        )
-                        .span_label(sp, "negative because of this")
-                        .span_label(span, "unsafe because of this")
-                        .emit();
+                        this.session.emit_err(errors::UnsafeNegativeImpl {
+                            span: sp.to(t.path.span),
+                            negative: sp,
+                            r#unsafe: span,
+                        });
                     }
 
                     this.visit_vis(&item.vis);
@@ -1038,52 +857,54 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 self_ty,
                 items: _,
             }) => {
-                let error = |annotation_span, annotation| {
-                    let mut err = self.err_handler().struct_span_err(
-                        self_ty.span,
-                        &format!("inherent impls cannot be {}", annotation),
-                    );
-                    err.span_label(annotation_span, &format!("{} because of this", annotation));
-                    err.span_label(self_ty.span, "inherent impl for this type");
-                    err
-                };
+                let error =
+                    |annotation_span, annotation, only_trait: bool| errors::InherentImplCannot {
+                        span: self_ty.span,
+                        annotation_span,
+                        annotation,
+                        self_ty: self_ty.span,
+                        only_trait: only_trait.then_some(()),
+                    };
 
                 self.invalid_visibility(
                     &item.vis,
-                    Some(InvalidVisibilityNote::IndividualImplItems),
+                    Some(errors::InvalidVisibilityNote::IndividualImplItems),
                 );
                 if let &Unsafe::Yes(span) = unsafety {
-                    error(span, "unsafe").code(error_code!(E0197)).emit();
+                    self.err_handler().emit_err(errors::InherentImplCannotUnsafe {
+                        span: self_ty.span,
+                        annotation_span: span,
+                        annotation: "unsafe",
+                        self_ty: self_ty.span,
+                    });
                 }
                 if let &ImplPolarity::Negative(span) = polarity {
-                    error(span, "negative").emit();
+                    self.err_handler().emit_err(error(span, "negative", false));
                 }
                 if let &Defaultness::Default(def_span) = defaultness {
-                    error(def_span, "`default`")
-                        .note("only trait implementations may be annotated with `default`")
-                        .emit();
+                    self.err_handler().emit_err(error(def_span, "`default`", true));
                 }
                 if let &Const::Yes(span) = constness {
-                    error(span, "`const`")
-                        .note("only trait implementations may be annotated with `const`")
-                        .emit();
+                    self.err_handler().emit_err(error(span, "`const`", true));
                 }
             }
             ItemKind::Fn(box Fn { defaultness, sig, generics, body }) => {
                 self.check_defaultness(item.span, *defaultness);
 
                 if body.is_none() {
-                    self.session.emit_err(FnWithoutBody {
+                    self.session.emit_err(errors::FnWithoutBody {
                         span: item.span,
                         replace_span: self.ending_semi_or_hi(item.span),
                         extern_block_suggestion: match sig.header.ext {
                             Extern::None => None,
-                            Extern::Implicit(start_span) => Some(ExternBlockSuggestion::Implicit {
-                                start_span,
-                                end_span: item.span.shrink_to_hi(),
-                            }),
+                            Extern::Implicit(start_span) => {
+                                Some(errors::ExternBlockSuggestion::Implicit {
+                                    start_span,
+                                    end_span: item.span.shrink_to_hi(),
+                                })
+                            }
                             Extern::Explicit(abi, start_span) => {
-                                Some(ExternBlockSuggestion::Explicit {
+                                Some(errors::ExternBlockSuggestion::Explicit {
                                     start_span,
                                     end_span: item.span.shrink_to_hi(),
                                     abi: abi.symbol_unescaped,
@@ -1105,10 +926,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 let old_item = mem::replace(&mut self.extern_mod, Some(item));
                 self.invalid_visibility(
                     &item.vis,
-                    Some(InvalidVisibilityNote::IndividualForeignItems),
+                    Some(errors::InvalidVisibilityNote::IndividualForeignItems),
                 );
                 if let &Unsafe::Yes(span) = unsafety {
-                    self.err_handler().span_err(span, "extern block cannot be declared unsafe");
+                    self.err_handler().emit_err(errors::UnsafeItem { span, kind: "extern block" });
                 }
                 if abi.is_none() {
                     self.maybe_lint_missing_abi(item.span, item.id);
@@ -1148,7 +969,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             }
             ItemKind::Mod(unsafety, mod_kind) => {
                 if let &Unsafe::Yes(span) = unsafety {
-                    self.err_handler().span_err(span, "module cannot be declared unsafe");
+                    self.err_handler().emit_err(errors::UnsafeItem { span, kind: "module" });
                 }
                 // Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
                 if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _))
@@ -1159,18 +980,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             }
             ItemKind::Union(vdata, ..) => {
                 if vdata.fields().is_empty() {
-                    self.err_handler().span_err(item.span, "unions cannot have zero fields");
+                    self.err_handler().emit_err(errors::FieldlessUnion { span: item.span });
                 }
             }
             ItemKind::Const(def, .., None) => {
                 self.check_defaultness(item.span, *def);
-                self.session.emit_err(ConstWithoutBody {
+                self.session.emit_err(errors::ConstWithoutBody {
                     span: item.span,
                     replace_span: self.ending_semi_or_hi(item.span),
                 });
             }
             ItemKind::Static(.., None) => {
-                self.session.emit_err(StaticWithoutBody {
+                self.session.emit_err(errors::StaticWithoutBody {
                     span: item.span,
                     replace_span: self.ending_semi_or_hi(item.span),
                 });
@@ -1178,21 +999,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             ItemKind::TyAlias(box TyAlias { defaultness, where_clauses, bounds, ty, .. }) => {
                 self.check_defaultness(item.span, *defaultness);
                 if ty.is_none() {
-                    self.session.emit_err(TyAliasWithoutBody {
+                    self.session.emit_err(errors::TyAliasWithoutBody {
                         span: item.span,
                         replace_span: self.ending_semi_or_hi(item.span),
                     });
                 }
                 self.check_type_no_bounds(bounds, "this context");
                 if where_clauses.1.0 {
-                    let mut err = self.err_handler().struct_span_err(
-                        where_clauses.1.1,
-                        "where clauses are not allowed after the type for type aliases",
-                    );
-                    err.note(
-                        "see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information",
-                    );
-                    err.emit();
+                    self.err_handler()
+                        .emit_err(errors::WhereAfterTypeAlias { span: where_clauses.1.1 });
                 }
             }
             _ => {}
@@ -1246,7 +1061,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         // are allowed to contain nested `impl Trait`.
                         AngleBracketedArg::Constraint(constraint) => {
                             self.with_impl_trait(None, |this| {
-                                this.visit_assoc_constraint_from_generic_args(constraint);
+                                this.visit_assoc_constraint(constraint);
                             });
                         }
                     }
@@ -1274,11 +1089,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 }
                 GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
                     if let Some(span) = prev_param_default {
-                        let mut err = self.err_handler().struct_span_err(
-                            span,
-                            "generic parameters with a default must be trailing",
-                        );
-                        err.emit();
+                        self.err_handler().emit_err(errors::GenericDefaultTrailing { span });
                         break;
                     }
                 }
@@ -1306,13 +1117,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                             match bound {
                                 GenericBound::Trait(t, _) => {
                                     if !t.bound_generic_params.is_empty() {
-                                        struct_span_err!(
-                                            self.err_handler(),
-                                            t.span,
-                                            E0316,
-                                            "nested quantification of lifetimes"
-                                        )
-                                        .emit();
+                                        self.err_handler()
+                                            .emit_err(errors::NestedLifetimes { span: t.span });
                                     }
                                 }
                                 GenericBound::Outlives(_) => {}
@@ -1337,32 +1143,27 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
         if let GenericBound::Trait(poly, modify) = bound {
             match (ctxt, modify) {
                 (BoundKind::SuperTraits, TraitBoundModifier::Maybe) => {
-                    let mut err = self
-                        .err_handler()
-                        .struct_span_err(poly.span, "`?Trait` is not permitted in supertraits");
-                    let path_str = pprust::path_to_string(&poly.trait_ref.path);
-                    err.note(&format!("traits are `?{}` by default", path_str));
-                    err.emit();
+                    self.err_handler().emit_err(errors::OptionalTraitSupertrait {
+                        span: poly.span,
+                        path_str: pprust::path_to_string(&poly.trait_ref.path)
+                    });
                 }
                 (BoundKind::TraitObject, TraitBoundModifier::Maybe) => {
-                    let mut err = self.err_handler().struct_span_err(
-                        poly.span,
-                        "`?Trait` is not permitted in trait object types",
-                    );
-                    err.emit();
+                    self.err_handler().emit_err(errors::OptionalTraitObject {span: poly.span});
                 }
                 (_, TraitBoundModifier::MaybeConst) if let Some(reason) = &self.disallow_tilde_const => {
-                    let mut err = self.err_handler().struct_span_err(bound.span(), "`~const` is not allowed here");
-                    match reason {
-                        DisallowTildeConstContext::TraitObject => err.note("trait objects cannot have `~const` trait bounds"),
-                        DisallowTildeConstContext::Fn(FnKind::Closure(..)) => err.note("closures cannot have `~const` trait bounds"),
-                        DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => err.span_note(ident.span, "this function is not `const`, so it cannot have `~const` trait bounds"),
+                    let reason = match reason {
+                        DisallowTildeConstContext::TraitObject => errors::TildeConstReason::TraitObject,
+                        DisallowTildeConstContext::Fn(FnKind::Closure(..)) => errors::TildeConstReason::Closure,
+                        DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => errors::TildeConstReason::Function { ident: ident.span },
                     };
-                    err.emit();
+                    self.err_handler().emit_err(errors::TildeConstDisallowed {
+                        span: bound.span(),
+                        reason
+                    });
                 }
                 (_, TraitBoundModifier::MaybeConstMaybe) => {
-                    self.err_handler()
-                        .span_err(bound.span(), "`~const` and `?` are mutually exclusive");
+                    self.err_handler().emit_err(errors::OptionalConstExclusive {span: bound.span()});
                 }
                 _ => {}
             }
@@ -1371,14 +1172,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
         visit::walk_param_bound(self, bound)
     }
 
-    fn visit_variant_data(&mut self, s: &'a VariantData) {
-        self.with_banned_assoc_ty_bound(|this| visit::walk_struct_def(this, s))
-    }
-
-    fn visit_enum_def(&mut self, enum_definition: &'a EnumDef) {
-        self.with_banned_assoc_ty_bound(|this| visit::walk_enum_def(this, enum_definition))
-    }
-
     fn visit_fn(&mut self, fk: FnKind<'a>, span: Span, id: NodeId) {
         // Only associated `fn`s can have `self` parameters.
         let self_semantic = match fk.ctxt() {
@@ -1390,21 +1183,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
         self.check_c_variadic_type(fk);
 
         // Functions cannot both be `const async`
-        if let Some(FnHeader {
+        if let Some(&FnHeader {
             constness: Const::Yes(cspan),
             asyncness: Async::Yes { span: aspan, .. },
             ..
         }) = fk.header()
         {
-            self.err_handler()
-                .struct_span_err(
-                    vec![*cspan, *aspan],
-                    "functions cannot be both `const` and `async`",
-                )
-                .span_label(*cspan, "`const` because of this")
-                .span_label(*aspan, "`async` because of this")
-                .span_label(span, "") // Point at the fn header.
-                .emit();
+            self.err_handler().emit_err(errors::ConstAndAsync {
+                spans: vec![cspan, aspan],
+                cspan,
+                aspan,
+                span,
+            });
         }
 
         if let FnKind::Fn(
@@ -1422,20 +1212,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
         // Functions without bodies cannot have patterns.
         if let FnKind::Fn(ctxt, _, sig, _, _, None) = fk {
             Self::check_decl_no_pat(&sig.decl, |span, ident, mut_ident| {
-                let (code, msg, label) = match ctxt {
-                    FnCtxt::Foreign => (
-                        error_code!(E0130),
-                        "patterns aren't allowed in foreign function declarations",
-                        "pattern not allowed in foreign function",
-                    ),
-                    _ => (
-                        error_code!(E0642),
-                        "patterns aren't allowed in functions without bodies",
-                        "pattern not allowed in function without body",
-                    ),
-                };
                 if mut_ident && matches!(ctxt, FnCtxt::Assoc(_)) {
                     if let Some(ident) = ident {
+                        let msg = match ctxt {
+                            FnCtxt::Foreign => fluent::ast_passes_pattern_in_foreign,
+                            _ => fluent::ast_passes_pattern_in_bodiless,
+                        };
                         let diag = BuiltinLintDiagnostics::PatternsInFnsWithoutBody(span, ident);
                         self.lint_buffer.buffer_lint_with_diagnostic(
                             PATTERNS_IN_FNS_WITHOUT_BODY,
@@ -1446,11 +1228,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         )
                     }
                 } else {
-                    self.err_handler()
-                        .struct_span_err(span, msg)
-                        .span_label(span, label)
-                        .code(code)
-                        .emit();
+                    match ctxt {
+                        FnCtxt::Foreign => {
+                            self.err_handler().emit_err(errors::PatternInForeign { span })
+                        }
+                        _ => self.err_handler().emit_err(errors::PatternInBodiless { span }),
+                    };
                 }
             });
         }
@@ -1477,7 +1260,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             match &item.kind {
                 AssocItemKind::Const(_, _, body) => {
                     if body.is_none() {
-                        self.session.emit_err(AssocConstWithoutBody {
+                        self.session.emit_err(errors::AssocConstWithoutBody {
                             span: item.span,
                             replace_span: self.ending_semi_or_hi(item.span),
                         });
@@ -1485,7 +1268,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 }
                 AssocItemKind::Fn(box Fn { body, .. }) => {
                     if body.is_none() {
-                        self.session.emit_err(AssocFnWithoutBody {
+                        self.session.emit_err(errors::AssocFnWithoutBody {
                             span: item.span,
                             replace_span: self.ending_semi_or_hi(item.span),
                         });
@@ -1500,7 +1283,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     ..
                 }) => {
                     if ty.is_none() {
-                        self.session.emit_err(AssocTypeWithoutBody {
+                        self.session.emit_err(errors::AssocTypeWithoutBody {
                             span: item.span,
                             replace_span: self.ending_semi_or_hi(item.span),
                         });
@@ -1572,11 +1355,7 @@ fn deny_equality_constraints(
     predicate: &WhereEqPredicate,
     generics: &Generics,
 ) {
-    let mut err = this.err_handler().struct_span_err(
-        predicate.span,
-        "equality constraints are not yet supported in `where` clauses",
-    );
-    err.span_label(predicate.span, "not supported");
+    let mut err = errors::EqualityInWhere { span: predicate.span, assoc: None, assoc2: None };
 
     // Given `<A as Foo>::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
     if let TyKind::Path(Some(qself), full_path) = &predicate.lhs_ty.kind {
@@ -1615,25 +1394,17 @@ fn deny_equality_constraints(
                                         empty_args => {
                                             *empty_args = AngleBracketedArgs {
                                                 span: ident.span,
-                                                args: vec![arg],
+                                                args: thin_vec![arg],
                                             }
                                             .into();
                                         }
                                     }
-                                    err.span_suggestion_verbose(
-                                        predicate.span,
-                                        &format!(
-                                            "if `{}` is an associated type you're trying to set, \
-                                            use the associated type binding syntax",
-                                            ident
-                                        ),
-                                        format!(
-                                            "{}: {}",
-                                            param,
-                                            pprust::path_to_string(&assoc_path)
-                                        ),
-                                        Applicability::MaybeIncorrect,
-                                    );
+                                    err.assoc = Some(errors::AssociatedSuggestion {
+                                        span: predicate.span,
+                                        ident: *ident,
+                                        param: *param,
+                                        path: pprust::path_to_string(&assoc_path),
+                                    })
                                 }
                                 _ => {}
                             };
@@ -1675,15 +1446,13 @@ fn deny_equality_constraints(
                                         trait_segment.span().shrink_to_hi(),
                                     ),
                                 };
-                                err.multipart_suggestion(
-                                    &format!(
-                                        "if `{}::{}` is an associated type you're trying to set, \
-                                        use the associated type binding syntax",
-                                        trait_segment.ident, potential_assoc.ident,
-                                    ),
-                                    vec![(span, args), (predicate.span, String::new())],
-                                    Applicability::MaybeIncorrect,
-                                );
+                                err.assoc2 = Some(errors::AssociatedSuggestion2 {
+                                    span,
+                                    args,
+                                    predicate: predicate.span,
+                                    trait_segment: trait_segment.ident,
+                                    potential_assoc: potential_assoc.ident,
+                                });
                             }
                         }
                     }
@@ -1691,10 +1460,7 @@ fn deny_equality_constraints(
             }
         }
     }
-    err.note(
-        "see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information",
-    );
-    err.emit();
+    this.err_handler().emit_err(err);
 }
 
 pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) -> bool {
@@ -1707,7 +1473,6 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) ->
         outer_impl_trait: None,
         disallow_tilde_const: None,
         is_impl_trait_banned: false,
-        is_assoc_ty_bound_banned: false,
         forbidden_let_reason: Some(ForbiddenLetReason::GenericForbidden),
         lint_buffer: lints,
     };
@@ -1722,12 +1487,12 @@ pub(crate) enum ForbiddenLetReason {
     /// `let` is not valid and the source environment is not important
     GenericForbidden,
     /// A let chain with the `||` operator
-    #[note(not_supported_or)]
+    #[note(ast_passes_not_supported_or)]
     NotSupportedOr(#[primary_span] Span),
     /// A let chain with invalid parentheses
     ///
     /// For example, `let 1 = 1 && (expr && expr)` is allowed
     /// but `(let 1 = 1 && (let 1 = 1 && (let 1 = 1))) && let a = 1` is not
-    #[note(not_supported_parentheses)]
+    #[note(ast_passes_not_supported_parentheses)]
     NotSupportedParentheses(#[primary_span] Span),
 }
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 09e262452b1..d007097d918 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -1,9 +1,12 @@
 //! Errors emitted by ast_passes.
 
+use rustc_ast::ParamKindOrd;
+use rustc_errors::AddToDiagnostic;
 use rustc_macros::{Diagnostic, Subdiagnostic};
-use rustc_span::{Span, Symbol};
+use rustc_span::{symbol::Ident, Span, Symbol};
 
 use crate::ast_validation::ForbiddenLetReason;
+use crate::fluent_generated as fluent;
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_forbidden_let)]
@@ -24,13 +27,6 @@ pub struct ForbiddenLetStable {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_forbidden_assoc_constraint)]
-pub struct ForbiddenAssocConstraint {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(ast_passes_keyword_lifetime)]
 pub struct KeywordLifetime {
     #[primary_span]
@@ -50,7 +46,7 @@ pub struct InvalidLabel {
 pub struct InvalidVisibility {
     #[primary_span]
     pub span: Span,
-    #[label(implied)]
+    #[label(ast_passes_implied)]
     pub implied: Option<Span>,
     #[subdiagnostic]
     pub note: Option<InvalidVisibilityNote>,
@@ -58,9 +54,9 @@ pub struct InvalidVisibility {
 
 #[derive(Subdiagnostic)]
 pub enum InvalidVisibilityNote {
-    #[note(individual_impl_items)]
+    #[note(ast_passes_individual_impl_items)]
     IndividualImplItems,
-    #[note(individual_foreign_items)]
+    #[note(ast_passes_individual_foreign_items)]
     IndividualForeignItems,
 }
 
@@ -224,3 +220,474 @@ pub enum ExternBlockSuggestion {
         abi: Symbol,
     },
 }
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_bound_in_context)]
+pub struct BoundInContext<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub ctx: &'a str,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_extern_types_cannot)]
+#[note(ast_passes_extern_keyword_link)]
+pub struct ExternTypesCannotHave<'a> {
+    #[primary_span]
+    #[suggestion(code = "", applicability = "maybe-incorrect")]
+    pub span: Span,
+    pub descr: &'a str,
+    pub remove_descr: &'a str,
+    #[label]
+    pub block_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_body_in_extern)]
+#[note(ast_passes_extern_keyword_link)]
+pub struct BodyInExtern<'a> {
+    #[primary_span]
+    #[label(ast_passes_cannot_have)]
+    pub span: Span,
+    #[label(ast_passes_invalid)]
+    pub body: Span,
+    #[label(ast_passes_existing)]
+    pub block: Span,
+    pub kind: &'a str,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_fn_body_extern)]
+#[help]
+#[note(ast_passes_extern_keyword_link)]
+pub struct FnBodyInExtern {
+    #[primary_span]
+    #[label(ast_passes_cannot_have)]
+    pub span: Span,
+    #[suggestion(code = ";", applicability = "maybe-incorrect")]
+    pub body: Span,
+    #[label]
+    pub block: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_extern_fn_qualifiers)]
+pub struct FnQualifierInExtern {
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub block: Span,
+    #[suggestion(code = "fn ", applicability = "maybe-incorrect", style = "verbose")]
+    pub sugg_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_extern_item_ascii)]
+#[note]
+pub struct ExternItemAscii {
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub block: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_bad_c_variadic)]
+pub struct BadCVariadic {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_item_underscore)]
+pub struct ItemUnderscore<'a> {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    pub kind: &'a str,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_nomangle_ascii, code = "E0754")]
+pub struct NoMangleAscii {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_module_nonascii, code = "E0754")]
+#[help]
+pub struct ModuleNonAscii {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_auto_generic, code = "E0567")]
+pub struct AutoTraitGeneric {
+    #[primary_span]
+    #[suggestion(code = "", applicability = "machine-applicable")]
+    pub span: Span,
+    #[label]
+    pub ident: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_auto_super_lifetime, code = "E0568")]
+pub struct AutoTraitBounds {
+    #[primary_span]
+    #[suggestion(code = "", applicability = "machine-applicable")]
+    pub span: Span,
+    #[label]
+    pub ident: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_auto_items, code = "E0380")]
+pub struct AutoTraitItems {
+    #[primary_span]
+    pub spans: Vec<Span>,
+    #[suggestion(code = "", applicability = "machine-applicable")]
+    pub total: Span,
+    #[label]
+    pub ident: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_generic_before_constraints)]
+pub struct ArgsBeforeConstraint {
+    #[primary_span]
+    pub arg_spans: Vec<Span>,
+    #[label(ast_passes_constraints)]
+    pub constraints: Span,
+    #[label(ast_passes_args)]
+    pub args: Span,
+    #[suggestion(code = "{suggestion}", applicability = "machine-applicable", style = "verbose")]
+    pub data: Span,
+    pub suggestion: String,
+    pub constraint_len: usize,
+    pub args_len: usize,
+    #[subdiagnostic]
+    pub constraint_spans: EmptyLabelManySpans,
+    #[subdiagnostic]
+    pub arg_spans2: EmptyLabelManySpans,
+}
+
+pub struct EmptyLabelManySpans(pub Vec<Span>);
+
+// The derive for `Vec<Span>` does multiple calls to `span_label`, adding commas between each
+impl AddToDiagnostic for EmptyLabelManySpans {
+    fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
+    where
+        F: Fn(
+            &mut rustc_errors::Diagnostic,
+            rustc_errors::SubdiagnosticMessage,
+        ) -> rustc_errors::SubdiagnosticMessage,
+    {
+        diag.span_labels(self.0, "");
+    }
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_pattern_in_fn_pointer, code = "E0561")]
+pub struct PatternFnPointer {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_trait_object_single_bound, code = "E0226")]
+pub struct TraitObjectBound {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_impl_trait_path, code = "E0667")]
+pub struct ImplTraitPath {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_nested_impl_trait, code = "E0666")]
+pub struct NestedImplTrait {
+    #[primary_span]
+    pub span: Span,
+    #[label(ast_passes_outer)]
+    pub outer: Span,
+    #[label(ast_passes_inner)]
+    pub inner: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_at_least_one_trait)]
+pub struct AtLeastOneTrait {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_out_of_order_params)]
+pub struct OutOfOrderParams<'a> {
+    #[primary_span]
+    pub spans: Vec<Span>,
+    #[suggestion(code = "{ordered_params}", applicability = "machine-applicable")]
+    pub sugg_span: Span,
+    pub param_ord: &'a ParamKindOrd,
+    pub max_param: &'a ParamKindOrd,
+    pub ordered_params: &'a str,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_obsolete_auto)]
+#[help]
+pub struct ObsoleteAuto {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_unsafe_negative_impl, code = "E0198")]
+pub struct UnsafeNegativeImpl {
+    #[primary_span]
+    pub span: Span,
+    #[label(ast_passes_negative)]
+    pub negative: Span,
+    #[label(ast_passes_unsafe)]
+    pub r#unsafe: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_inherent_cannot_be)]
+pub struct InherentImplCannot<'a> {
+    #[primary_span]
+    pub span: Span,
+    #[label(ast_passes_because)]
+    pub annotation_span: Span,
+    pub annotation: &'a str,
+    #[label(ast_passes_type)]
+    pub self_ty: Span,
+    #[note(ast_passes_only_trait)]
+    pub only_trait: Option<()>,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_inherent_cannot_be, code = "E0197")]
+pub struct InherentImplCannotUnsafe<'a> {
+    #[primary_span]
+    pub span: Span,
+    #[label(ast_passes_because)]
+    pub annotation_span: Span,
+    pub annotation: &'a str,
+    #[label(ast_passes_type)]
+    pub self_ty: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_unsafe_item)]
+pub struct UnsafeItem {
+    #[primary_span]
+    pub span: Span,
+    pub kind: &'static str,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_fieldless_union)]
+pub struct FieldlessUnion {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_where_after_type_alias)]
+#[note]
+pub struct WhereAfterTypeAlias {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_generic_default_trailing)]
+pub struct GenericDefaultTrailing {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_nested_lifetimes, code = "E0316")]
+pub struct NestedLifetimes {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_optional_trait_supertrait)]
+#[note]
+pub struct OptionalTraitSupertrait {
+    #[primary_span]
+    pub span: Span,
+    pub path_str: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_optional_trait_object)]
+pub struct OptionalTraitObject {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_tilde_const_disallowed)]
+pub struct TildeConstDisallowed {
+    #[primary_span]
+    pub span: Span,
+    #[subdiagnostic]
+    pub reason: TildeConstReason,
+}
+
+#[derive(Subdiagnostic)]
+pub enum TildeConstReason {
+    #[note(ast_passes_trait)]
+    TraitObject,
+    #[note(ast_passes_closure)]
+    Closure,
+    #[note(ast_passes_function)]
+    Function {
+        #[primary_span]
+        ident: Span,
+    },
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_optional_const_exclusive)]
+pub struct OptionalConstExclusive {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_const_and_async)]
+pub struct ConstAndAsync {
+    #[primary_span]
+    pub spans: Vec<Span>,
+    #[label(ast_passes_const)]
+    pub cspan: Span,
+    #[label(ast_passes_async)]
+    pub aspan: Span,
+    #[label]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_pattern_in_foreign, code = "E0130")]
+pub struct PatternInForeign {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_pattern_in_bodiless, code = "E0642")]
+pub struct PatternInBodiless {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_equality_in_where)]
+#[note]
+pub struct EqualityInWhere {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    #[subdiagnostic]
+    pub assoc: Option<AssociatedSuggestion>,
+    #[subdiagnostic]
+    pub assoc2: Option<AssociatedSuggestion2>,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(
+    ast_passes_suggestion,
+    code = "{param}: {path}",
+    style = "verbose",
+    applicability = "maybe-incorrect"
+)]
+pub struct AssociatedSuggestion {
+    #[primary_span]
+    pub span: Span,
+    pub ident: Ident,
+    pub param: Ident,
+    pub path: String,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(ast_passes_suggestion_path, applicability = "maybe-incorrect")]
+pub struct AssociatedSuggestion2 {
+    #[suggestion_part(code = "{args}")]
+    pub span: Span,
+    pub args: String,
+    #[suggestion_part(code = "")]
+    pub predicate: Span,
+    pub trait_segment: Ident,
+    pub potential_assoc: Ident,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_stability_outside_std, code = "E0734")]
+pub struct StabilityOutsideStd {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_feature_on_non_nightly, code = "E0554")]
+pub struct FeatureOnNonNightly {
+    #[primary_span]
+    pub span: Span,
+    pub channel: &'static str,
+    #[subdiagnostic]
+    pub stable_features: Vec<StableFeature>,
+    #[suggestion(code = "", applicability = "machine-applicable")]
+    pub sugg: Option<Span>,
+}
+
+pub struct StableFeature {
+    pub name: Symbol,
+    pub since: Symbol,
+}
+
+impl AddToDiagnostic for StableFeature {
+    fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
+    where
+        F: Fn(
+            &mut rustc_errors::Diagnostic,
+            rustc_errors::SubdiagnosticMessage,
+        ) -> rustc_errors::SubdiagnosticMessage,
+    {
+        diag.set_arg("name", self.name);
+        diag.set_arg("since", self.since);
+        diag.help(fluent::ast_passes_stable_since);
+    }
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_incompatbile_features)]
+#[help]
+pub struct IncompatibleFeatures {
+    #[primary_span]
+    pub spans: Vec<Span>,
+    pub f1: Symbol,
+    pub f2: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_show_span)]
+pub struct ShowSpan {
+    #[primary_span]
+    pub span: Span,
+    pub msg: &'static str,
+}
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 3af2ef4e727..926b0da2ec6 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -2,7 +2,7 @@ use rustc_ast as ast;
 use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
 use rustc_ast::{AssocConstraint, AssocConstraintKind, NodeId};
 use rustc_ast::{PatKind, RangeEnd};
-use rustc_errors::{struct_span_err, Applicability, StashKey};
+use rustc_errors::{Applicability, StashKey};
 use rustc_feature::{AttributeGate, BuiltinAttribute, Features, GateIssue, BUILTIN_ATTRIBUTE_MAP};
 use rustc_session::parse::{feature_err, feature_err_issue, feature_warn};
 use rustc_session::Session;
@@ -10,8 +10,10 @@ use rustc_span::source_map::Spanned;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 use rustc_target::spec::abi;
+use thin_vec::ThinVec;
+use tracing::debug;
 
-use crate::errors::ForbiddenLifetimeBound;
+use crate::errors;
 
 macro_rules! gate_feature_fn {
     ($visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $help: expr) => {{
@@ -155,14 +157,14 @@ impl<'a> PostExpansionVisitor<'a> {
                 &self.sess.parse_sess,
                 sym::non_lifetime_binders,
                 non_lt_param_spans,
-                rustc_errors::fluent::ast_passes_forbidden_non_lifetime_param,
+                crate::fluent_generated::ast_passes_forbidden_non_lifetime_param,
             )
             .emit();
         }
         for param in params {
             if !param.bounds.is_empty() {
                 let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
-                self.sess.emit_err(ForbiddenLifetimeBound { spans });
+                self.sess.emit_err(errors::ForbiddenLifetimeBound { spans });
             }
         }
     }
@@ -216,13 +218,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                 || attr.has_name(sym::rustc_const_stable)
                 || attr.has_name(sym::rustc_default_body_unstable)
             {
-                struct_span_err!(
-                    self.sess,
-                    attr.span,
-                    E0734,
-                    "stability attributes may not be used outside of the standard library",
-                )
-                .emit();
+                self.sess.emit_err(errors::StabilityOutsideStd { span: attr.span });
             }
         }
     }
@@ -250,7 +246,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
 
             ast::ItemKind::Struct(..) => {
                 for attr in self.sess.filter_by_name(&i.attrs, sym::repr) {
-                    for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
+                    for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) {
                         if item.has_name(sym::simd) {
                             gate_feature_post!(
                                 &self,
@@ -633,13 +629,13 @@ fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
             return;
         }
         for attr in krate.attrs.iter().filter(|attr| attr.has_name(sym::feature)) {
-            let mut err = struct_span_err!(
-                sess.parse_sess.span_diagnostic,
-                attr.span,
-                E0554,
-                "`#![feature]` may not be used on the {} release channel",
-                option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)")
-            );
+            let mut err = errors::FeatureOnNonNightly {
+                span: attr.span,
+                channel: option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)"),
+                stable_features: vec![],
+                sugg: None,
+            };
+
             let mut all_stable = true;
             for ident in
                 attr.meta_item_list().into_iter().flatten().flat_map(|nested| nested.ident())
@@ -650,24 +646,15 @@ fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
                     .flat_map(|&(feature, _, since)| if feature == name { since } else { None })
                     .next();
                 if let Some(since) = stable_since {
-                    err.help(&format!(
-                        "the feature `{}` has been stable since {} and no longer requires \
-                                  an attribute to enable",
-                        name, since
-                    ));
+                    err.stable_features.push(errors::StableFeature { name, since });
                 } else {
                     all_stable = false;
                 }
             }
             if all_stable {
-                err.span_suggestion(
-                    attr.span,
-                    "remove the attribute",
-                    "",
-                    Applicability::MachineApplicable,
-                );
+                err.sugg = Some(attr.span);
             }
-            err.emit();
+            sess.parse_sess.span_diagnostic.emit_err(err);
         }
     }
 }
@@ -690,16 +677,7 @@ fn check_incompatible_features(sess: &Session) {
             if let Some((f2_name, f2_span)) = declared_features.clone().find(|(name, _)| name == f2)
             {
                 let spans = vec![f1_span, f2_span];
-                sess.struct_span_err(
-                    spans,
-                    &format!(
-                        "features `{}` and `{}` are incompatible, using them at the same time \
-                        is not allowed",
-                        f1_name, f2_name
-                    ),
-                )
-                .help("remove one of these features")
-                .emit();
+                sess.emit_err(errors::IncompatibleFeatures { spans, f1: f1_name, f2: f2_name });
             }
         }
     }
diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs
index f58fffc9172..b9dcaee2373 100644
--- a/compiler/rustc_ast_passes/src/lib.rs
+++ b/compiler/rustc_ast_passes/src/lib.rs
@@ -10,12 +10,16 @@
 #![feature(iter_is_partitioned)]
 #![feature(let_chains)]
 #![recursion_limit = "256"]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 
-#[macro_use]
-extern crate tracing;
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_macros::fluent_messages;
 
 pub mod ast_validation;
 mod errors;
 pub mod feature_gate;
 pub mod node_count;
 pub mod show_span;
+
+fluent_messages! { "../locales/en-US.ftl" }
diff --git a/compiler/rustc_ast_passes/src/show_span.rs b/compiler/rustc_ast_passes/src/show_span.rs
index 27637e311f4..280cf3284c3 100644
--- a/compiler/rustc_ast_passes/src/show_span.rs
+++ b/compiler/rustc_ast_passes/src/show_span.rs
@@ -9,6 +9,8 @@ use rustc_ast as ast;
 use rustc_ast::visit;
 use rustc_ast::visit::Visitor;
 
+use crate::errors;
+
 enum Mode {
     Expression,
     Pattern,
@@ -36,21 +38,21 @@ struct ShowSpanVisitor<'a> {
 impl<'a> Visitor<'a> for ShowSpanVisitor<'a> {
     fn visit_expr(&mut self, e: &'a ast::Expr) {
         if let Mode::Expression = self.mode {
-            self.span_diagnostic.span_warn(e.span, "expression");
+            self.span_diagnostic.emit_warning(errors::ShowSpan { span: e.span, msg: "expression" });
         }
         visit::walk_expr(self, e);
     }
 
     fn visit_pat(&mut self, p: &'a ast::Pat) {
         if let Mode::Pattern = self.mode {
-            self.span_diagnostic.span_warn(p.span, "pattern");
+            self.span_diagnostic.emit_warning(errors::ShowSpan { span: p.span, msg: "pattern" });
         }
         visit::walk_pat(self, p);
     }
 
     fn visit_ty(&mut self, t: &'a ast::Ty) {
         if let Mode::Type = self.mode {
-            self.span_diagnostic.span_warn(t.span, "type");
+            self.span_diagnostic.emit_warning(errors::ShowSpan { span: t.span, msg: "type" });
         }
         visit::walk_ty(self, t);
     }
diff --git a/compiler/rustc_ast_pretty/Cargo.toml b/compiler/rustc_ast_pretty/Cargo.toml
index d1513c114fe..980a8fa93a9 100644
--- a/compiler/rustc_ast_pretty/Cargo.toml
+++ b/compiler/rustc_ast_pretty/Cargo.toml
@@ -8,3 +8,4 @@ edition = "2021"
 [dependencies]
 rustc_ast = { path = "../rustc_ast" }
 rustc_span = { path = "../rustc_span" }
+thin-vec = "0.2.12"
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index cd621bc67a1..694d688bf1f 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -4,7 +4,7 @@ mod item;
 
 use crate::pp::Breaks::{Consistent, Inconsistent};
 use crate::pp::{self, Breaks};
-
+use rustc_ast::attr::AttrIdGenerator;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, BinOpToken, CommentKind, Delimiter, Nonterminal, Token, TokenKind};
 use rustc_ast::tokenstream::{TokenStream, TokenTree};
@@ -20,9 +20,8 @@ use rustc_span::edition::Edition;
 use rustc_span::source_map::{SourceMap, Spanned};
 use rustc_span::symbol::{kw, sym, Ident, IdentPrinter, Symbol};
 use rustc_span::{BytePos, FileName, Span, DUMMY_SP};
-
-use rustc_ast::attr::AttrIdGenerator;
 use std::borrow::Cow;
+use thin_vec::ThinVec;
 
 pub use self::delimited::IterDelimited;
 
@@ -1722,10 +1721,10 @@ impl<'a> State<'a> {
         self.ibox(INDENT_UNIT);
         self.print_formal_generic_params(generic_params);
         let generics = ast::Generics {
-            params: Vec::new(),
+            params: ThinVec::new(),
             where_clause: ast::WhereClause {
                 has_where_token: false,
-                predicates: Vec::new(),
+                predicates: ThinVec::new(),
                 span: DUMMY_SP,
             },
             span: DUMMY_SP,
diff --git a/compiler/rustc_ast_pretty/src/pprust/tests.rs b/compiler/rustc_ast_pretty/src/pprust/tests.rs
index 6c8d42f33eb..3b2b60a86f0 100644
--- a/compiler/rustc_ast_pretty/src/pprust/tests.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/tests.rs
@@ -3,6 +3,7 @@ use super::*;
 use rustc_ast as ast;
 use rustc_span::create_default_session_globals_then;
 use rustc_span::symbol::Ident;
+use thin_vec::ThinVec;
 
 fn fun_to_string(
     decl: &ast::FnDecl,
@@ -27,8 +28,10 @@ fn test_fun_to_string() {
     create_default_session_globals_then(|| {
         let abba_ident = Ident::from_str("abba");
 
-        let decl =
-            ast::FnDecl { inputs: Vec::new(), output: ast::FnRetTy::Default(rustc_span::DUMMY_SP) };
+        let decl = ast::FnDecl {
+            inputs: ThinVec::new(),
+            output: ast::FnRetTy::Default(rustc_span::DUMMY_SP),
+        };
         let generics = ast::Generics::default();
         assert_eq!(
             fun_to_string(&decl, ast::FnHeader::default(), abba_ident, &generics),
diff --git a/compiler/rustc_error_messages/locales/en-US/attr.ftl b/compiler/rustc_attr/locales/en-US.ftl
index a7f8c993d42..a7f8c993d42 100644
--- a/compiler/rustc_error_messages/locales/en-US/attr.ftl
+++ b/compiler/rustc_attr/locales/en-US.ftl
diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs
index 4580ffcc6d8..5fede0a58ac 100644
--- a/compiler/rustc_attr/src/lib.rs
+++ b/compiler/rustc_attr/src/lib.rs
@@ -11,6 +11,9 @@
 #[macro_use]
 extern crate rustc_macros;
 
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_macros::fluent_messages;
+
 mod builtin;
 mod session_diagnostics;
 
@@ -22,3 +25,5 @@ pub use StabilityLevel::*;
 pub use rustc_ast::attr::*;
 
 pub(crate) use rustc_ast::HashStableContext;
+
+fluent_messages! { "../locales/en-US.ftl" }
diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs
index 3ba7a3c5336..ee79545e304 100644
--- a/compiler/rustc_attr/src/session_diagnostics.rs
+++ b/compiler/rustc_attr/src/session_diagnostics.rs
@@ -2,11 +2,12 @@ use std::num::IntErrorKind;
 
 use rustc_ast as ast;
 use rustc_errors::{
-    error_code, fluent, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic,
+    error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic,
 };
 use rustc_macros::Diagnostic;
 use rustc_span::{Span, Symbol};
 
+use crate::fluent_generated as fluent;
 use crate::UnsupportedLiteralReason;
 
 #[derive(Diagnostic)]
@@ -59,7 +60,7 @@ impl<'a> IntoDiagnostic<'a> for UnknownMetaItem<'_> {
         );
         diag.set_arg("item", self.item);
         diag.set_arg("expected", expected.join(", "));
-        diag.span_label(self.span, fluent::label);
+        diag.span_label(self.span, fluent::attr_label);
         diag
     }
 }
@@ -99,31 +100,31 @@ pub(crate) struct InvalidIssueString {
 // translatable.
 #[derive(Subdiagnostic)]
 pub(crate) enum InvalidIssueStringCause {
-    #[label(must_not_be_zero)]
+    #[label(attr_must_not_be_zero)]
     MustNotBeZero {
         #[primary_span]
         span: Span,
     },
 
-    #[label(empty)]
+    #[label(attr_empty)]
     Empty {
         #[primary_span]
         span: Span,
     },
 
-    #[label(invalid_digit)]
+    #[label(attr_invalid_digit)]
     InvalidDigit {
         #[primary_span]
         span: Span,
     },
 
-    #[label(pos_overflow)]
+    #[label(attr_pos_overflow)]
     PosOverflow {
         #[primary_span]
         span: Span,
     },
 
-    #[label(neg_overflow)]
+    #[label(attr_neg_overflow)]
     NegOverflow {
         #[primary_span]
         span: Span,
@@ -275,7 +276,7 @@ pub(crate) struct IncorrectReprFormatGeneric<'a> {
 
 #[derive(Subdiagnostic)]
 pub(crate) enum IncorrectReprFormatGenericCause<'a> {
-    #[suggestion(suggestion, code = "{name}({int})", applicability = "machine-applicable")]
+    #[suggestion(attr_suggestion, code = "{name}({int})", applicability = "machine-applicable")]
     Int {
         #[primary_span]
         span: Span,
@@ -287,7 +288,7 @@ pub(crate) enum IncorrectReprFormatGenericCause<'a> {
         int: u128,
     },
 
-    #[suggestion(suggestion, code = "{name}({symbol})", applicability = "machine-applicable")]
+    #[suggestion(attr_suggestion, code = "{name}({symbol})", applicability = "machine-applicable")]
     Symbol {
         #[primary_span]
         span: Span,
diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_borrowck/locales/en-US.ftl
index a3b6b5e8138..a3b6b5e8138 100644
--- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl
+++ b/compiler/rustc_borrowck/locales/en-US.ftl
diff --git a/compiler/rustc_borrowck/src/constraint_generation.rs b/compiler/rustc_borrowck/src/constraint_generation.rs
index 11b31c3f140..1427f5cb31d 100644
--- a/compiler/rustc_borrowck/src/constraint_generation.rs
+++ b/compiler/rustc_borrowck/src/constraint_generation.rs
@@ -9,7 +9,7 @@ use rustc_middle::mir::{
 };
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::visit::TypeVisitable;
-use rustc_middle::ty::{self, RegionVid, Ty};
+use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
 
 use crate::{
     borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, nll::ToRegionVid,
@@ -165,7 +165,7 @@ impl<'cx, 'tcx> ConstraintGeneration<'cx, 'tcx> {
     /// `location`.
     fn add_regular_live_constraint<T>(&mut self, live_ty: T, location: Location)
     where
-        T: TypeVisitable<'tcx>,
+        T: TypeVisitable<TyCtxt<'tcx>>,
     {
         debug!("add_regular_live_constraint(live_ty={:?}, location={:?})", live_ty, location);
 
diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs
index 1f0b8adeaf1..f370c02161b 100644
--- a/compiler/rustc_borrowck/src/constraints/mod.rs
+++ b/compiler/rustc_borrowck/src/constraints/mod.rs
@@ -17,7 +17,7 @@ pub(crate) mod graph;
 /// constraints of the form `R1: R2`. Each constraint is identified by
 /// a unique `OutlivesConstraintIndex` and you can index into the set
 /// (`constraint_set[i]`) to access the constraint details.
-#[derive(Clone, Default)]
+#[derive(Clone, Debug, Default)]
 pub(crate) struct OutlivesConstraintSet<'tcx> {
     outlives: IndexVec<OutlivesConstraintIndex, OutlivesConstraint<'tcx>>,
 }
diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
index d51cc652bfd..68205fa4558 100644
--- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
@@ -106,7 +106,7 @@ impl<'tcx> ToUniverseInfo<'tcx>
     }
 }
 
-impl<'tcx, T: Copy + fmt::Display + TypeFoldable<'tcx> + 'tcx> ToUniverseInfo<'tcx>
+impl<'tcx, T: Copy + fmt::Display + TypeFoldable<TyCtxt<'tcx>> + 'tcx> ToUniverseInfo<'tcx>
     for Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize<T>>>
 {
     fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
@@ -258,7 +258,7 @@ struct NormalizeQuery<'tcx, T> {
 
 impl<'tcx, T> TypeOpInfo<'tcx> for NormalizeQuery<'tcx, T>
 where
-    T: Copy + fmt::Display + TypeFoldable<'tcx> + 'tcx,
+    T: Copy + fmt::Display + TypeFoldable<TyCtxt<'tcx>> + 'tcx,
 {
     fn fallback_error(
         &self,
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index b2d72654a2a..7a1066f6b58 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -1494,7 +1494,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         assert!(root_place.projection.is_empty());
         let proper_span = self.body.local_decls[root_place.local].source_info.span;
 
-        let root_place_projection = self.infcx.tcx.intern_place_elems(root_place.projection);
+        let root_place_projection = self.infcx.tcx.mk_place_elems(root_place.projection);
 
         if self.access_place_error_reported.contains(&(
             Place { local: root_place.local, projection: root_place_projection },
@@ -2135,7 +2135,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
         let tcx = self.infcx.tcx;
 
-        let (_, escapes_from) = tcx.article_and_description(self.mir_def_id().to_def_id());
+        let escapes_from = tcx.def_descr(self.mir_def_id().to_def_id());
 
         let mut err =
             borrowck_errors::borrowed_data_escapes_closure(tcx, escape_span, escapes_from);
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index a2fa3018234..4baf1b6aa87 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -660,10 +660,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             errci.outlived_fr,
         );
 
-        let (_, escapes_from) = self
-            .infcx
-            .tcx
-            .article_and_description(self.regioncx.universal_regions().defining_ty.def_id());
+        let escapes_from =
+            self.infcx.tcx.def_descr(self.regioncx.universal_regions().defining_ty.def_id());
 
         // Revert to the normal error in these cases.
         // Assignments aren't "escapes" in function items.
@@ -757,8 +755,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             ..
         } = errci;
 
-        let (_, mir_def_name) =
-            self.infcx.tcx.article_and_description(self.mir_def_id().to_def_id());
+        let mir_def_name = self.infcx.tcx.def_descr(self.mir_def_id().to_def_id());
 
         let err = LifetimeOutliveErr { span: *span };
         let mut diag = self.infcx.tcx.sess.create_err(err);
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 98103af779d..18d7bde60d7 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -1,6 +1,7 @@
 //! This query borrow-checks the MIR to (further) ensure it is not broken.
 
 #![allow(rustc::potential_query_instability)]
+#![feature(associated_type_bounds)]
 #![feature(box_patterns)]
 #![feature(let_chains)]
 #![feature(min_specialization)]
@@ -20,12 +21,15 @@ extern crate tracing;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::graph::dominators::Dominators;
 use rustc_data_structures::vec_map::VecMap;
-use rustc_errors::{Diagnostic, DiagnosticBuilder};
+use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticMessage, SubdiagnosticMessage};
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_index::bit_set::ChunkedBitSet;
 use rustc_index::vec::IndexVec;
-use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt};
+use rustc_infer::infer::{
+    DefiningAnchor, InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt,
+};
+use rustc_macros::fluent_messages;
 use rustc_middle::mir::{
     traversal, Body, ClearCrossCrate, Local, Location, Mutability, NonDivergingIntrinsic, Operand,
     Place, PlaceElem, PlaceRef, VarDebugInfoContents,
@@ -43,6 +47,7 @@ use smallvec::SmallVec;
 use std::cell::OnceCell;
 use std::cell::RefCell;
 use std::collections::BTreeMap;
+use std::ops::Deref;
 use std::rc::Rc;
 
 use rustc_mir_dataflow::impls::{
@@ -94,6 +99,9 @@ use nll::{PoloniusOutput, ToRegionVid};
 use place_ext::PlaceExt;
 use places_conflict::{places_conflict, PlaceConflictBias};
 use region_infer::RegionInferenceContext;
+use renumber::RegionCtxt;
+
+fluent_messages! { "../locales/en-US.ftl" }
 
 // FIXME(eddyb) perhaps move this somewhere more centrally.
 #[derive(Debug)]
@@ -167,10 +175,10 @@ fn do_mir_borrowck<'tcx>(
     return_body_with_facts: bool,
 ) -> (BorrowCheckResult<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) {
     let def = input_body.source.with_opt_param().as_local().unwrap();
-
     debug!(?def);
 
     let tcx = infcx.tcx;
+    let infcx = BorrowckInferCtxt::new(infcx);
     let param_env = tcx.param_env(def.did);
 
     let mut local_names = IndexVec::from_elem(None, &input_body.local_decls);
@@ -218,7 +226,7 @@ fn do_mir_borrowck<'tcx>(
     let mut body_owned = input_body.clone();
     let mut promoted = input_promoted.clone();
     let free_regions =
-        nll::replace_regions_in_mir(infcx, param_env, &mut body_owned, &mut promoted);
+        nll::replace_regions_in_mir(&infcx, param_env, &mut body_owned, &mut promoted);
     let body = &body_owned; // no further changes
 
     let location_table_owned = LocationTable::new(body);
@@ -256,7 +264,7 @@ fn do_mir_borrowck<'tcx>(
         opt_closure_req,
         nll_errors,
     } = nll::compute_regions(
-        infcx,
+        &infcx,
         free_regions,
         body,
         &promoted,
@@ -271,12 +279,12 @@ fn do_mir_borrowck<'tcx>(
 
     // Dump MIR results into a file, if that is enabled. This let us
     // write unit-tests, as well as helping with debugging.
-    nll::dump_mir_results(infcx, &body, &regioncx, &opt_closure_req);
+    nll::dump_mir_results(&infcx, &body, &regioncx, &opt_closure_req);
 
     // We also have a `#[rustc_regions]` annotation that causes us to dump
     // information.
     nll::dump_annotation(
-        infcx,
+        &infcx,
         &body,
         &regioncx,
         &opt_closure_req,
@@ -320,7 +328,7 @@ fn do_mir_borrowck<'tcx>(
 
         if let Err((move_data, move_errors)) = move_data_results {
             let mut promoted_mbcx = MirBorrowckCtxt {
-                infcx,
+                infcx: &infcx,
                 param_env,
                 body: promoted_body,
                 move_data: &move_data,
@@ -349,7 +357,7 @@ fn do_mir_borrowck<'tcx>(
     }
 
     let mut mbcx = MirBorrowckCtxt {
-        infcx,
+        infcx: &infcx,
         param_env,
         body,
         move_data: &mdpe.move_data,
@@ -481,8 +489,84 @@ pub struct BodyWithBorrowckFacts<'tcx> {
     pub location_table: LocationTable,
 }
 
+pub struct BorrowckInferCtxt<'cx, 'tcx> {
+    pub(crate) infcx: &'cx InferCtxt<'tcx>,
+    pub(crate) reg_var_to_origin: RefCell<FxHashMap<ty::RegionVid, RegionCtxt>>,
+}
+
+impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> {
+    pub(crate) fn new(infcx: &'cx InferCtxt<'tcx>) -> Self {
+        BorrowckInferCtxt { infcx, reg_var_to_origin: RefCell::new(Default::default()) }
+    }
+
+    pub(crate) fn next_region_var<F>(
+        &self,
+        origin: RegionVariableOrigin,
+        get_ctxt_fn: F,
+    ) -> ty::Region<'tcx>
+    where
+        F: Fn() -> RegionCtxt,
+    {
+        let next_region = self.infcx.next_region_var(origin);
+        let vid = next_region
+            .as_var()
+            .unwrap_or_else(|| bug!("expected RegionKind::RegionVar on {:?}", next_region));
+
+        if cfg!(debug_assertions) {
+            debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin);
+            let ctxt = get_ctxt_fn();
+            let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
+            let prev = var_to_origin.insert(vid, ctxt);
+
+            // This only makes sense if not called in a canonicalization context. If this
+            // ever changes we either want to get rid of `BorrowckInferContext::reg_var_to_origin`
+            // or modify how we track nll region vars for that map.
+            assert!(matches!(prev, None));
+        }
+
+        next_region
+    }
+
+    #[instrument(skip(self, get_ctxt_fn), level = "debug")]
+    pub(crate) fn next_nll_region_var<F>(
+        &self,
+        origin: NllRegionVariableOrigin,
+        get_ctxt_fn: F,
+    ) -> ty::Region<'tcx>
+    where
+        F: Fn() -> RegionCtxt,
+    {
+        let next_region = self.infcx.next_nll_region_var(origin.clone());
+        let vid = next_region
+            .as_var()
+            .unwrap_or_else(|| bug!("expected RegionKind::RegionVar on {:?}", next_region));
+
+        if cfg!(debug_assertions) {
+            debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin);
+            let ctxt = get_ctxt_fn();
+            let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
+            let prev = var_to_origin.insert(vid, ctxt);
+
+            // This only makes sense if not called in a canonicalization context. If this
+            // ever changes we either want to get rid of `BorrowckInferContext::reg_var_to_origin`
+            // or modify how we track nll region vars for that map.
+            assert!(matches!(prev, None));
+        }
+
+        next_region
+    }
+}
+
+impl<'cx, 'tcx> Deref for BorrowckInferCtxt<'cx, 'tcx> {
+    type Target = InferCtxt<'tcx>;
+
+    fn deref(&self) -> &'cx Self::Target {
+        self.infcx
+    }
+}
+
 struct MirBorrowckCtxt<'cx, 'tcx> {
-    infcx: &'cx InferCtxt<'tcx>,
+    infcx: &'cx BorrowckInferCtxt<'cx, 'tcx>,
     param_env: ParamEnv<'tcx>,
     body: &'cx Body<'tcx>,
     move_data: &'cx MoveData<'tcx>,
diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs
index c71413e8e7c..e5dbb83dd07 100644
--- a/compiler/rustc_borrowck/src/nll.rs
+++ b/compiler/rustc_borrowck/src/nll.rs
@@ -5,7 +5,6 @@
 use rustc_data_structures::vec_map::VecMap;
 use rustc_hir::def_id::LocalDefId;
 use rustc_index::vec::IndexVec;
-use rustc_infer::infer::InferCtxt;
 use rustc_middle::mir::{create_dump_file, dump_enabled, dump_mir, PassWhere};
 use rustc_middle::mir::{
     BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
@@ -37,7 +36,7 @@ use crate::{
     renumber,
     type_check::{self, MirTypeckRegionConstraints, MirTypeckResults},
     universal_regions::UniversalRegions,
-    Upvar,
+    BorrowckInferCtxt, Upvar,
 };
 
 pub type PoloniusOutput = Output<RustcFacts>;
@@ -58,7 +57,7 @@ pub(crate) struct NllOutput<'tcx> {
 /// `compute_regions`.
 #[instrument(skip(infcx, param_env, body, promoted), level = "debug")]
 pub(crate) fn replace_regions_in_mir<'tcx>(
-    infcx: &InferCtxt<'tcx>,
+    infcx: &BorrowckInferCtxt<'_, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     body: &mut Body<'tcx>,
     promoted: &mut IndexVec<Promoted, Body<'tcx>>,
@@ -157,7 +156,7 @@ fn populate_polonius_move_facts(
 ///
 /// This may result in errors being reported.
 pub(crate) fn compute_regions<'cx, 'tcx>(
-    infcx: &InferCtxt<'tcx>,
+    infcx: &BorrowckInferCtxt<'_, 'tcx>,
     universal_regions: UniversalRegions<'tcx>,
     body: &Body<'tcx>,
     promoted: &IndexVec<Promoted, Body<'tcx>>,
@@ -259,6 +258,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
     );
 
     let mut regioncx = RegionInferenceContext::new(
+        infcx,
         var_origins,
         universal_regions,
         placeholder_indices,
@@ -322,7 +322,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
 }
 
 pub(super) fn dump_mir_results<'tcx>(
-    infcx: &InferCtxt<'tcx>,
+    infcx: &BorrowckInferCtxt<'_, 'tcx>,
     body: &Body<'tcx>,
     regioncx: &RegionInferenceContext<'tcx>,
     closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
@@ -372,7 +372,7 @@ pub(super) fn dump_mir_results<'tcx>(
 #[allow(rustc::diagnostic_outside_of_impl)]
 #[allow(rustc::untranslatable_diagnostic)]
 pub(super) fn dump_annotation<'tcx>(
-    infcx: &InferCtxt<'tcx>,
+    infcx: &BorrowckInferCtxt<'_, 'tcx>,
     body: &Body<'tcx>,
     regioncx: &RegionInferenceContext<'tcx>,
     closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 83fdb6066c6..941da2dd3b5 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -17,7 +17,7 @@ use rustc_middle::mir::{
 };
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::traits::ObligationCauseCode;
-use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable};
+use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
 use rustc_span::Span;
 
 use crate::{
@@ -34,6 +34,7 @@ use crate::{
     },
     type_check::{free_region_relations::UniversalRegionRelations, Locations},
     universal_regions::UniversalRegions,
+    BorrowckInferCtxt,
 };
 
 mod dump_mir;
@@ -243,6 +244,70 @@ pub enum ExtraConstraintInfo {
     PlaceholderFromPredicate(Span),
 }
 
+#[instrument(skip(infcx, sccs), level = "debug")]
+fn sccs_info<'cx, 'tcx>(
+    infcx: &'cx BorrowckInferCtxt<'cx, 'tcx>,
+    sccs: Rc<Sccs<RegionVid, ConstraintSccIndex>>,
+) {
+    use crate::renumber::RegionCtxt;
+
+    let var_to_origin = infcx.reg_var_to_origin.borrow();
+
+    let mut var_to_origin_sorted = var_to_origin.clone().into_iter().collect::<Vec<_>>();
+    var_to_origin_sorted.sort_by(|a, b| a.0.cmp(&b.0));
+    let mut debug_str = "region variables to origins:\n".to_string();
+    for (reg_var, origin) in var_to_origin_sorted.into_iter() {
+        debug_str.push_str(&format!("{:?}: {:?}\n", reg_var, origin));
+    }
+    debug!(debug_str);
+
+    let num_components = sccs.scc_data().ranges().len();
+    let mut components = vec![FxHashSet::default(); num_components];
+
+    for (reg_var_idx, scc_idx) in sccs.scc_indices().iter().enumerate() {
+        let reg_var = ty::RegionVid::from_usize(reg_var_idx);
+        let origin = var_to_origin.get(&reg_var).unwrap_or_else(|| &RegionCtxt::Unknown);
+        components[scc_idx.as_usize()].insert((reg_var, *origin));
+    }
+
+    let mut components_str = "strongly connected components:".to_string();
+    for (scc_idx, reg_vars_origins) in components.iter().enumerate() {
+        let regions_info = reg_vars_origins.clone().into_iter().collect::<Vec<_>>();
+        components_str.push_str(&format!(
+            "{:?}: {:?})",
+            ConstraintSccIndex::from_usize(scc_idx),
+            regions_info,
+        ))
+    }
+    debug!(components_str);
+
+    // calculate the best representative for each component
+    let components_representatives = components
+        .into_iter()
+        .enumerate()
+        .map(|(scc_idx, region_ctxts)| {
+            let repr = region_ctxts
+                .into_iter()
+                .map(|reg_var_origin| reg_var_origin.1)
+                .max_by(|x, y| x.preference_value().cmp(&y.preference_value()))
+                .unwrap();
+
+            (ConstraintSccIndex::from_usize(scc_idx), repr)
+        })
+        .collect::<FxHashMap<_, _>>();
+
+    let mut scc_node_to_edges = FxHashMap::default();
+    for (scc_idx, repr) in components_representatives.iter() {
+        let edges_range = sccs.scc_data().ranges()[*scc_idx].clone();
+        let edges = &sccs.scc_data().all_successors()[edges_range];
+        let edge_representatives =
+            edges.iter().map(|scc_idx| components_representatives[scc_idx]).collect::<Vec<_>>();
+        scc_node_to_edges.insert((scc_idx, repr), edge_representatives);
+    }
+
+    debug!("SCC edges {:#?}", scc_node_to_edges);
+}
+
 impl<'tcx> RegionInferenceContext<'tcx> {
     /// Creates a new region inference context with a total of
     /// `num_region_variables` valid inference variables; the first N
@@ -251,7 +316,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     ///
     /// The `outlives_constraints` and `type_tests` are an initial set
     /// of constraints produced by the MIR type check.
-    pub(crate) fn new(
+    pub(crate) fn new<'cx>(
+        _infcx: &BorrowckInferCtxt<'cx, 'tcx>,
         var_infos: VarInfos,
         universal_regions: Rc<UniversalRegions<'tcx>>,
         placeholder_indices: Rc<PlaceholderIndices>,
@@ -263,6 +329,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         liveness_constraints: LivenessValues<RegionVid>,
         elements: &Rc<RegionValueElements>,
     ) -> Self {
+        debug!("universal_regions: {:#?}", universal_regions);
+        debug!("outlives constraints: {:#?}", outlives_constraints);
+        debug!("placeholder_indices: {:#?}", placeholder_indices);
+        debug!("type tests: {:#?}", type_tests);
+
         // Create a RegionDefinition for each inference variable.
         let definitions: IndexVec<_, _> = var_infos
             .iter()
@@ -274,6 +345,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         let fr_static = universal_regions.fr_static;
         let constraint_sccs = Rc::new(constraints.compute_sccs(&constraint_graph, fr_static));
 
+        if cfg!(debug_assertions) {
+            sccs_info(_infcx, constraint_sccs.clone());
+        }
+
         let mut scc_values =
             RegionValues::new(elements, universal_regions.len(), &placeholder_indices);
 
@@ -1291,7 +1366,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// we use this kind of hacky solution.
     fn normalize_to_scc_representatives<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         tcx.fold_regions(value, |r, _db| {
             let vid = self.to_region_vid(r);
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index bb42301828d..c550e37c63e 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -1,12 +1,13 @@
 use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
 use rustc_data_structures::vec_map::VecMap;
+use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::OpaqueTyOrigin;
 use rustc_infer::infer::TyCtxtInferExt as _;
 use rustc_infer::infer::{DefiningAnchor, InferCtxt};
 use rustc_infer::traits::{Obligation, ObligationCause};
 use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
-use rustc_middle::ty::visit::TypeVisitable;
+use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
 use rustc_span::Span;
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
@@ -149,13 +150,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             // once we convert the generic parameters to those of the opaque type.
             if let Some(prev) = result.get_mut(&opaque_type_key.def_id) {
                 if prev.ty != ty {
-                    if !ty.references_error() {
+                    let guar = ty.error_reported().err().unwrap_or_else(|| {
                         prev.report_mismatch(
                             &OpaqueHiddenType { ty, span: concrete_type.span },
                             infcx.tcx,
-                        );
-                    }
-                    prev.ty = infcx.tcx.ty_error();
+                        )
+                    });
+                    prev.ty = infcx.tcx.ty_error(guar);
                 }
                 // Pick a better span if there is one.
                 // FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
@@ -178,7 +179,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// region names in error messages.
     pub(crate) fn name_regions<T>(&self, tcx: TyCtxt<'tcx>, ty: T) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         tcx.fold_regions(ty, |region, _| match *region {
             ty::ReVar(vid) => {
@@ -247,20 +248,20 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
         origin: OpaqueTyOrigin,
     ) -> Ty<'tcx> {
         if let Some(e) = self.tainted_by_errors() {
-            return self.tcx.ty_error_with_guaranteed(e);
+            return self.tcx.ty_error(e);
         }
 
         let definition_ty = instantiated_ty
             .remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false)
             .ty;
 
-        if !check_opaque_type_parameter_valid(
+        if let Err(guar) = check_opaque_type_parameter_valid(
             self.tcx,
             opaque_type_key,
             origin,
             instantiated_ty.span,
         ) {
-            return self.tcx.ty_error();
+            return self.tcx.ty_error(guar);
         }
 
         // Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs`
@@ -273,7 +274,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
         // FIXME(oli-obk): Also do region checks here and then consider removing `check_opaque_meets_bounds` entirely.
         let param_env = self.tcx.param_env(def_id);
         // HACK This bubble is required for this tests to pass:
-        // type-alias-impl-trait/issue-67844-nested-opaque.rs
+        // nested-return-type2-tait2.rs
+        // nested-return-type2-tait3.rs
         let infcx =
             self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build();
         let ocx = ObligationCtxt::new(&infcx);
@@ -324,7 +326,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
             definition_ty
         } else {
             let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None);
-            self.tcx.ty_error_with_guaranteed(reported)
+            self.tcx.ty_error(reported)
         }
     }
 }
@@ -334,7 +336,7 @@ fn check_opaque_type_parameter_valid(
     opaque_type_key: OpaqueTypeKey<'_>,
     origin: OpaqueTyOrigin,
     span: Span,
-) -> bool {
+) -> Result<(), ErrorGuaranteed> {
     match origin {
         // No need to check return position impl trait (RPIT)
         // because for type and const parameters they are correct
@@ -357,7 +359,7 @@ fn check_opaque_type_parameter_valid(
         // fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>.
         //
         // which would error here on all of the `'static` args.
-        OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return true,
+        OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return Ok(()),
         // Check these
         OpaqueTyOrigin::TyAlias => {}
     }
@@ -378,13 +380,13 @@ fn check_opaque_type_parameter_valid(
             // Prevent `fn foo() -> Foo<u32>` from being defining.
             let opaque_param = opaque_generics.param_at(i, tcx);
             let kind = opaque_param.kind.descr();
-            tcx.sess.emit_err(NonGenericOpaqueTypeParam {
+
+            return Err(tcx.sess.emit_err(NonGenericOpaqueTypeParam {
                 ty: arg,
                 kind,
                 span,
                 param_span: tcx.def_span(opaque_param.def_id),
-            });
-            return false;
+            }));
         }
     }
 
@@ -395,12 +397,13 @@ fn check_opaque_type_parameter_valid(
                 .into_iter()
                 .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id))
                 .collect();
-            tcx.sess
+            return Err(tcx
+                .sess
                 .struct_span_err(span, "non-defining opaque type use in defining scope")
                 .span_note(spans, &format!("{} used multiple times", descr))
-                .emit();
-            return false;
+                .emit());
         }
     }
-    true
+
+    Ok(())
 }
diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs
index 6a3748fded5..c361357ca21 100644
--- a/compiler/rustc_borrowck/src/region_infer/values.rs
+++ b/compiler/rustc_borrowck/src/region_infer/values.rs
@@ -181,7 +181,7 @@ impl<N: Idx> LivenessValues<N> {
 /// Maps from `ty::PlaceholderRegion` values that are used in the rest of
 /// rustc to the internal `PlaceholderIndex` values that are used in
 /// NLL.
-#[derive(Default)]
+#[derive(Debug, Default)]
 pub(crate) struct PlaceholderIndices {
     indices: FxIndexSet<ty::PlaceholderRegion>,
 }
diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs
index 084754830bd..016f6f78dfa 100644
--- a/compiler/rustc_borrowck/src/renumber.rs
+++ b/compiler/rustc_borrowck/src/renumber.rs
@@ -1,18 +1,20 @@
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
+use crate::BorrowckInferCtxt;
 use rustc_index::vec::IndexVec;
-use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
+use rustc_infer::infer::NllRegionVariableOrigin;
 use rustc_middle::mir::visit::{MutVisitor, TyContext};
 use rustc_middle::mir::Constant;
 use rustc_middle::mir::{Body, Location, Promoted};
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
+use rustc_span::{Span, Symbol};
 
 /// Replaces all free regions appearing in the MIR with fresh
 /// inference variables, returning the number of variables created.
 #[instrument(skip(infcx, body, promoted), level = "debug")]
 pub fn renumber_mir<'tcx>(
-    infcx: &InferCtxt<'tcx>,
+    infcx: &BorrowckInferCtxt<'_, 'tcx>,
     body: &mut Body<'tcx>,
     promoted: &mut IndexVec<Promoted, Body<'tcx>>,
 ) {
@@ -29,27 +31,68 @@ pub fn renumber_mir<'tcx>(
 
 /// Replaces all regions appearing in `value` with fresh inference
 /// variables.
-#[instrument(skip(infcx), level = "debug")]
-pub fn renumber_regions<'tcx, T>(infcx: &InferCtxt<'tcx>, value: T) -> T
+#[instrument(skip(infcx, get_ctxt_fn), level = "debug")]
+pub(crate) fn renumber_regions<'tcx, T, F>(
+    infcx: &BorrowckInferCtxt<'_, 'tcx>,
+    value: T,
+    get_ctxt_fn: F,
+) -> T
 where
-    T: TypeFoldable<'tcx>,
+    T: TypeFoldable<TyCtxt<'tcx>>,
+    F: Fn() -> RegionCtxt,
 {
     infcx.tcx.fold_regions(value, |_region, _depth| {
         let origin = NllRegionVariableOrigin::Existential { from_forall: false };
-        infcx.next_nll_region_var(origin)
+        infcx.next_nll_region_var(origin, || get_ctxt_fn())
     })
 }
 
+#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
+pub(crate) enum BoundRegionInfo {
+    Name(Symbol),
+    Span(Span),
+}
+
+#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
+pub(crate) enum RegionCtxt {
+    Location(Location),
+    TyContext(TyContext),
+    Free(Symbol),
+    Bound(BoundRegionInfo),
+    LateBound(BoundRegionInfo),
+    Existential(Option<Symbol>),
+    Placeholder(BoundRegionInfo),
+    Unknown,
+}
+
+impl RegionCtxt {
+    /// Used to determine the representative of a component in the strongly connected
+    /// constraint graph
+    pub(crate) fn preference_value(self) -> usize {
+        let _anon = Symbol::intern("anon");
+
+        match self {
+            RegionCtxt::Unknown => 1,
+            RegionCtxt::Existential(None) => 2,
+            RegionCtxt::Existential(Some(_anon)) | RegionCtxt::Free(_anon) => 2,
+            RegionCtxt::Location(_) => 3,
+            RegionCtxt::TyContext(_) => 4,
+            _ => 5,
+        }
+    }
+}
+
 struct NllVisitor<'a, 'tcx> {
-    infcx: &'a InferCtxt<'tcx>,
+    infcx: &'a BorrowckInferCtxt<'a, 'tcx>,
 }
 
 impl<'a, 'tcx> NllVisitor<'a, 'tcx> {
-    fn renumber_regions<T>(&mut self, value: T) -> T
+    fn renumber_regions<T, F>(&mut self, value: T, region_ctxt_fn: F) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
+        F: Fn() -> RegionCtxt,
     {
-        renumber_regions(self.infcx, value)
+        renumber_regions(self.infcx, value, region_ctxt_fn)
     }
 }
 
@@ -60,14 +103,14 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
 
     #[instrument(skip(self), level = "debug")]
     fn visit_ty(&mut self, ty: &mut Ty<'tcx>, ty_context: TyContext) {
-        *ty = self.renumber_regions(*ty);
+        *ty = self.renumber_regions(*ty, || RegionCtxt::TyContext(ty_context));
 
         debug!(?ty);
     }
 
     #[instrument(skip(self), level = "debug")]
     fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, location: Location) {
-        *substs = self.renumber_regions(*substs);
+        *substs = self.renumber_regions(*substs, || RegionCtxt::Location(location));
 
         debug!(?substs);
     }
@@ -75,7 +118,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
     #[instrument(skip(self), level = "debug")]
     fn visit_region(&mut self, region: &mut ty::Region<'tcx>, location: Location) {
         let old_region = *region;
-        *region = self.renumber_regions(old_region);
+        *region = self.renumber_regions(old_region, || RegionCtxt::Location(location));
 
         debug!(?region);
     }
@@ -83,7 +126,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
     #[instrument(skip(self), level = "debug")]
     fn visit_constant(&mut self, constant: &mut Constant<'tcx>, _location: Location) {
         let literal = constant.literal;
-        constant.literal = self.renumber_regions(literal);
+        constant.literal = self.renumber_regions(literal, || RegionCtxt::Location(_location));
         debug!("constant: {:#?}", constant);
     }
 }
diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs
index 13199d03852..a3678929099 100644
--- a/compiler/rustc_borrowck/src/session_diagnostics.rs
+++ b/compiler/rustc_borrowck/src/session_diagnostics.rs
@@ -55,7 +55,7 @@ pub(crate) struct VarNeedNotMut {
 #[derive(Diagnostic)]
 #[diag(borrowck_var_cannot_escape_closure)]
 #[note]
-#[note(cannot_escape)]
+#[note(borrowck_cannot_escape)]
 pub(crate) struct FnMutError {
     #[primary_span]
     pub span: Span,
@@ -223,7 +223,7 @@ pub(crate) struct MoveBorrow<'a> {
     pub borrow_place: &'a str,
     pub value_place: &'a str,
     #[primary_span]
-    #[label(move_label)]
+    #[label(borrowck_move_label)]
     pub span: Span,
     #[label]
     pub borrow_span: Span,
diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs
index 2b81a35052d..b27d5d20532 100644
--- a/compiler/rustc_borrowck/src/type_check/canonical.rs
+++ b/compiler/rustc_borrowck/src/type_check/canonical.rs
@@ -2,7 +2,7 @@ use std::fmt;
 
 use rustc_infer::infer::{canonical::Canonical, InferOk};
 use rustc_middle::mir::ConstraintCategory;
-use rustc_middle::ty::{self, ToPredicate, Ty, TypeFoldable};
+use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
 use rustc_span::def_id::DefId;
 use rustc_span::Span;
 use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput};
@@ -66,7 +66,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         canonical: &Canonical<'tcx, T>,
     ) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         let old_universe = self.infcx.universe();
 
@@ -117,7 +117,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
 
     pub(super) fn prove_predicates(
         &mut self,
-        predicates: impl IntoIterator<Item = impl ToPredicate<'tcx> + std::fmt::Debug>,
+        predicates: impl IntoIterator<Item: ToPredicate<'tcx> + std::fmt::Debug>,
         locations: Locations,
         category: ConstraintCategory<'tcx>,
     ) {
diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
index 1dc6c42fbf7..504633c6a5c 100644
--- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
+++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
@@ -6,8 +6,8 @@ use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
 use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
 use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
 use rustc_middle::ty::subst::GenericArgKind;
-use rustc_middle::ty::TypeFoldable;
 use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
 use rustc_span::{Span, DUMMY_SP};
 
 use crate::{
@@ -171,7 +171,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
     ///
     /// FIXME: This should get removed once higher ranked region obligations
     /// are dealt with during trait solving.
-    fn replace_placeholders_with_nll<T: TypeFoldable<'tcx>>(&mut self, value: T) -> T {
+    fn replace_placeholders_with_nll<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, value: T) -> T {
         if value.has_placeholders() {
             self.tcx.fold_regions(value, |r, _| match *r {
                 ty::RePlaceholder(placeholder) => {
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 2dd24fe0340..e2f897a89e8 100644
--- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
+++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
@@ -270,12 +270,13 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
                 .and(type_op::normalize::Normalize::new(ty))
                 .fully_perform(self.infcx)
                 .unwrap_or_else(|_| {
-                    self.infcx
+                    let guar = self
+                        .infcx
                         .tcx
                         .sess
                         .delay_span_bug(span, &format!("failed to normalize {:?}", ty));
                     TypeOpOutput {
-                        output: self.infcx.tcx.ty_error(),
+                        output: self.infcx.tcx.ty_error(guar),
                         constraints: None,
                         error_info: None,
                     }
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
index 3ff5d188a3d..473c0596300 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
@@ -3,7 +3,7 @@ use rustc_index::bit_set::HybridBitSet;
 use rustc_index::interval::IntervalSet;
 use rustc_infer::infer::canonical::QueryRegionConstraints;
 use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location};
-use rustc_middle::ty::{Ty, TypeVisitable};
+use rustc_middle::ty::{Ty, TyCtxt, TypeVisitable, TypeVisitableExt};
 use rustc_trait_selection::traits::query::dropck_outlives::DropckOutlivesResult;
 use rustc_trait_selection::traits::query::type_op::outlives::DropckOutlives;
 use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
@@ -477,7 +477,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
     /// points `live_at`.
     fn add_use_live_facts_for(
         &mut self,
-        value: impl TypeVisitable<'tcx>,
+        value: impl TypeVisitable<TyCtxt<'tcx>>,
         live_at: &IntervalSet<PointIndex>,
     ) {
         debug!("add_use_live_facts_for(value={:?})", value);
@@ -542,7 +542,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
     fn make_all_regions_live(
         elements: &RegionValueElements,
         typeck: &mut TypeChecker<'_, 'tcx>,
-        value: impl TypeVisitable<'tcx>,
+        value: impl TypeVisitable<TyCtxt<'tcx>>,
         live_at: &IntervalSet<PointIndex>,
     ) {
         debug!("make_all_regions_live(value={:?})", value);
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 5e1334559f5..a49da3da6c0 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -30,7 +30,7 @@ use rustc_middle::mir::*;
 use rustc_middle::ty::adjustment::PointerCast;
 use rustc_middle::ty::cast::CastTy;
 use rustc_middle::ty::subst::{SubstsRef, UserSubsts};
-use rustc_middle::ty::visit::TypeVisitable;
+use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{
     self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic,
     OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
@@ -64,7 +64,7 @@ use crate::{
     region_infer::TypeTest,
     type_check::free_region_relations::{CreateResult, UniversalRegionRelations},
     universal_regions::{DefiningTy, UniversalRegions},
-    Upvar,
+    BorrowckInferCtxt, Upvar,
 };
 
 macro_rules! span_mirbug {
@@ -123,7 +123,7 @@ mod relate_tys;
 /// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis
 /// - `elements` -- MIR region map
 pub(crate) fn type_check<'mir, 'tcx>(
-    infcx: &InferCtxt<'tcx>,
+    infcx: &BorrowckInferCtxt<'_, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     body: &Body<'tcx>,
     promoted: &IndexVec<Promoted, Body<'tcx>>,
@@ -239,7 +239,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
                     decl.hidden_type.span,
                     &format!("could not resolve {:#?}", hidden_type.ty.kind()),
                 );
-                hidden_type.ty = infcx.tcx.ty_error_with_guaranteed(reported);
+                hidden_type.ty = infcx.tcx.ty_error(reported);
             }
 
             (opaque_type_key, (hidden_type, decl.origin))
@@ -529,9 +529,9 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
 
         for elem in place.projection.iter() {
             if place_ty.variant_index.is_none() {
-                if place_ty.ty.references_error() {
+                if let Err(guar) = place_ty.ty.error_reported() {
                     assert!(self.errors_reported);
-                    return PlaceTy::from_ty(self.tcx().ty_error());
+                    return PlaceTy::from_ty(self.tcx().ty_error(guar));
                 }
             }
             place_ty = self.sanitize_projection(place_ty, elem, place, location, context);
@@ -763,7 +763,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
 
     fn error(&mut self) -> Ty<'tcx> {
         self.errors_reported = true;
-        self.tcx().ty_error()
+        self.tcx().ty_error_misc()
     }
 
     fn get_ambient_variance(&self, context: PlaceContext) -> ty::Variance {
@@ -866,7 +866,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
 /// way, it accrues region constraints -- these can later be used by
 /// NLL region checking.
 struct TypeChecker<'a, 'tcx> {
-    infcx: &'a InferCtxt<'tcx>,
+    infcx: &'a BorrowckInferCtxt<'a, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     last_span: Span,
     body: &'a Body<'tcx>,
@@ -1019,7 +1019,7 @@ impl Locations {
 
 impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
     fn new(
-        infcx: &'a InferCtxt<'tcx>,
+        infcx: &'a BorrowckInferCtxt<'a, 'tcx>,
         body: &'a Body<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         region_bound_pairs: &'a RegionBoundPairs<'tcx>,
@@ -1356,11 +1356,34 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     }
                 };
                 let (sig, map) = tcx.replace_late_bound_regions(sig, |br| {
-                    self.infcx.next_region_var(LateBoundRegion(
-                        term.source_info.span,
-                        br.kind,
-                        LateBoundRegionConversionTime::FnCall,
-                    ))
+                    use crate::renumber::{BoundRegionInfo, RegionCtxt};
+                    use rustc_span::Symbol;
+
+                    let region_ctxt_fn = || {
+                        let reg_info = match br.kind {
+                            ty::BoundRegionKind::BrAnon(_, Some(span)) => {
+                                BoundRegionInfo::Span(span)
+                            }
+                            ty::BoundRegionKind::BrAnon(..) => {
+                                BoundRegionInfo::Name(Symbol::intern("anon"))
+                            }
+                            ty::BoundRegionKind::BrNamed(_, name) => BoundRegionInfo::Name(name),
+                            ty::BoundRegionKind::BrEnv => {
+                                BoundRegionInfo::Name(Symbol::intern("env"))
+                            }
+                        };
+
+                        RegionCtxt::LateBound(reg_info)
+                    };
+
+                    self.infcx.next_region_var(
+                        LateBoundRegion(
+                            term.source_info.span,
+                            br.kind,
+                            LateBoundRegionConversionTime::FnCall,
+                        ),
+                        region_ctxt_fn,
+                    )
                 });
                 debug!(?sig);
                 // IMPORTANT: We have to prove well formed for the function signature before
@@ -2610,7 +2633,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             DefKind::InlineConst => substs.as_inline_const().parent_substs(),
             other => bug!("unexpected item {:?}", other),
         };
-        let parent_substs = tcx.intern_substs(parent_substs);
+        let parent_substs = tcx.mk_substs(parent_substs);
 
         assert_eq!(typeck_root_substs.len(), parent_substs.len());
         if let Err(_) = self.eq_substs(
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index 8dd06187877..d96372fb99b 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -4,11 +4,12 @@ use rustc_infer::traits::PredicateObligations;
 use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::ty::relate::TypeRelation;
 use rustc_middle::ty::{self, Ty};
-use rustc_span::Span;
+use rustc_span::{Span, Symbol};
 use rustc_trait_selection::traits::query::Fallible;
 
 use crate::constraints::OutlivesConstraint;
 use crate::diagnostics::UniverseInfo;
+use crate::renumber::{BoundRegionInfo, RegionCtxt};
 use crate::type_check::{InstantiateOpaqueType, Locations, TypeChecker};
 
 impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
@@ -100,23 +101,65 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
         universe
     }
 
-    fn next_existential_region_var(&mut self, from_forall: bool) -> ty::Region<'tcx> {
+    #[instrument(skip(self), level = "debug")]
+    fn next_existential_region_var(
+        &mut self,
+        from_forall: bool,
+        _name: Option<Symbol>,
+    ) -> ty::Region<'tcx> {
         let origin = NllRegionVariableOrigin::Existential { from_forall };
-        self.type_checker.infcx.next_nll_region_var(origin)
+
+        let reg_var =
+            self.type_checker.infcx.next_nll_region_var(origin, || RegionCtxt::Existential(_name));
+
+        reg_var
     }
 
+    #[instrument(skip(self), level = "debug")]
     fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx> {
-        self.type_checker
+        let reg = self
+            .type_checker
             .borrowck_context
             .constraints
-            .placeholder_region(self.type_checker.infcx, placeholder)
+            .placeholder_region(self.type_checker.infcx, placeholder);
+
+        let reg_info = match placeholder.name {
+            ty::BoundRegionKind::BrAnon(_, Some(span)) => BoundRegionInfo::Span(span),
+            ty::BoundRegionKind::BrAnon(..) => BoundRegionInfo::Name(Symbol::intern("anon")),
+            ty::BoundRegionKind::BrNamed(_, name) => BoundRegionInfo::Name(name),
+            ty::BoundRegionKind::BrEnv => BoundRegionInfo::Name(Symbol::intern("env")),
+        };
+
+        let reg_var =
+            reg.as_var().unwrap_or_else(|| bug!("expected region {:?} to be of kind ReVar", reg));
+        let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut();
+        let prev = var_to_origin.insert(reg_var, RegionCtxt::Placeholder(reg_info));
+        assert!(matches!(prev, None));
+
+        reg
     }
 
+    #[instrument(skip(self), level = "debug")]
     fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> {
-        self.type_checker.infcx.next_nll_region_var_in_universe(
+        let reg = self.type_checker.infcx.next_nll_region_var_in_universe(
             NllRegionVariableOrigin::Existential { from_forall: false },
             universe,
-        )
+        );
+
+        let reg_var =
+            reg.as_var().unwrap_or_else(|| bug!("expected region {:?} to be of kind ReVar", reg));
+
+        if cfg!(debug_assertions) {
+            let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut();
+            let prev = var_to_origin.insert(reg_var, RegionCtxt::Existential(None));
+
+            // It only makes sense to track region vars in non-canonicalization contexts. If this
+            // ever changes we either want to get rid of `BorrowckInferContext::reg_var_to_origin`
+            // or modify how we track nll region vars for that map.
+            assert!(matches!(prev, None));
+        }
+
+        reg
     }
 
     fn push_outlives(
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index efa5a29c5dd..e058fe0db22 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -20,15 +20,18 @@ use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{BodyOwnerKind, HirId};
 use rustc_index::vec::{Idx, IndexVec};
-use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
+use rustc_infer::infer::NllRegionVariableOrigin;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::{
     self, DefIdTree, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt,
 };
 use rustc_middle::ty::{InternalSubsts, SubstsRef};
+use rustc_span::Symbol;
 use std::iter;
 
 use crate::nll::ToRegionVid;
+use crate::renumber::{BoundRegionInfo, RegionCtxt};
+use crate::BorrowckInferCtxt;
 
 #[derive(Debug)]
 pub struct UniversalRegions<'tcx> {
@@ -224,7 +227,7 @@ impl<'tcx> UniversalRegions<'tcx> {
     /// signature. This will also compute the relationships that are
     /// known between those regions.
     pub fn new(
-        infcx: &InferCtxt<'tcx>,
+        infcx: &BorrowckInferCtxt<'_, 'tcx>,
         mir_def: ty::WithOptConstParam<LocalDefId>,
         param_env: ty::ParamEnv<'tcx>,
     ) -> Self {
@@ -385,7 +388,7 @@ impl<'tcx> UniversalRegions<'tcx> {
 }
 
 struct UniversalRegionsBuilder<'cx, 'tcx> {
-    infcx: &'cx InferCtxt<'tcx>,
+    infcx: &'cx BorrowckInferCtxt<'cx, 'tcx>,
     mir_def: ty::WithOptConstParam<LocalDefId>,
     mir_hir_id: HirId,
     param_env: ty::ParamEnv<'tcx>,
@@ -403,7 +406,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
         assert_eq!(FIRST_GLOBAL_INDEX, self.infcx.num_region_vars());
 
         // Create the "global" region that is always free in all contexts: 'static.
-        let fr_static = self.infcx.next_nll_region_var(FR).to_region_vid();
+        let fr_static = self
+            .infcx
+            .next_nll_region_var(FR, || RegionCtxt::Free(Symbol::intern("static")))
+            .to_region_vid();
 
         // We've now added all the global regions. The next ones we
         // add will be external.
@@ -435,7 +441,17 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                 |r| {
                     debug!(?r);
                     if !indices.indices.contains_key(&r) {
-                        let region_vid = self.infcx.next_nll_region_var(FR);
+                        let region_vid = {
+                            let name = match r.get_name() {
+                                Some(name) => name,
+                                _ => Symbol::intern("anon"),
+                            };
+
+                            self.infcx.next_nll_region_var(FR, || {
+                                RegionCtxt::LateBound(BoundRegionInfo::Name(name))
+                            })
+                        };
+
                         debug!(?region_vid);
                         indices.insert_late_bound_region(r, region_vid.to_region_vid());
                     }
@@ -463,7 +479,17 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
         for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def.did, |r| {
             debug!(?r);
             if !indices.indices.contains_key(&r) {
-                let region_vid = self.infcx.next_nll_region_var(FR);
+                let region_vid = {
+                    let name = match r.get_name() {
+                        Some(name) => name,
+                        _ => Symbol::intern("anon"),
+                    };
+
+                    self.infcx.next_nll_region_var(FR, || {
+                        RegionCtxt::LateBound(BoundRegionInfo::Name(name))
+                    })
+                };
+
                 debug!(?region_vid);
                 indices.insert_late_bound_region(r, region_vid.to_region_vid());
             }
@@ -480,18 +506,27 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                     LangItem::VaList,
                     Some(self.infcx.tcx.def_span(self.mir_def.did)),
                 );
-                let region =
-                    self.infcx.tcx.mk_re_var(self.infcx.next_nll_region_var(FR).to_region_vid());
+
+                let reg_vid = self
+                    .infcx
+                    .next_nll_region_var(FR, || RegionCtxt::Free(Symbol::intern("c-variadic")))
+                    .to_region_vid();
+
+                let region = self.infcx.tcx.mk_re_var(reg_vid);
                 let va_list_ty =
                     self.infcx.tcx.type_of(va_list_did).subst(self.infcx.tcx, &[region.into()]);
 
-                unnormalized_input_tys = self.infcx.tcx.mk_type_list(
+                unnormalized_input_tys = self.infcx.tcx.mk_type_list_from_iter(
                     unnormalized_input_tys.iter().copied().chain(iter::once(va_list_ty)),
                 );
             }
         }
 
-        let fr_fn_body = self.infcx.next_nll_region_var(FR).to_region_vid();
+        let fr_fn_body = self
+            .infcx
+            .next_nll_region_var(FR, || RegionCtxt::Free(Symbol::intern("fn_body")))
+            .to_region_vid();
+
         let num_universals = self.infcx.num_region_vars();
 
         debug!("build: global regions = {}..{}", FIRST_GLOBAL_INDEX, first_extern_index);
@@ -621,7 +656,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                 assert_eq!(self.mir_def.did.to_def_id(), def_id);
                 let closure_sig = substs.as_closure().sig();
                 let inputs_and_output = closure_sig.inputs_and_output();
-                let bound_vars = tcx.mk_bound_variable_kinds(
+                let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
                     inputs_and_output
                         .bound_vars()
                         .iter()
@@ -645,7 +680,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                 };
 
                 ty::Binder::bind_with_vars(
-                    tcx.mk_type_list(
+                    tcx.mk_type_list_from_iter(
                         iter::once(closure_ty).chain(inputs).chain(iter::once(output)),
                     ),
                     bound_vars,
@@ -658,7 +693,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                 let output = substs.as_generator().return_ty();
                 let generator_ty = tcx.mk_generator(def_id, substs, movability);
                 let inputs_and_output =
-                    self.infcx.tcx.intern_type_list(&[generator_ty, resume_ty, output]);
+                    self.infcx.tcx.mk_type_list(&[generator_ty, resume_ty, output]);
                 ty::Binder::dummy(inputs_and_output)
             }
 
@@ -674,13 +709,13 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                 assert_eq!(self.mir_def.did.to_def_id(), def_id);
                 let ty = tcx.type_of(self.mir_def.def_id_for_type_of()).subst_identity();
                 let ty = indices.fold_to_region_vids(tcx, ty);
-                ty::Binder::dummy(tcx.intern_type_list(&[ty]))
+                ty::Binder::dummy(tcx.mk_type_list(&[ty]))
             }
 
             DefiningTy::InlineConst(def_id, substs) => {
                 assert_eq!(self.mir_def.did.to_def_id(), def_id);
                 let ty = substs.as_inline_const().ty();
-                ty::Binder::dummy(tcx.intern_type_list(&[ty]))
+                ty::Binder::dummy(tcx.mk_type_list(&[ty]))
             }
         }
     }
@@ -693,7 +728,7 @@ trait InferCtxtExt<'tcx> {
         value: T,
     ) -> T
     where
-        T: TypeFoldable<'tcx>;
+        T: TypeFoldable<TyCtxt<'tcx>>;
 
     fn replace_bound_regions_with_nll_infer_vars<T>(
         &self,
@@ -703,7 +738,7 @@ trait InferCtxtExt<'tcx> {
         indices: &mut UniversalRegionIndices<'tcx>,
     ) -> T
     where
-        T: TypeFoldable<'tcx>;
+        T: TypeFoldable<TyCtxt<'tcx>>;
 
     fn replace_late_bound_regions_with_nll_infer_vars_in_recursive_scope(
         &self,
@@ -718,16 +753,27 @@ trait InferCtxtExt<'tcx> {
     );
 }
 
-impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
+impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> {
+    #[instrument(skip(self), level = "debug")]
     fn replace_free_regions_with_nll_infer_vars<T>(
         &self,
         origin: NllRegionVariableOrigin,
         value: T,
     ) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
-        self.tcx.fold_regions(value, |_region, _depth| self.next_nll_region_var(origin))
+        self.infcx.tcx.fold_regions(value, |region, _depth| {
+            let name = match region.get_name() {
+                Some(name) => name,
+                _ => Symbol::intern("anon"),
+            };
+            debug!(?region, ?name);
+
+            let reg_var = self.next_nll_region_var(origin, || RegionCtxt::Free(name));
+
+            reg_var
+        })
     }
 
     #[instrument(level = "debug", skip(self, indices))]
@@ -739,12 +785,20 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
         indices: &mut UniversalRegionIndices<'tcx>,
     ) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         let (value, _map) = self.tcx.replace_late_bound_regions(value, |br| {
             debug!(?br);
             let liberated_region = self.tcx.mk_re_free(all_outlive_scope.to_def_id(), br.kind);
-            let region_vid = self.next_nll_region_var(origin);
+            let region_vid = {
+                let name = match br.kind.get_name() {
+                    Some(name) => name,
+                    _ => Symbol::intern("anon"),
+                };
+
+                self.next_nll_region_var(origin, || RegionCtxt::Bound(BoundRegionInfo::Name(name)))
+            };
+
             indices.insert_late_bound_region(liberated_region, region_vid.to_region_vid());
             debug!(?liberated_region, ?region_vid);
             region_vid
@@ -770,7 +824,17 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
         for_each_late_bound_region_in_recursive_scope(self.tcx, mir_def_id, |r| {
             debug!(?r);
             if !indices.indices.contains_key(&r) {
-                let region_vid = self.next_nll_region_var(FR);
+                let region_vid = {
+                    let name = match r.get_name() {
+                        Some(name) => name,
+                        _ => Symbol::intern("anon"),
+                    };
+
+                    self.next_nll_region_var(FR, || {
+                        RegionCtxt::LateBound(BoundRegionInfo::Name(name))
+                    })
+                };
+
                 debug!(?region_vid);
                 indices.insert_late_bound_region(r, region_vid.to_region_vid());
             }
@@ -786,8 +850,17 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
         for_each_late_bound_region_in_item(self.tcx, mir_def_id, |r| {
             debug!(?r);
             if !indices.indices.contains_key(&r) {
-                let region_vid = self.next_nll_region_var(FR);
-                debug!(?region_vid);
+                let region_vid = {
+                    let name = match r.get_name() {
+                        Some(name) => name,
+                        _ => Symbol::intern("anon"),
+                    };
+
+                    self.next_nll_region_var(FR, || {
+                        RegionCtxt::LateBound(BoundRegionInfo::Name(name))
+                    })
+                };
+
                 indices.insert_late_bound_region(r, region_vid.to_region_vid());
             }
         });
@@ -833,7 +906,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
     /// returned by `to_region_vid`.
     pub fn fold_to_region_vids<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         tcx.fold_regions(value, |region, _| tcx.mk_re_var(self.to_region_vid(region)))
     }
diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml
index 467fa932a15..336e14ef966 100644
--- a/compiler/rustc_builtin_macros/Cargo.toml
+++ b/compiler/rustc_builtin_macros/Cargo.toml
@@ -23,5 +23,5 @@ rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-thin-vec = "0.2.9"
+thin-vec = "0.2.12"
 tracing = "0.1"
diff --git a/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl b/compiler/rustc_builtin_macros/locales/en-US.ftl
index 4d088e27b36..4d088e27b36 100644
--- a/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl
+++ b/compiler/rustc_builtin_macros/locales/en-US.ftl
diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
index dcf500ddbd3..ac6697232cb 100644
--- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
+++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
@@ -6,7 +6,7 @@ use rustc_ast::{Fn, ItemKind, Stmt, TyKind, Unsafe};
 use rustc_expand::base::{Annotatable, ExtCtxt};
 use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::Span;
-use thin_vec::thin_vec;
+use thin_vec::{thin_vec, ThinVec};
 
 pub fn expand(
     ecx: &mut ExtCtxt<'_>,
@@ -39,10 +39,10 @@ pub fn expand(
     let span = ecx.with_def_site_ctxt(item.span);
 
     // Generate item statements for the allocator methods.
-    let stmts = vec![generate_handler(ecx, item.ident, span, sig_span)];
+    let stmts = thin_vec![generate_handler(ecx, item.ident, span, sig_span)];
 
     // Generate anonymous constant serving as container for the allocator methods.
-    let const_ty = ecx.ty(sig_span, TyKind::Tup(Vec::new()));
+    let const_ty = ecx.ty(sig_span, TyKind::Tup(ThinVec::new()));
     let const_body = ecx.expr_block(ecx.block(span, stmts));
     let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body);
     let const_item = if is_stmt {
@@ -67,13 +67,16 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span
 
     let layout_new = cx.std_path(&[sym::alloc, sym::Layout, sym::from_size_align_unchecked]);
     let layout_new = cx.expr_path(cx.path(span, layout_new));
-    let layout =
-        cx.expr_call(span, layout_new, vec![cx.expr_ident(span, size), cx.expr_ident(span, align)]);
+    let layout = cx.expr_call(
+        span,
+        layout_new,
+        thin_vec![cx.expr_ident(span, size), cx.expr_ident(span, align)],
+    );
 
-    let call = cx.expr_call_ident(sig_span, handler, vec![layout]);
+    let call = cx.expr_call_ident(sig_span, handler, thin_vec![layout]);
 
     let never = ast::FnRetTy::Ty(cx.ty(span, TyKind::Never));
-    let params = vec![cx.param(span, size, ty_usize.clone()), cx.param(span, align, ty_usize)];
+    let params = thin_vec![cx.param(span, size, ty_usize.clone()), cx.param(span, align, ty_usize)];
     let decl = cx.fn_decl(params, never);
     let header = FnHeader { unsafety: Unsafe::Yes(span), ..FnHeader::default() };
     let sig = FnSig { decl, header, span: span };
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 925392b500a..3fdbc971527 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -152,7 +152,7 @@ pub fn parse_asm_args<'a>(
                 ast::InlineAsmOperand::InOut { reg, expr, late: true }
             }
         } else if p.eat_keyword(kw::Const) {
-            let anon_const = p.parse_anon_const_expr()?;
+            let anon_const = p.parse_expr_anon_const()?;
             ast::InlineAsmOperand::Const { anon_const }
         } else if p.eat_keyword(sym::sym) {
             let expr = p.parse_expr()?;
diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs
index 8555c3593b3..75af5e2b1fa 100644
--- a/compiler/rustc_builtin_macros/src/assert.rs
+++ b/compiler/rustc_builtin_macros/src/assert.rs
@@ -11,6 +11,7 @@ use rustc_expand::base::{DummyResult, ExtCtxt, MacEager, MacResult};
 use rustc_parse::parser::Parser;
 use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
+use thin_vec::thin_vec;
 
 pub fn expand_assert<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
@@ -79,7 +80,7 @@ pub fn expand_assert<'cx>(
         let then = cx.expr_call_global(
             call_site_span,
             cx.std_path(&[sym::panicking, sym::panic]),
-            vec![cx.expr_str(
+            thin_vec![cx.expr_str(
                 DUMMY_SP,
                 Symbol::intern(&format!(
                     "assertion failed: {}",
diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs
index 342b1735661..b0b4dda16af 100644
--- a/compiler/rustc_builtin_macros/src/assert/context.rs
+++ b/compiler/rustc_builtin_macros/src/assert/context.rs
@@ -12,7 +12,7 @@ use rustc_span::{
     symbol::{sym, Ident, Symbol},
     Span,
 };
-use thin_vec::thin_vec;
+use thin_vec::{thin_vec, ThinVec};
 
 pub(super) struct Context<'cx, 'a> {
     // An optimization.
@@ -83,12 +83,12 @@ impl<'cx, 'a> Context<'cx, 'a> {
 
         let Self { best_case_captures, capture_decls, cx, local_bind_decls, span, .. } = self;
 
-        let mut assert_then_stmts = Vec::with_capacity(2);
+        let mut assert_then_stmts = ThinVec::with_capacity(2);
         assert_then_stmts.extend(best_case_captures);
         assert_then_stmts.push(self.cx.stmt_expr(panic));
         let assert_then = self.cx.block(span, assert_then_stmts);
 
-        let mut stmts = Vec::with_capacity(4);
+        let mut stmts = ThinVec::with_capacity(4);
         stmts.push(initial_imports);
         stmts.extend(capture_decls.into_iter().map(|c| c.decl));
         stmts.extend(local_bind_decls);
@@ -120,7 +120,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
                 thin_vec![self.cx.attr_nested_word(sym::allow, sym::unused_imports, self.span)],
                 ItemKind::Use(UseTree {
                     prefix: self.cx.path(self.span, self.cx.std_path(&[sym::asserting])),
-                    kind: UseTreeKind::Nested(vec![
+                    kind: UseTreeKind::Nested(thin_vec![
                         nested_tree(self, sym::TryCaptureGeneric),
                         nested_tree(self, sym::TryCapturePrintable),
                     ]),
@@ -136,7 +136,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
         self.cx.expr_call(
             self.span,
             self.cx.expr_path(self.cx.path(self.span, unlikely_path)),
-            vec![self.cx.expr(self.span, ExprKind::Unary(UnOp::Not, cond_expr))],
+            thin_vec![self.cx.expr(self.span, ExprKind::Unary(UnOp::Not, cond_expr))],
         )
     }
 
@@ -339,7 +339,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
         let init = self.cx.expr_call(
             self.span,
             self.cx.expr_path(self.cx.path(self.span, init_std_path)),
-            vec![],
+            ThinVec::new(),
         );
         let capture = Capture { decl: self.cx.stmt_let(self.span, true, ident, init), ident };
         self.capture_decls.push(capture);
@@ -366,7 +366,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
             self.cx.expr_path(
                 self.cx.path(self.span, self.cx.std_path(&[sym::asserting, sym::Wrapper])),
             ),
-            vec![self.cx.expr_path(Path::from_ident(local_bind))],
+            thin_vec![self.cx.expr_path(Path::from_ident(local_bind))],
         );
         let try_capture_call = self
             .cx
@@ -378,7 +378,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
                     ident: Ident::new(sym::try_capture, self.span),
                 },
                 expr_paren(self.cx, self.span, self.cx.expr_addr_of(self.span, wrapper)),
-                vec![expr_addr_of_mut(
+                thin_vec![expr_addr_of_mut(
                     self.cx,
                     self.span,
                     self.cx.expr_path(Path::from_ident(capture)),
@@ -389,7 +389,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
         let local_bind_path = self.cx.expr_path(Path::from_ident(local_bind));
         let rslt = if self.is_consumed {
             let ret = self.cx.stmt_expr(local_bind_path);
-            self.cx.expr_block(self.cx.block(self.span, vec![try_capture_call, ret]))
+            self.cx.expr_block(self.cx.block(self.span, thin_vec![try_capture_call, ret]))
         } else {
             self.best_case_captures.push(try_capture_call);
             local_bind_path
@@ -441,7 +441,7 @@ fn expr_method_call(
     cx: &ExtCtxt<'_>,
     seg: PathSegment,
     receiver: P<Expr>,
-    args: Vec<P<Expr>>,
+    args: ThinVec<P<Expr>>,
     span: Span,
 ) -> P<Expr> {
     cx.expr(span, ExprKind::MethodCall(Box::new(MethodCall { seg, receiver, args, span })))
diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs
index 42f50d8ade2..dfee2d3ce77 100644
--- a/compiler/rustc_builtin_macros/src/deriving/clone.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs
@@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_expand::base::{Annotatable, ExtCtxt};
 use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::Span;
-use thin_vec::thin_vec;
+use thin_vec::{thin_vec, ThinVec};
 
 pub fn expand_deriving_clone(
     cx: &mut ExtCtxt<'_>,
@@ -100,7 +100,7 @@ fn cs_clone_simple(
     substr: &Substructure<'_>,
     is_union: bool,
 ) -> BlockOrExpr {
-    let mut stmts = Vec::new();
+    let mut stmts = ThinVec::new();
     let mut seen_type_names = FxHashSet::default();
     let mut process_variant = |variant: &VariantData| {
         for field in variant.fields() {
@@ -162,7 +162,7 @@ fn cs_clone(
     let all_fields;
     let fn_path = cx.std_path(&[sym::clone, sym::Clone, sym::clone]);
     let subcall = |cx: &mut ExtCtxt<'_>, field: &FieldInfo| {
-        let args = vec![field.self_expr.clone()];
+        let args = thin_vec![field.self_expr.clone()];
         cx.expr_call_global(field.span, fn_path.clone(), args)
     };
 
@@ -200,7 +200,7 @@ fn cs_clone(
                     let call = subcall(cx, field);
                     cx.field_imm(field.span, ident, call)
                 })
-                .collect::<Vec<_>>();
+                .collect::<ThinVec<_>>();
 
             cx.expr_struct(trait_span, ctor_path, fields)
         }
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
index 424719f9795..af971958680 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
@@ -7,7 +7,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_expand::base::{Annotatable, ExtCtxt};
 use rustc_span::symbol::sym;
 use rustc_span::Span;
-use thin_vec::thin_vec;
+use thin_vec::{thin_vec, ThinVec};
 
 pub fn expand_deriving_eq(
     cx: &mut ExtCtxt<'_>,
@@ -56,7 +56,7 @@ fn cs_total_eq_assert(
     trait_span: Span,
     substr: &Substructure<'_>,
 ) -> BlockOrExpr {
-    let mut stmts = Vec::new();
+    let mut stmts = ThinVec::new();
     let mut seen_type_names = FxHashSet::default();
     let mut process_variant = |variant: &ast::VariantData| {
         for field in variant.fields() {
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
index 671f32550d2..cfd36f030a1 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
@@ -64,14 +64,14 @@ pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> Bl
                 let [other_expr] = &field.other_selflike_exprs[..] else {
                         cx.span_bug(field.span, "not exactly 2 arguments in `derive(Ord)`");
                     };
-                let args = vec![field.self_expr.clone(), other_expr.clone()];
+                let args = thin_vec![field.self_expr.clone(), other_expr.clone()];
                 cx.expr_call_global(field.span, cmp_path.clone(), args)
             }
             CsFold::Combine(span, expr1, expr2) => {
                 let eq_arm = cx.arm(span, cx.pat_path(span, equal_path.clone()), expr1);
                 let neq_arm =
                     cx.arm(span, cx.pat_ident(span, test_id), cx.expr_ident(span, test_id));
-                cx.expr_match(span, expr2, vec![eq_arm, neq_arm])
+                cx.expr_match(span, expr2, thin_vec![eq_arm, neq_arm])
             }
             CsFold::Fieldless => cx.expr_path(equal_path.clone()),
         },
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
index bcc90442eb7..9f46247908d 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
@@ -98,7 +98,7 @@ fn cs_partial_cmp(
                 let [other_expr] = &field.other_selflike_exprs[..] else {
                         cx.span_bug(field.span, "not exactly 2 arguments in `derive(Ord)`");
                     };
-                let args = vec![field.self_expr.clone(), other_expr.clone()];
+                let args = thin_vec![field.self_expr.clone(), other_expr.clone()];
                 cx.expr_call_global(field.span, partial_cmp_path.clone(), args)
             }
             CsFold::Combine(span, mut expr1, expr2) => {
@@ -143,7 +143,7 @@ fn cs_partial_cmp(
                         cx.arm(span, cx.pat_some(span, cx.pat_path(span, equal_path.clone())), expr1);
                     let neq_arm =
                         cx.arm(span, cx.pat_ident(span, test_id), cx.expr_ident(span, test_id));
-                    cx.expr_match(span, expr2, vec![eq_arm, neq_arm])
+                    cx.expr_match(span, expr2, thin_vec![eq_arm, neq_arm])
                 }
             }
             CsFold::Fieldless => cx.expr_some(span, cx.expr_path(equal_path.clone())),
diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs
index d30e8ba4b93..809f9838d20 100644
--- a/compiler/rustc_builtin_macros/src/deriving/debug.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs
@@ -7,6 +7,7 @@ use rustc_ast::{self as ast, MetaItem};
 use rustc_expand::base::{Annotatable, ExtCtxt};
 use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
+use thin_vec::{thin_vec, ThinVec};
 
 pub fn expand_deriving_debug(
     cx: &mut ExtCtxt<'_>,
@@ -94,7 +95,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
     if fields.is_empty() {
         // Special case for no fields.
         let fn_path_write_str = cx.std_path(&[sym::fmt, sym::Formatter, sym::write_str]);
-        let expr = cx.expr_call_global(span, fn_path_write_str, vec![fmt, name]);
+        let expr = cx.expr_call_global(span, fn_path_write_str, thin_vec![fmt, name]);
         BlockOrExpr::new_expr(expr)
     } else if fields.len() <= CUTOFF {
         // Few enough fields that we can use a specific-length method.
@@ -105,7 +106,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
         };
         let fn_path_debug = cx.std_path(&[sym::fmt, sym::Formatter, Symbol::intern(&debug)]);
 
-        let mut args = Vec::with_capacity(2 + fields.len() * args_per_field);
+        let mut args = ThinVec::with_capacity(2 + fields.len() * args_per_field);
         args.extend([fmt, name]);
         for i in 0..fields.len() {
             let field = &fields[i];
@@ -121,8 +122,8 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
         BlockOrExpr::new_expr(expr)
     } else {
         // Enough fields that we must use the any-length method.
-        let mut name_exprs = Vec::with_capacity(fields.len());
-        let mut value_exprs = Vec::with_capacity(fields.len());
+        let mut name_exprs = ThinVec::with_capacity(fields.len());
+        let mut value_exprs = ThinVec::with_capacity(fields.len());
 
         for i in 0..fields.len() {
             let field = &fields[i];
@@ -177,7 +178,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
         };
         let fn_path_debug_internal = cx.std_path(&[sym::fmt, sym::Formatter, sym_debug]);
 
-        let mut args = Vec::with_capacity(4);
+        let mut args = ThinVec::with_capacity(4);
         args.push(fmt);
         args.push(name);
         if is_struct {
@@ -186,7 +187,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
         args.push(cx.expr_ident(span, Ident::new(sym::values, span)));
         let expr = cx.expr_call_global(span, fn_path_debug_internal, args);
 
-        let mut stmts = Vec::with_capacity(3);
+        let mut stmts = ThinVec::with_capacity(2);
         if is_struct {
             stmts.push(names_let.unwrap());
         }
@@ -223,18 +224,18 @@ fn show_fieldless_enum(
             let pat = match &v.data {
                 ast::VariantData::Tuple(fields, _) => {
                     debug_assert!(fields.is_empty());
-                    cx.pat_tuple_struct(span, variant_path, vec![])
+                    cx.pat_tuple_struct(span, variant_path, ThinVec::new())
                 }
                 ast::VariantData::Struct(fields, _) => {
                     debug_assert!(fields.is_empty());
-                    cx.pat_struct(span, variant_path, vec![])
+                    cx.pat_struct(span, variant_path, ThinVec::new())
                 }
                 ast::VariantData::Unit(_) => cx.pat_path(span, variant_path),
             };
             cx.arm(span, pat, cx.expr_str(span, v.ident.name))
         })
-        .collect::<Vec<_>>();
+        .collect::<ThinVec<_>>();
     let name = cx.expr_match(span, cx.expr_self(span), arms);
     let fn_path_write_str = cx.std_path(&[sym::fmt, sym::Formatter, sym::write_str]);
-    BlockOrExpr::new_expr(cx.expr_call_global(span, fn_path_write_str, vec![fmt, name]))
+    BlockOrExpr::new_expr(cx.expr_call_global(span, fn_path_write_str, thin_vec![fmt, name]))
 }
diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
index c783e46eda9..3921533c84a 100644
--- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
@@ -3,12 +3,12 @@
 use crate::deriving::generic::ty::*;
 use crate::deriving::generic::*;
 use crate::deriving::pathvec_std;
-
 use rustc_ast::ptr::P;
 use rustc_ast::{self as ast, Expr, MetaItem, Mutability};
 use rustc_expand::base::{Annotatable, ExtCtxt};
 use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
+use thin_vec::{thin_vec, ThinVec};
 
 pub fn expand_deriving_rustc_decodable(
     cx: &mut ExtCtxt<'_>,
@@ -96,7 +96,7 @@ fn decodable_substructure(
                         cx.expr_call_global(
                             span,
                             fn_read_struct_field_path.clone(),
-                            vec![
+                            thin_vec![
                                 blkdecoder.clone(),
                                 cx.expr_str(span, name),
                                 cx.expr_usize(span, field),
@@ -112,7 +112,7 @@ fn decodable_substructure(
             cx.expr_call_global(
                 trait_span,
                 fn_read_struct_path,
-                vec![
+                thin_vec![
                     decoder,
                     cx.expr_str(trait_span, substr.type_ident.name),
                     cx.expr_usize(trait_span, nfields),
@@ -123,8 +123,8 @@ fn decodable_substructure(
         StaticEnum(_, fields) => {
             let variant = Ident::new(sym::i, trait_span);
 
-            let mut arms = Vec::with_capacity(fields.len() + 1);
-            let mut variants = Vec::with_capacity(fields.len());
+            let mut arms = ThinVec::with_capacity(fields.len() + 1);
+            let mut variants = ThinVec::with_capacity(fields.len());
 
             let fn_read_enum_variant_arg_path: Vec<_> =
                 cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_enum_variant_arg]);
@@ -141,7 +141,7 @@ fn decodable_substructure(
                             cx.expr_call_global(
                                 span,
                                 fn_read_enum_variant_arg_path.clone(),
-                                vec![blkdecoder.clone(), idx, exprdecode.clone()],
+                                thin_vec![blkdecoder.clone(), idx, exprdecode.clone()],
                             ),
                         )
                     });
@@ -162,7 +162,7 @@ fn decodable_substructure(
             let result = cx.expr_call_global(
                 trait_span,
                 fn_read_enum_variant_path,
-                vec![blkdecoder, variant_array_ref, lambda],
+                thin_vec![blkdecoder, variant_array_ref, lambda],
             );
             let fn_read_enum_path: Vec<_> =
                 cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_enum]);
@@ -170,7 +170,7 @@ fn decodable_substructure(
             cx.expr_call_global(
                 trait_span,
                 fn_read_enum_path,
-                vec![
+                thin_vec![
                     decoder,
                     cx.expr_str(trait_span, substr.type_ident.name),
                     cx.lambda1(trait_span, result, blkarg),
diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index a6c8b111527..4d753a2ed80 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -8,7 +8,7 @@ use rustc_span::symbol::Ident;
 use rustc_span::symbol::{kw, sym};
 use rustc_span::Span;
 use smallvec::SmallVec;
-use thin_vec::thin_vec;
+use thin_vec::{thin_vec, ThinVec};
 
 pub fn expand_deriving_default(
     cx: &mut ExtCtxt<'_>,
@@ -60,7 +60,7 @@ fn default_struct_substructure(
 ) -> BlockOrExpr {
     // Note that `kw::Default` is "default" and `sym::Default` is "Default"!
     let default_ident = cx.std_path(&[kw::Default, sym::Default, kw::Default]);
-    let default_call = |span| cx.expr_call_global(span, default_ident.clone(), Vec::new());
+    let default_call = |span| cx.expr_call_global(span, default_ident.clone(), ThinVec::new());
 
     let expr = match summary {
         Unnamed(_, false) => cx.expr_ident(trait_span, substr.type_ident),
diff --git a/compiler/rustc_builtin_macros/src/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
index a5e2b599df4..a3b11309d0c 100644
--- a/compiler/rustc_builtin_macros/src/deriving/encodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
@@ -88,11 +88,11 @@
 use crate::deriving::generic::ty::*;
 use crate::deriving::generic::*;
 use crate::deriving::pathvec_std;
-
 use rustc_ast::{AttrVec, ExprKind, MetaItem, Mutability};
 use rustc_expand::base::{Annotatable, ExtCtxt};
 use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
+use thin_vec::{thin_vec, ThinVec};
 
 pub fn expand_deriving_rustc_encodable(
     cx: &mut ExtCtxt<'_>,
@@ -169,19 +169,20 @@ fn encodable_substructure(
         Struct(_, fields) => {
             let fn_emit_struct_field_path =
                 cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_struct_field]);
-            let mut stmts = Vec::new();
+            let mut stmts = ThinVec::new();
             for (i, &FieldInfo { name, ref self_expr, span, .. }) in fields.iter().enumerate() {
                 let name = match name {
                     Some(id) => id.name,
                     None => Symbol::intern(&format!("_field{}", i)),
                 };
                 let self_ref = cx.expr_addr_of(span, self_expr.clone());
-                let enc = cx.expr_call(span, fn_path.clone(), vec![self_ref, blkencoder.clone()]);
+                let enc =
+                    cx.expr_call(span, fn_path.clone(), thin_vec![self_ref, blkencoder.clone()]);
                 let lambda = cx.lambda1(span, enc, blkarg);
                 let call = cx.expr_call_global(
                     span,
                     fn_emit_struct_field_path.clone(),
-                    vec![
+                    thin_vec![
                         blkencoder.clone(),
                         cx.expr_str(span, name),
                         cx.expr_usize(span, i),
@@ -203,7 +204,7 @@ fn encodable_substructure(
 
             // unit structs have no fields and need to return Ok()
             let blk = if stmts.is_empty() {
-                let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, vec![]));
+                let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, ThinVec::new()));
                 cx.lambda1(trait_span, ok, blkarg)
             } else {
                 cx.lambda_stmts_1(trait_span, stmts, blkarg)
@@ -215,7 +216,7 @@ fn encodable_substructure(
             let expr = cx.expr_call_global(
                 trait_span,
                 fn_emit_struct_path,
-                vec![
+                thin_vec![
                     encoder,
                     cx.expr_str(trait_span, substr.type_ident.name),
                     cx.expr_usize(trait_span, fields.len()),
@@ -236,19 +237,22 @@ fn encodable_substructure(
             let fn_emit_enum_variant_arg_path: Vec<_> =
                 cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_enum_variant_arg]);
 
-            let mut stmts = Vec::new();
+            let mut stmts = ThinVec::new();
             if !fields.is_empty() {
                 let last = fields.len() - 1;
                 for (i, &FieldInfo { ref self_expr, span, .. }) in fields.iter().enumerate() {
                     let self_ref = cx.expr_addr_of(span, self_expr.clone());
-                    let enc =
-                        cx.expr_call(span, fn_path.clone(), vec![self_ref, blkencoder.clone()]);
+                    let enc = cx.expr_call(
+                        span,
+                        fn_path.clone(),
+                        thin_vec![self_ref, blkencoder.clone()],
+                    );
                     let lambda = cx.lambda1(span, enc, blkarg);
 
                     let call = cx.expr_call_global(
                         span,
                         fn_emit_enum_variant_arg_path.clone(),
-                        vec![blkencoder.clone(), cx.expr_usize(span, i), lambda],
+                        thin_vec![blkencoder.clone(), cx.expr_usize(span, i), lambda],
                     );
                     let call = if i != last {
                         cx.expr_try(span, call)
@@ -258,7 +262,7 @@ fn encodable_substructure(
                     stmts.push(cx.stmt_expr(call));
                 }
             } else {
-                let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, vec![]));
+                let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, ThinVec::new()));
                 let ret_ok = cx.expr(trait_span, ExprKind::Ret(Some(ok)));
                 stmts.push(cx.stmt_expr(ret_ok));
             }
@@ -272,7 +276,7 @@ fn encodable_substructure(
             let call = cx.expr_call_global(
                 trait_span,
                 fn_emit_enum_variant_path,
-                vec![
+                thin_vec![
                     blkencoder,
                     name,
                     cx.expr_usize(trait_span, *idx),
@@ -287,9 +291,9 @@ fn encodable_substructure(
             let expr = cx.expr_call_global(
                 trait_span,
                 fn_emit_enum_path,
-                vec![encoder, cx.expr_str(trait_span, substr.type_ident.name), blk],
+                thin_vec![encoder, cx.expr_str(trait_span, substr.type_ident.name), blk],
             );
-            BlockOrExpr::new_mixed(vec![me], Some(expr))
+            BlockOrExpr::new_mixed(thin_vec![me], Some(expr))
         }
 
         _ => cx.bug("expected Struct or EnumMatching in derive(Encodable)"),
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 38878ba7012..1f819beeb5d 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -177,7 +177,7 @@ use std::cell::RefCell;
 use std::iter;
 use std::ops::Not;
 use std::vec;
-use thin_vec::thin_vec;
+use thin_vec::{thin_vec, ThinVec};
 use ty::{Bounds, Path, Ref, Self_, Ty};
 
 pub mod ty;
@@ -318,7 +318,7 @@ pub fn combine_substructure(
 }
 
 struct TypeParameter {
-    bound_generic_params: Vec<ast::GenericParam>,
+    bound_generic_params: ThinVec<ast::GenericParam>,
     ty: P<ast::Ty>,
 }
 
@@ -328,18 +328,18 @@ struct TypeParameter {
 /// avoiding the insertion of any unnecessary blocks.
 ///
 /// The statements come before the expression.
-pub struct BlockOrExpr(Vec<ast::Stmt>, Option<P<Expr>>);
+pub struct BlockOrExpr(ThinVec<ast::Stmt>, Option<P<Expr>>);
 
 impl BlockOrExpr {
-    pub fn new_stmts(stmts: Vec<ast::Stmt>) -> BlockOrExpr {
+    pub fn new_stmts(stmts: ThinVec<ast::Stmt>) -> BlockOrExpr {
         BlockOrExpr(stmts, None)
     }
 
     pub fn new_expr(expr: P<Expr>) -> BlockOrExpr {
-        BlockOrExpr(vec![], Some(expr))
+        BlockOrExpr(ThinVec::new(), Some(expr))
     }
 
-    pub fn new_mixed(stmts: Vec<ast::Stmt>, expr: Option<P<Expr>>) -> BlockOrExpr {
+    pub fn new_mixed(stmts: ThinVec<ast::Stmt>, expr: Option<P<Expr>>) -> BlockOrExpr {
         BlockOrExpr(stmts, expr)
     }
 
@@ -355,7 +355,7 @@ impl BlockOrExpr {
     fn into_expr(self, cx: &ExtCtxt<'_>, span: Span) -> P<Expr> {
         if self.0.is_empty() {
             match self.1 {
-                None => cx.expr_block(cx.block(span, vec![])),
+                None => cx.expr_block(cx.block(span, ThinVec::new())),
                 Some(expr) => expr,
             }
         } else if self.0.len() == 1
@@ -385,7 +385,7 @@ fn find_type_parameters(
     struct Visitor<'a, 'b> {
         cx: &'a ExtCtxt<'b>,
         ty_param_names: &'a [Symbol],
-        bound_generic_params_stack: Vec<ast::GenericParam>,
+        bound_generic_params_stack: ThinVec<ast::GenericParam>,
         type_params: Vec<TypeParameter>,
     }
 
@@ -422,7 +422,7 @@ fn find_type_parameters(
     let mut visitor = Visitor {
         cx,
         ty_param_names,
-        bound_generic_params_stack: Vec::new(),
+        bound_generic_params_stack: ThinVec::new(),
         type_params: Vec::new(),
     };
     visit::Visitor::visit_ty(&mut visitor, ty);
@@ -594,7 +594,7 @@ impl<'a> TraitDef<'a> {
         let span = generics.span.with_ctxt(ctxt);
 
         // Create the generic parameters
-        let params: Vec<_> = generics
+        let params: ThinVec<_> = generics
             .params
             .iter()
             .map(|param| match &param.kind {
@@ -935,8 +935,8 @@ impl<'a> MethodDef<'a> {
         trait_: &TraitDef<'_>,
         type_ident: Ident,
         generics: &Generics,
-    ) -> (Option<ast::ExplicitSelf>, Vec<P<Expr>>, Vec<P<Expr>>, Vec<(Ident, P<ast::Ty>)>) {
-        let mut selflike_args = Vec::new();
+    ) -> (Option<ast::ExplicitSelf>, ThinVec<P<Expr>>, Vec<P<Expr>>, Vec<(Ident, P<ast::Ty>)>) {
+        let mut selflike_args = ThinVec::new();
         let mut nonselflike_args = Vec::new();
         let mut nonself_arg_tys = Vec::new();
         let span = trait_.span;
@@ -1133,7 +1133,7 @@ impl<'a> MethodDef<'a> {
         trait_: &TraitDef<'b>,
         enum_def: &'b EnumDef,
         type_ident: Ident,
-        selflike_args: Vec<P<Expr>>,
+        selflike_args: ThinVec<P<Expr>>,
         nonselflike_args: &[P<Expr>],
     ) -> BlockOrExpr {
         let span = trait_.span;
@@ -1146,7 +1146,7 @@ impl<'a> MethodDef<'a> {
         // There is no sensible code to be generated for *any* deriving on a
         // zero-variant enum. So we just generate a failing expression.
         if variants.is_empty() {
-            return BlockOrExpr(vec![], Some(deriving::call_unreachable(cx, span)));
+            return BlockOrExpr(ThinVec::new(), Some(deriving::call_unreachable(cx, span)));
         }
 
         let prefixes = iter::once("__self".to_string())
@@ -1182,13 +1182,13 @@ impl<'a> MethodDef<'a> {
             let other_selflike_exprs = tag_exprs;
             let tag_field = FieldInfo { span, name: None, self_expr, other_selflike_exprs };
 
-            let tag_let_stmts: Vec<_> = iter::zip(&tag_idents, &selflike_args)
+            let tag_let_stmts: ThinVec<_> = iter::zip(&tag_idents, &selflike_args)
                 .map(|(&ident, selflike_arg)| {
                     let variant_value = deriving::call_intrinsic(
                         cx,
                         span,
                         sym::discriminant_value,
-                        vec![selflike_arg.clone()],
+                        thin_vec![selflike_arg.clone()],
                     );
                     cx.stmt_let(span, false, ident, variant_value)
                 })
@@ -1247,7 +1247,7 @@ impl<'a> MethodDef<'a> {
         // (Variant2, Variant2, ...) => Body2
         // ...
         // where each tuple has length = selflike_args.len()
-        let mut match_arms: Vec<ast::Arm> = variants
+        let mut match_arms: ThinVec<ast::Arm> = variants
             .iter()
             .enumerate()
             .filter(|&(_, v)| !(unify_fieldless_variants && v.data.fields().is_empty()))
@@ -1260,7 +1260,7 @@ impl<'a> MethodDef<'a> {
                 let sp = variant.span.with_ctxt(trait_.span.ctxt());
                 let variant_path = cx.path(sp, vec![type_ident, variant.ident]);
                 let by_ref = ByRef::No; // because enums can't be repr(packed)
-                let mut subpats: Vec<_> = trait_.create_struct_patterns(
+                let mut subpats = trait_.create_struct_patterns(
                     cx,
                     variant_path,
                     &variant.data,
@@ -1336,7 +1336,7 @@ impl<'a> MethodDef<'a> {
         //          ...
         //          _ => ::core::intrinsics::unreachable()
         //      }
-        let get_match_expr = |mut selflike_args: Vec<P<Expr>>| {
+        let get_match_expr = |mut selflike_args: ThinVec<P<Expr>>| {
             let match_arg = if selflike_args.len() == 1 {
                 selflike_args.pop().unwrap()
             } else {
@@ -1362,7 +1362,7 @@ impl<'a> MethodDef<'a> {
             tag_let_stmts.append(&mut tag_check_plus_match.0);
             BlockOrExpr(tag_let_stmts, tag_check_plus_match.1)
         } else {
-            BlockOrExpr(vec![], Some(get_match_expr(selflike_args)))
+            BlockOrExpr(ThinVec::new(), Some(get_match_expr(selflike_args)))
         }
     }
 
@@ -1427,7 +1427,7 @@ impl<'a> TraitDef<'a> {
         struct_def: &'a VariantData,
         prefixes: &[String],
         by_ref: ByRef,
-    ) -> Vec<P<ast::Pat>> {
+    ) -> ThinVec<P<ast::Pat>> {
         prefixes
             .iter()
             .map(|prefix| {
@@ -1599,7 +1599,7 @@ impl<'a> TraitDef<'a> {
                         } else {
                             // Wrap the expression in `{...}`, causing a copy.
                             field_expr = cx.expr_block(
-                                cx.block(struct_field.span, vec![cx.stmt_expr(field_expr)]),
+                                cx.block(struct_field.span, thin_vec![cx.stmt_expr(field_expr)]),
                             );
                         }
                     }
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
index aabd5b1f773..26f91b714b4 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
@@ -9,6 +9,7 @@ use rustc_expand::base::ExtCtxt;
 use rustc_span::source_map::{respan, DUMMY_SP};
 use rustc_span::symbol::{kw, Ident, Symbol};
 use rustc_span::Span;
+use thin_vec::ThinVec;
 
 /// A path, e.g., `::std::option::Option::<i32>` (global). Has support
 /// for type parameters.
@@ -102,7 +103,7 @@ impl Ty {
             Path(p) => p.to_ty(cx, span, self_ty, self_generics),
             Self_ => cx.ty_path(self.to_path(cx, span, self_ty, self_generics)),
             Unit => {
-                let ty = ast::TyKind::Tup(vec![]);
+                let ty = ast::TyKind::Tup(ThinVec::new());
                 cx.ty(span, ty)
             }
         }
@@ -185,7 +186,11 @@ impl Bounds {
 
         Generics {
             params,
-            where_clause: ast::WhereClause { has_where_token: false, predicates: Vec::new(), span },
+            where_clause: ast::WhereClause {
+                has_where_token: false,
+                predicates: ThinVec::new(),
+                span,
+            },
             span,
         }
     }
diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs
index 5c2e89c5697..4eee573db42 100644
--- a/compiler/rustc_builtin_macros/src/deriving/hash.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs
@@ -1,11 +1,11 @@
 use crate::deriving::generic::ty::*;
 use crate::deriving::generic::*;
 use crate::deriving::{path_std, pathvec_std};
-
 use rustc_ast::{AttrVec, MetaItem, Mutability};
 use rustc_expand::base::{Annotatable, ExtCtxt};
 use rustc_span::symbol::sym;
 use rustc_span::Span;
+use thin_vec::thin_vec;
 
 pub fn expand_deriving_hash(
     cx: &mut ExtCtxt<'_>,
@@ -60,7 +60,7 @@ fn hash_substructure(
 
             cx.expr_path(cx.path_global(span, strs))
         };
-        let expr = cx.expr_call(span, hash_path, vec![expr, state_expr.clone()]);
+        let expr = cx.expr_call(span, hash_path, thin_vec![expr, state_expr.clone()]);
         cx.stmt_expr(expr)
     };
 
@@ -72,7 +72,7 @@ fn hash_substructure(
         }
         EnumTag(tag_field, match_expr) => {
             assert!(tag_field.other_selflike_exprs.is_empty());
-            let stmts = vec![call_hash(tag_field.span, tag_field.self_expr.clone())];
+            let stmts = thin_vec![call_hash(tag_field.span, tag_field.self_expr.clone())];
             (stmts, match_expr.clone())
         }
         _ => cx.span_bug(trait_span, "impossible substructure in `derive(Hash)`"),
diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs
index de657e4e600..d34336e7679 100644
--- a/compiler/rustc_builtin_macros/src/deriving/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs
@@ -6,6 +6,7 @@ use rustc_ast::{GenericArg, Impl, ItemKind, MetaItem};
 use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier};
 use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
+use thin_vec::{thin_vec, ThinVec};
 
 macro path_local($x:ident) {
     generic::ty::Path::new_local(sym::$x)
@@ -92,7 +93,7 @@ fn call_intrinsic(
     cx: &ExtCtxt<'_>,
     span: Span,
     intrinsic: Symbol,
-    args: Vec<P<ast::Expr>>,
+    args: ThinVec<P<ast::Expr>>,
 ) -> P<ast::Expr> {
     let span = cx.with_def_site_ctxt(span);
     let path = cx.std_path(&[sym::intrinsics, intrinsic]);
@@ -103,10 +104,10 @@ fn call_intrinsic(
 fn call_unreachable(cx: &ExtCtxt<'_>, span: Span) -> P<ast::Expr> {
     let span = cx.with_def_site_ctxt(span);
     let path = cx.std_path(&[sym::intrinsics, sym::unreachable]);
-    let call = cx.expr_call_global(span, path, vec![]);
+    let call = cx.expr_call_global(span, path, ThinVec::new());
 
     cx.expr_block(P(ast::Block {
-        stmts: vec![cx.stmt_expr(call)],
+        stmts: thin_vec![cx.stmt_expr(call)],
         id: ast::DUMMY_NODE_ID,
         rules: ast::BlockCheckMode::Unsafe(ast::CompilerGenerated),
         span,
@@ -202,7 +203,7 @@ fn inject_impl_of_structural_trait(
             generics,
             of_trait: Some(trait_ref),
             self_ty: self_type,
-            items: Vec::new(),
+            items: ThinVec::new(),
         })),
     );
 
@@ -211,7 +212,7 @@ fn inject_impl_of_structural_trait(
 
 fn assert_ty_bounds(
     cx: &mut ExtCtxt<'_>,
-    stmts: &mut Vec<ast::Stmt>,
+    stmts: &mut ThinVec<ast::Stmt>,
     ty: P<ast::Ty>,
     span: Span,
     assert_path: &[Symbol],
diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs
index e5a5e606930..6aa900f0201 100644
--- a/compiler/rustc_builtin_macros/src/env.rs
+++ b/compiler/rustc_builtin_macros/src/env.rs
@@ -8,8 +8,8 @@ use rustc_ast::{self as ast, GenericArg};
 use rustc_expand::base::{self, *};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
-
 use std::env;
+use thin_vec::thin_vec;
 
 pub fn expand_option_env<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
@@ -41,7 +41,7 @@ pub fn expand_option_env<'cx>(
         Some(value) => cx.expr_call_global(
             sp,
             cx.std_path(&[sym::option, sym::Option, sym::Some]),
-            vec![cx.expr_str(sp, value)],
+            thin_vec![cx.expr_str(sp, value)],
         ),
     };
     MacEager::expr(e)
diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs
index f8761653bf5..41b51bae736 100644
--- a/compiler/rustc_builtin_macros/src/global_allocator.rs
+++ b/compiler/rustc_builtin_macros/src/global_allocator.rs
@@ -9,7 +9,7 @@ use rustc_ast::{Fn, ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe};
 use rustc_expand::base::{Annotatable, ExtCtxt};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
-use thin_vec::thin_vec;
+use thin_vec::{thin_vec, ThinVec};
 
 pub fn expand(
     ecx: &mut ExtCtxt<'_>,
@@ -47,7 +47,7 @@ pub fn expand(
     let stmts = ALLOCATOR_METHODS.iter().map(|method| f.allocator_fn(method)).collect();
 
     // Generate anonymous constant serving as container for the allocator methods.
-    let const_ty = ecx.ty(ty_span, TyKind::Tup(Vec::new()));
+    let const_ty = ecx.ty(ty_span, TyKind::Tup(ThinVec::new()));
     let const_body = ecx.expr_block(ecx.block(span, stmts));
     let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body);
     let const_item = if is_stmt {
@@ -70,7 +70,7 @@ struct AllocFnFactory<'a, 'b> {
 
 impl AllocFnFactory<'_, '_> {
     fn allocator_fn(&self, method: &AllocatorMethod) -> Stmt {
-        let mut abi_args = Vec::new();
+        let mut abi_args = ThinVec::new();
         let mut i = 0;
         let mut mk = || {
             let name = Ident::from_str_and_span(&format!("arg{}", i), self.span);
@@ -99,7 +99,7 @@ impl AllocFnFactory<'_, '_> {
         self.cx.stmt_item(self.ty_span, item)
     }
 
-    fn call_allocator(&self, method: Symbol, mut args: Vec<P<Expr>>) -> P<Expr> {
+    fn call_allocator(&self, method: Symbol, mut args: ThinVec<P<Expr>>) -> P<Expr> {
         let method = self.cx.std_path(&[sym::alloc, sym::GlobalAlloc, method]);
         let method = self.cx.expr_path(self.cx.path(self.ty_span, method));
         let allocator = self.cx.path_ident(self.ty_span, self.global);
@@ -117,7 +117,7 @@ impl AllocFnFactory<'_, '_> {
     fn arg_ty(
         &self,
         ty: &AllocatorTy,
-        args: &mut Vec<Param>,
+        args: &mut ThinVec<Param>,
         ident: &mut dyn FnMut() -> Ident,
     ) -> P<Expr> {
         match *ty {
@@ -134,7 +134,7 @@ impl AllocFnFactory<'_, '_> {
                 let layout_new = self.cx.expr_path(self.cx.path(self.span, layout_new));
                 let size = self.cx.expr_ident(self.span, size);
                 let align = self.cx.expr_ident(self.span, align);
-                let layout = self.cx.expr_call(self.span, layout_new, vec![size, align]);
+                let layout = self.cx.expr_call(self.span, layout_new, thin_vec![size, align]);
                 layout
             }
 
@@ -168,7 +168,7 @@ impl AllocFnFactory<'_, '_> {
                 (self.ptr_u8(), expr)
             }
 
-            AllocatorTy::Unit => (self.cx.ty(self.span, TyKind::Tup(Vec::new())), expr),
+            AllocatorTy::Unit => (self.cx.ty(self.span, TyKind::Tup(ThinVec::new())), expr),
 
             AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
                 panic!("can't convert `AllocatorTy` to an output")
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 75cfac72384..8afb6e56069 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -21,8 +21,10 @@ extern crate tracing;
 
 use crate::deriving::*;
 
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
 use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind};
 use rustc_expand::proc_macro::BangProcMacro;
+use rustc_macros::fluent_messages;
 use rustc_span::symbol::sym;
 
 mod alloc_error_handler;
@@ -54,6 +56,8 @@ pub mod proc_macro_harness;
 pub mod standard_library_imports;
 pub mod test_harness;
 
+fluent_messages! { "../locales/en-US.ftl" }
+
 pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
     let mut register = |name, kind| resolver.register_builtin_macro(name, kind);
     macro register_bang($($name:ident: $f:expr,)*) {
diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
index 21c8caa658f..bc513607ddd 100644
--- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
+++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
@@ -11,6 +11,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 use smallvec::smallvec;
 use std::mem;
+use thin_vec::{thin_vec, ThinVec};
 
 struct ProcMacroDerive {
     id: NodeId,
@@ -314,11 +315,14 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
                     cx.expr_call(
                         span,
                         proc_macro_ty_method_path(cx, custom_derive),
-                        vec![
+                        thin_vec![
                             cx.expr_str(span, cd.trait_name),
                             cx.expr_array_ref(
                                 span,
-                                cd.attrs.iter().map(|&s| cx.expr_str(span, s)).collect::<Vec<_>>(),
+                                cd.attrs
+                                    .iter()
+                                    .map(|&s| cx.expr_str(span, s))
+                                    .collect::<ThinVec<_>>(),
                             ),
                             local_path(cx, cd.function_name),
                         ],
@@ -335,7 +339,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
                     cx.expr_call(
                         span,
                         proc_macro_ty_method_path(cx, ident),
-                        vec![
+                        thin_vec![
                             cx.expr_str(span, ca.function_name.name),
                             local_path(cx, ca.function_name),
                         ],
@@ -371,13 +375,13 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
         });
 
     let block = cx.expr_block(
-        cx.block(span, vec![cx.stmt_item(span, krate), cx.stmt_item(span, decls_static)]),
+        cx.block(span, thin_vec![cx.stmt_item(span, krate), cx.stmt_item(span, decls_static)]),
     );
 
     let anon_constant = cx.item_const(
         span,
         Ident::new(kw::Underscore, span),
-        cx.ty(span, ast::TyKind::Tup(Vec::new())),
+        cx.ty(span, ast::TyKind::Tup(ThinVec::new())),
         block,
     );
 
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index 729ae4071e2..e02c7e6c01b 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -10,7 +10,7 @@ use rustc_session::Session;
 use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
 use std::iter;
-use thin_vec::thin_vec;
+use thin_vec::{thin_vec, ThinVec};
 
 /// #[test_case] is used by custom test authors to mark tests
 /// When building for test, it needs to make the item public and gensym the name
@@ -179,19 +179,19 @@ pub fn expand_test_or_bench(
         cx.expr_call(
             sp,
             cx.expr_path(test_path("StaticBenchFn")),
-            vec![
+            thin_vec![
                 // |b| self::test::assert_test_result(
                 cx.lambda1(
                     sp,
                     cx.expr_call(
                         sp,
                         cx.expr_path(test_path("assert_test_result")),
-                        vec![
+                        thin_vec![
                             // super::$test_fn(b)
                             cx.expr_call(
                                 ret_ty_sp,
                                 cx.expr_path(cx.path(sp, vec![item.ident])),
-                                vec![cx.expr_ident(sp, b)],
+                                thin_vec![cx.expr_ident(sp, b)],
                             ),
                         ],
                     ),
@@ -203,7 +203,7 @@ pub fn expand_test_or_bench(
         cx.expr_call(
             sp,
             cx.expr_path(test_path("StaticTestFn")),
-            vec![
+            thin_vec![
                 // || {
                 cx.lambda0(
                     sp,
@@ -211,12 +211,12 @@ pub fn expand_test_or_bench(
                     cx.expr_call(
                         sp,
                         cx.expr_path(test_path("assert_test_result")),
-                        vec![
+                        thin_vec![
                             // $test_fn()
                             cx.expr_call(
                                 ret_ty_sp,
                                 cx.expr_path(cx.path(sp, vec![item.ident])),
-                                vec![],
+                                ThinVec::new(),
                             ), // )
                         ],
                     ), // }
@@ -249,21 +249,21 @@ pub fn expand_test_or_bench(
                 cx.expr_struct(
                     sp,
                     test_path("TestDescAndFn"),
-                    vec![
+                    thin_vec![
                         // desc: test::TestDesc {
                         field(
                             "desc",
                             cx.expr_struct(
                                 sp,
                                 test_path("TestDesc"),
-                                vec![
+                                thin_vec![
                                     // name: "path::to::test"
                                     field(
                                         "name",
                                         cx.expr_call(
                                             sp,
                                             cx.expr_path(test_path("StaticTestName")),
-                                            vec![cx.expr_str(sp, test_path_symbol)],
+                                            thin_vec![cx.expr_str(sp, test_path_symbol)],
                                         ),
                                     ),
                                     // ignore: true | false
@@ -300,7 +300,7 @@ pub fn expand_test_or_bench(
                                             ShouldPanic::Yes(Some(sym)) => cx.expr_call(
                                                 sp,
                                                 cx.expr_path(should_panic_path("YesWithMessage")),
-                                                vec![cx.expr_str(sp, sym)],
+                                                thin_vec![cx.expr_str(sp, sym)],
                                             ),
                                         },
                                     ),
diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index ad887108091..d8e3db9e8ee 100644
--- a/compiler/rustc_builtin_macros/src/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
@@ -14,7 +14,8 @@ use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::spec::PanicStrategy;
 use smallvec::{smallvec, SmallVec};
-use thin_vec::thin_vec;
+use thin_vec::{thin_vec, ThinVec};
+use tracing::debug;
 
 use std::{iter, mem};
 
@@ -299,7 +300,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
     test_runner.span = sp;
 
     let test_main_path_expr = ecx.expr_path(test_runner);
-    let call_test_main = ecx.expr_call(sp, test_main_path_expr, vec![mk_tests_slice(cx, sp)]);
+    let call_test_main = ecx.expr_call(sp, test_main_path_expr, thin_vec![mk_tests_slice(cx, sp)]);
     let call_test_main = ecx.stmt_expr(call_test_main);
 
     // extern crate test
@@ -312,16 +313,16 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
     let main_attr = ecx.attr_word(sym::rustc_main, sp);
 
     // pub fn main() { ... }
-    let main_ret_ty = ecx.ty(sp, ast::TyKind::Tup(vec![]));
+    let main_ret_ty = ecx.ty(sp, ast::TyKind::Tup(ThinVec::new()));
 
     // If no test runner is provided we need to import the test crate
     let main_body = if cx.test_runner.is_none() {
-        ecx.block(sp, vec![test_extern_stmt, call_test_main])
+        ecx.block(sp, thin_vec![test_extern_stmt, call_test_main])
     } else {
-        ecx.block(sp, vec![call_test_main])
+        ecx.block(sp, thin_vec![call_test_main])
     };
 
-    let decl = ecx.fn_decl(vec![], ast::FnRetTy::Ty(main_ret_ty));
+    let decl = ecx.fn_decl(ThinVec::new(), ast::FnRetTy::Ty(main_ret_ty));
     let sig = ast::FnSig { decl, header: ast::FnHeader::default(), span: sp };
     let defaultness = ast::Defaultness::Final;
     let main = ast::ItemKind::Fn(Box::new(ast::Fn {
diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
index 3c34585d419..74396a66f54 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
@@ -405,9 +405,9 @@ pub(crate) fn codegen_terminator_call<'tcx>(
     };
 
     let extra_args = &args[fn_sig.inputs().skip_binder().len()..];
-    let extra_args = fx
-        .tcx
-        .mk_type_list(extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx))));
+    let extra_args = fx.tcx.mk_type_list_from_iter(
+        extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx))),
+    );
     let fn_abi = if let Some(instance) = instance {
         RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args)
     } else {
diff --git a/compiler/rustc_codegen_cranelift/src/codegen_i128.rs b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs
index b4a2537b5ea..40bfe70771c 100644
--- a/compiler/rustc_codegen_cranelift/src/codegen_i128.rs
+++ b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs
@@ -56,7 +56,7 @@ pub(crate) fn maybe_codegen<'tcx>(
                     Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty))
                 }
             } else {
-                let out_ty = fx.tcx.intern_tup(&[lhs.layout().ty, fx.tcx.types.bool]);
+                let out_ty = fx.tcx.mk_tup(&[lhs.layout().ty, fx.tcx.types.bool]);
                 let oflow = CPlace::new_stack_slot(fx, fx.layout_of(fx.tcx.types.i32));
                 let lhs = lhs.load_scalar(fx);
                 let rhs = rhs.load_scalar(fx);
@@ -78,7 +78,7 @@ pub(crate) fn maybe_codegen<'tcx>(
         }
         BinOp::Add | BinOp::Sub | BinOp::Mul => {
             assert!(checked);
-            let out_ty = fx.tcx.intern_tup(&[lhs.layout().ty, fx.tcx.types.bool]);
+            let out_ty = fx.tcx.mk_tup(&[lhs.layout().ty, fx.tcx.types.bool]);
             let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty));
             let (param_types, args) = if fx.tcx.sess.target.is_like_windows {
                 let (lhs_ptr, lhs_extra) = lhs.force_stack(fx);
diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs
index a8be0d32cc8..722e2754e83 100644
--- a/compiler/rustc_codegen_cranelift/src/common.rs
+++ b/compiler/rustc_codegen_cranelift/src/common.rs
@@ -374,7 +374,7 @@ impl<'tcx> HasTargetSpec for FunctionCx<'_, '_, 'tcx> {
 impl<'tcx> FunctionCx<'_, '_, 'tcx> {
     pub(crate) fn monomorphize<T>(&self, value: T) -> T
     where
-        T: TypeFoldable<'tcx> + Copy,
+        T: TypeFoldable<TyCtxt<'tcx>> + Copy,
     {
         self.instance.subst_mir_and_normalize_erasing_regions(
             self.tcx,
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
index cbac2e66765..e5c4b244a1a 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
@@ -191,7 +191,7 @@ fn llvm_add_sub<'tcx>(
     // carry0 | carry1 -> carry or borrow respectively
     let cb_out = fx.bcx.ins().bor(cb0, cb1);
 
-    let layout = fx.layout_of(fx.tcx.intern_tup(&[fx.tcx.types.u8, fx.tcx.types.u64]));
+    let layout = fx.layout_of(fx.tcx.mk_tup(&[fx.tcx.types.u8, fx.tcx.types.u64]));
     let val = CValue::by_val_pair(cb_out, c, layout);
     ret.write_cvalue(fx, val);
 }
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs
index c7fe382bac4..80ce3dc9328 100644
--- a/compiler/rustc_codegen_cranelift/src/lib.rs
+++ b/compiler/rustc_codegen_cranelift/src/lib.rs
@@ -86,7 +86,7 @@ mod prelude {
     pub(crate) use rustc_middle::ty::layout::{self, LayoutOf, TyAndLayout};
     pub(crate) use rustc_middle::ty::{
         self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut,
-        TypeFoldable, UintTy,
+        TypeFoldable, TypeVisitableExt, UintTy,
     };
     pub(crate) use rustc_target::abi::{Abi, Scalar, Size, VariantIdx};
 
@@ -172,6 +172,11 @@ pub struct CraneliftCodegenBackend {
 }
 
 impl CodegenBackend for CraneliftCodegenBackend {
+    fn locale_resource(&self) -> &'static str {
+        // FIXME(rust-lang/rust#100717) - cranelift codegen backend is not yet translated
+        ""
+    }
+
     fn init(&self, sess: &Session) {
         use rustc_session::config::Lto;
         match sess.lto() {
diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs
index 26327107df4..be908df83e8 100644
--- a/compiler/rustc_codegen_cranelift/src/main_shim.rs
+++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs
@@ -119,7 +119,7 @@ pub(crate) fn maybe_create_entry_wrapper(
                     tcx,
                     ParamEnv::reveal_all(),
                     report.def_id,
-                    tcx.intern_substs(&[GenericArg::from(main_ret_ty)]),
+                    tcx.mk_substs(&[GenericArg::from(main_ret_ty)]),
                 )
                 .unwrap()
                 .unwrap()
@@ -146,7 +146,7 @@ pub(crate) fn maybe_create_entry_wrapper(
                     tcx,
                     ParamEnv::reveal_all(),
                     start_def_id,
-                    tcx.intern_substs(&[main_ret_ty.into()]),
+                    tcx.mk_substs(&[main_ret_ty.into()]),
                 )
                 .unwrap()
                 .unwrap()
diff --git a/compiler/rustc_codegen_cranelift/src/num.rs b/compiler/rustc_codegen_cranelift/src/num.rs
index 05905a7bcdf..c058ece96d8 100644
--- a/compiler/rustc_codegen_cranelift/src/num.rs
+++ b/compiler/rustc_codegen_cranelift/src/num.rs
@@ -289,7 +289,7 @@ pub(crate) fn codegen_checked_int_binop<'tcx>(
         _ => bug!("binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", bin_op, in_lhs, in_rhs),
     };
 
-    let out_layout = fx.layout_of(fx.tcx.intern_tup(&[in_lhs.layout().ty, fx.tcx.types.bool]));
+    let out_layout = fx.layout_of(fx.tcx.mk_tup(&[in_lhs.layout().ty, fx.tcx.types.bool]));
     CValue::by_val_pair(res, has_overflow, out_layout)
 }
 
diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl b/compiler/rustc_codegen_gcc/locales/en-US.ftl
index 6101b28ab0c..6101b28ab0c 100644
--- a/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl
+++ b/compiler/rustc_codegen_gcc/locales/en-US.ftl
diff --git a/compiler/rustc_codegen_gcc/src/callee.rs b/compiler/rustc_codegen_gcc/src/callee.rs
index c1041125ecc..9e3a22ee05d 100644
--- a/compiler/rustc_codegen_gcc/src/callee.rs
+++ b/compiler/rustc_codegen_gcc/src/callee.rs
@@ -1,6 +1,6 @@
 use gccjit::{FunctionType, RValue};
 use rustc_codegen_ssa::traits::BaseTypeMethods;
-use rustc_middle::ty::{self, Instance, TypeVisitable};
+use rustc_middle::ty::{self, Instance, TypeVisitableExt};
 use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
 
 use crate::abi::FnAbiGccExt;
diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs
index 4424b31c054..457006319af 100644
--- a/compiler/rustc_codegen_gcc/src/context.rs
+++ b/compiler/rustc_codegen_gcc/src/context.rs
@@ -383,7 +383,7 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
                     tcx,
                     ty::ParamEnv::reveal_all(),
                     def_id,
-                    tcx.intern_substs(&[]),
+                    ty::List::empty(),
                 )
                 .unwrap().unwrap(),
             ),
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index 5ab87feb98b..44538b41528 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -73,7 +73,8 @@ use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModul
 use rustc_codegen_ssa::target_features::supported_target_features;
 use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, ModuleBufferMethods, ThinBufferMethods, WriteBackendMethods};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{ErrorGuaranteed, Handler};
+use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, Handler, SubdiagnosticMessage};
+use rustc_macros::fluent_messages;
 use rustc_metadata::EncodedMetadata;
 use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
 use rustc_middle::ty::TyCtxt;
@@ -84,6 +85,8 @@ use rustc_span::Symbol;
 use rustc_span::fatal_error::FatalError;
 use tempfile::TempDir;
 
+fluent_messages! { "../locales/en-US.ftl" }
+
 pub struct PrintOnPanic<F: Fn() -> String>(pub F);
 
 impl<F: Fn() -> String> Drop for PrintOnPanic<F> {
@@ -100,6 +103,10 @@ pub struct GccCodegenBackend {
 }
 
 impl CodegenBackend for GccCodegenBackend {
+    fn locale_resource(&self) -> &'static str {
+        crate::DEFAULT_LOCALE_RESOURCE
+    }
+
     fn init(&self, sess: &Session) {
         if sess.lto() != Lto::No {
             sess.emit_warning(LTONotSupported {});
diff --git a/compiler/rustc_codegen_gcc/src/mono_item.rs b/compiler/rustc_codegen_gcc/src/mono_item.rs
index 9468a1ef4bb..a7c868354fb 100644
--- a/compiler/rustc_codegen_gcc/src/mono_item.rs
+++ b/compiler/rustc_codegen_gcc/src/mono_item.rs
@@ -1,7 +1,7 @@
 use rustc_codegen_ssa::traits::PreDefineMethods;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir::mono::{Linkage, Visibility};
-use rustc_middle::ty::{self, Instance, TypeVisitable};
+use rustc_middle::ty::{self, Instance, TypeVisitableExt};
 use rustc_middle::ty::layout::{FnAbiOf, LayoutOf};
 use rustc_span::def_id::DefId;
 
diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs
index 1326af670cd..ea2ce765053 100644
--- a/compiler/rustc_codegen_gcc/src/type_of.rs
+++ b/compiler/rustc_codegen_gcc/src/type_of.rs
@@ -3,7 +3,7 @@ use std::fmt::Write;
 use gccjit::{Struct, Type};
 use crate::rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods};
 use rustc_middle::bug;
-use rustc_middle::ty::{self, Ty, TypeVisitable};
+use rustc_middle::ty::{self, Ty, TypeVisitableExt};
 use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_target::abi::{self, Abi, F32, F64, FieldsShape, Int, Integer, Pointer, PointeeInfo, Size, TyAbiInterface, Variants};
diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_codegen_llvm/locales/en-US.ftl
index e5df417370b..e5df417370b 100644
--- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl
+++ b/compiler/rustc_codegen_llvm/locales/en-US.ftl
diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs
index f1d01a4602a..6ee2a05ffd7 100644
--- a/compiler/rustc_codegen_llvm/src/callee.rs
+++ b/compiler/rustc_codegen_llvm/src/callee.rs
@@ -13,7 +13,7 @@ use crate::value::Value;
 use rustc_codegen_ssa::traits::*;
 
 use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
-use rustc_middle::ty::{self, Instance, TypeVisitable};
+use rustc_middle::ty::{self, Instance, TypeVisitableExt};
 
 /// Codegens a reference to a fn/method item, monomorphizing and
 /// inlining as it goes.
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 37ee0e14020..3d29968d5d6 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -520,14 +520,9 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         let tcx = self.tcx;
         let llfn = match tcx.lang_items().eh_personality() {
             Some(def_id) if !wants_msvc_seh(self.sess()) => self.get_fn_addr(
-                ty::Instance::resolve(
-                    tcx,
-                    ty::ParamEnv::reveal_all(),
-                    def_id,
-                    tcx.intern_substs(&[]),
-                )
-                .unwrap()
-                .unwrap(),
+                ty::Instance::resolve(tcx, ty::ParamEnv::reveal_all(), def_id, ty::List::empty())
+                    .unwrap()
+                    .unwrap(),
             ),
             _ => {
                 let name = if wants_msvc_seh(self.sess()) {
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index cef403b9f8b..5392534cfcb 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -27,7 +27,7 @@ use rustc_index::vec::IndexVec;
 use rustc_middle::mir;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
-use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeVisitable};
+use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeVisitableExt};
 use rustc_session::config::{self, DebugInfo};
 use rustc_session::Session;
 use rustc_span::symbol::Symbol;
diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs
index 81072edc475..bae88d94293 100644
--- a/compiler/rustc_codegen_llvm/src/errors.rs
+++ b/compiler/rustc_codegen_llvm/src/errors.rs
@@ -2,9 +2,10 @@ use std::borrow::Cow;
 use std::ffi::CString;
 use std::path::Path;
 
+use crate::fluent_generated as fluent;
 use rustc_data_structures::small_c_str::SmallCStr;
 use rustc_errors::{
-    fluent, DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed, Handler, IntoDiagnostic,
+    DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed, Handler, IntoDiagnostic,
 };
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::Span;
@@ -27,9 +28,9 @@ pub(crate) struct UnknownCTargetFeature<'a> {
 
 #[derive(Subdiagnostic)]
 pub(crate) enum PossibleFeature<'a> {
-    #[help(possible_feature)]
+    #[help(codegen_llvm_possible_feature)]
     Some { rust_feature: &'a str },
-    #[help(consider_filing_feature_request)]
+    #[help(codegen_llvm_consider_filing_feature_request)]
     None,
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index 111d14b265c..c41e74c51a0 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -34,7 +34,8 @@ use rustc_codegen_ssa::traits::*;
 use rustc_codegen_ssa::ModuleCodegen;
 use rustc_codegen_ssa::{CodegenResults, CompiledModule};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{ErrorGuaranteed, FatalError, Handler};
+use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, FatalError, Handler, SubdiagnosticMessage};
+use rustc_macros::fluent_messages;
 use rustc_metadata::EncodedMetadata;
 use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
 use rustc_middle::ty::query::Providers;
@@ -83,6 +84,8 @@ mod type_of;
 mod va_arg;
 mod value;
 
+fluent_messages! { "../locales/en-US.ftl" }
+
 #[derive(Clone)]
 pub struct LlvmCodegenBackend(());
 
@@ -246,6 +249,10 @@ impl LlvmCodegenBackend {
 }
 
 impl CodegenBackend for LlvmCodegenBackend {
+    fn locale_resource(&self) -> &'static str {
+        crate::DEFAULT_LOCALE_RESOURCE
+    }
+
     fn init(&self, sess: &Session) {
         llvm_util::init(sess); // Make sure llvm is inited
     }
diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs
index 76f692b2016..d0ae36349df 100644
--- a/compiler/rustc_codegen_llvm/src/mono_item.rs
+++ b/compiler/rustc_codegen_llvm/src/mono_item.rs
@@ -9,7 +9,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 pub use rustc_middle::mir::mono::MonoItem;
 use rustc_middle::mir::mono::{Linkage, Visibility};
 use rustc_middle::ty::layout::{FnAbiOf, LayoutOf};
-use rustc_middle::ty::{self, Instance, TypeVisitable};
+use rustc_middle::ty::{self, Instance, TypeVisitableExt};
 use rustc_session::config::CrateType;
 use rustc_target::spec::RelocModel;
 
diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs
index 9cda24bab87..e264ce78f0d 100644
--- a/compiler/rustc_codegen_llvm/src/type_of.rs
+++ b/compiler/rustc_codegen_llvm/src/type_of.rs
@@ -5,7 +5,7 @@ use rustc_codegen_ssa::traits::*;
 use rustc_middle::bug;
 use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
 use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
-use rustc_middle::ty::{self, Ty, TypeVisitable};
+use rustc_middle::ty::{self, Ty, TypeVisitableExt};
 use rustc_target::abi::{Abi, Align, FieldsShape};
 use rustc_target::abi::{Int, Pointer, F32, F64};
 use rustc_target::abi::{PointeeInfo, Scalar, Size, TyAbiInterface, Variants};
diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_codegen_ssa/locales/en-US.ftl
index 8fe5f8d50ab..8fe5f8d50ab 100644
--- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
+++ b/compiler/rustc_codegen_ssa/locales/en-US.ftl
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index eaf1e9817c2..52c01b423a7 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -473,13 +473,13 @@ impl<'a> Linker for GccLinker<'a> {
         self.cmd.arg(path);
     }
     fn full_relro(&mut self) {
-        self.linker_args(&["-zrelro", "-znow"]);
+        self.linker_args(&["-z", "relro", "-z", "now"]);
     }
     fn partial_relro(&mut self) {
-        self.linker_arg("-zrelro");
+        self.linker_args(&["-z", "relro"]);
     }
     fn no_relro(&mut self) {
-        self.linker_arg("-znorelro");
+        self.linker_args(&["-z", "norelro"]);
     }
 
     fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
@@ -758,7 +758,7 @@ impl<'a> Linker for GccLinker<'a> {
         if self.sess.target.is_like_windows {
             self.linker_arg("--nxcompat");
         } else if self.is_gnu {
-            self.linker_arg("-znoexecstack");
+            self.linker_args(&["-z", "noexecstack"]);
         }
     }
 
@@ -1364,16 +1364,16 @@ impl<'a> Linker for L4Bender<'a> {
     }
 
     fn full_relro(&mut self) {
-        self.cmd.arg("-zrelro");
-        self.cmd.arg("-znow");
+        self.cmd.arg("-z").arg("relro");
+        self.cmd.arg("-z").arg("now");
     }
 
     fn partial_relro(&mut self) {
-        self.cmd.arg("-zrelro");
+        self.cmd.arg("-z").arg("relro");
     }
 
     fn no_relro(&mut self) {
-        self.cmd.arg("-znorelro");
+        self.cmd.arg("-z").arg("norelro");
     }
 
     fn cmd(&mut self) -> &mut Command {
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index 11bd47a8f0c..067a3e167fe 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -373,7 +373,7 @@ fn upstream_monomorphizations_provider(
                 ExportedSymbol::Generic(def_id, substs) => (def_id, substs),
                 ExportedSymbol::DropGlue(ty) => {
                     if let Some(drop_in_place_fn_def_id) = drop_in_place_fn_def_id {
-                        (drop_in_place_fn_def_id, tcx.intern_substs(&[ty.into()]))
+                        (drop_in_place_fn_def_id, tcx.mk_substs(&[ty.into()]))
                     } else {
                         // `drop_in_place` in place does not exist, don't try
                         // to use it.
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 4e13d4dbcb7..73179249bc4 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -476,7 +476,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
                     cx.tcx(),
                     ty::ParamEnv::reveal_all(),
                     start_def_id,
-                    cx.tcx().intern_substs(&[main_ret_ty.into()]),
+                    cx.tcx().mk_substs(&[main_ret_ty.into()]),
                 )
                 .unwrap()
                 .unwrap(),
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index d81252653df..6dea7496fc3 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -1,8 +1,9 @@
 //! Errors emitted by codegen_ssa
 
 use crate::back::command::Command;
+use crate::fluent_generated as fluent;
 use rustc_errors::{
-    fluent, DiagnosticArgValue, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic,
+    DiagnosticArgValue, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic,
     IntoDiagnosticArg,
 };
 use rustc_macros::Diagnostic;
@@ -388,7 +389,7 @@ pub struct LinkerNotFound {
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_unable_to_exe_linker)]
 #[note]
-#[note(command_note)]
+#[note(codegen_ssa_command_note)]
 pub struct UnableToExeLinker {
     pub linker_path: PathBuf,
     pub error: Error,
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 7d51cee307e..ebe9e50ffe6 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -25,7 +25,9 @@ extern crate rustc_middle;
 use rustc_ast as ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::Lrc;
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
 use rustc_hir::def_id::CrateNum;
+use rustc_macros::fluent_messages;
 use rustc_middle::dep_graph::WorkProduct;
 use rustc_middle::middle::dependency_format::Dependencies;
 use rustc_middle::middle::exported_symbols::SymbolExportKind;
@@ -54,6 +56,8 @@ pub mod mono_item;
 pub mod target_features;
 pub mod traits;
 
+fluent_messages! { "../locales/en-US.ftl" }
+
 pub struct ModuleCodegen<M> {
     /// The name of the module. When the crate may be saved between
     /// compilations, incremental compilation requires that name be
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index e105322a0b4..f6c1b7a98aa 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -16,7 +16,7 @@ use rustc_index::vec::Idx;
 use rustc_middle::mir::{self, AssertKind, SwitchTargets};
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
 use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
-use rustc_middle::ty::{self, Instance, Ty, TypeVisitable};
+use rustc_middle::ty::{self, Instance, Ty, TypeVisitableExt};
 use rustc_session::config::OptLevel;
 use rustc_span::source_map::Span;
 use rustc_span::{sym, Symbol};
@@ -783,7 +783,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         };
 
         let extra_args = &args[sig.inputs().skip_binder().len()..];
-        let extra_args = bx.tcx().mk_type_list(extra_args.iter().map(|op_arg| {
+        let extra_args = bx.tcx().mk_type_list_from_iter(extra_args.iter().map(|op_arg| {
             let op_ty = op_arg.ty(self.mir, bx.tcx());
             self.monomorphize(op_ty)
         }));
@@ -1547,7 +1547,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             slot
         } else {
             let layout = cx.layout_of(
-                cx.tcx().intern_tup(&[cx.tcx().mk_mut_ptr(cx.tcx().types.u8), cx.tcx().types.i32]),
+                cx.tcx().mk_tup(&[cx.tcx().mk_mut_ptr(cx.tcx().types.u8), cx.tcx().types.i32]),
             );
             let slot = PlaceRef::alloca(bx, layout);
             self.personality_slot = Some(slot);
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index eec91ffa44a..2ec9fdbf44f 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -3,7 +3,7 @@ use crate::traits::*;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout};
-use rustc_middle::ty::{self, Instance, Ty, TypeFoldable};
+use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
 use rustc_target::abi::call::{FnAbi, PassMode};
 
 use std::iter;
@@ -105,7 +105,7 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
 impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     pub fn monomorphize<T>(&self, value: T) -> T
     where
-        T: Copy + TypeFoldable<'tcx>,
+        T: Copy + TypeFoldable<TyCtxt<'tcx>>,
     {
         debug!("monomorphize: self.instance={:?}", self.instance);
         self.instance.subst_mir_and_normalize_erasing_regions(
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 41cd1c09a4e..3d856986fb4 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -413,7 +413,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     lhs.layout.ty,
                 );
                 let val_ty = op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty);
-                let operand_ty = bx.tcx().intern_tup(&[val_ty, bx.tcx().types.bool]);
+                let operand_ty = bx.tcx().mk_tup(&[val_ty, bx.tcx().types.bool]);
                 OperandRef { val: result, layout: bx.cx().layout_of(operand_ty) }
             }
 
diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs
index 5c35070ea66..64bebe50ddb 100644
--- a/compiler/rustc_codegen_ssa/src/traits/backend.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs
@@ -57,6 +57,10 @@ impl<'tcx, T> Backend<'tcx> for T where
 }
 
 pub trait CodegenBackend {
+    /// Locale resources for diagnostic messages - a string the content of the Fluent resource.
+    /// Called before `init` so that all other functions are able to emit translatable diagnostics.
+    fn locale_resource(&self) -> &'static str;
+
     fn init(&self, _sess: &Session) {}
     fn print(&self, _req: PrintRequest, _sess: &Session) {}
     fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<Symbol> {
diff --git a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl b/compiler/rustc_const_eval/locales/en-US.ftl
index 33bb116d6fa..33bb116d6fa 100644
--- a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl
+++ b/compiler/rustc_const_eval/locales/en-US.ftl
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index 45f7c756055..7564ba17b40 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -180,7 +180,7 @@ pub(super) fn op_to_const<'tcx>(
                         (ecx.tcx.global_alloc(alloc_id).unwrap_memory(), offset.bytes())
                     }
                     (None, _offset) => (
-                        ecx.tcx.intern_const_alloc(Allocation::from_bytes_byte_aligned_immutable(
+                        ecx.tcx.mk_const_alloc(Allocation::from_bytes_byte_aligned_immutable(
                             b"" as &[u8],
                         )),
                         0,
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index 4b055076742..f8b7cc6d7e1 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -9,12 +9,12 @@ pub(crate) struct UnstableInStable {
     #[primary_span]
     pub span: Span,
     #[suggestion(
-        unstable_sugg,
+        const_eval_unstable_sugg,
         code = "#[rustc_const_unstable(feature = \"...\", issue = \"...\")]\n",
         applicability = "has-placeholders"
     )]
     #[suggestion(
-        bypass_sugg,
+        const_eval_bypass_sugg,
         code = "#[rustc_allow_const_fn_unstable({gate})]\n",
         applicability = "has-placeholders"
     )]
@@ -35,15 +35,15 @@ pub(crate) struct StaticAccessErr {
     #[primary_span]
     pub span: Span,
     pub kind: ConstContext,
-    #[note(teach_note)]
-    #[help(teach_help)]
+    #[note(const_eval_teach_note)]
+    #[help(const_eval_teach_help)]
     pub teach: Option<()>,
 }
 
 #[derive(Diagnostic)]
 #[diag(const_eval_raw_ptr_to_int)]
 #[note]
-#[note(note2)]
+#[note(const_eval_note2)]
 pub(crate) struct RawPtrToIntErr {
     #[primary_span]
     pub span: Span,
@@ -118,7 +118,7 @@ pub(crate) struct UnallowedMutableRefs {
     #[primary_span]
     pub span: Span,
     pub kind: ConstContext,
-    #[note(teach_note)]
+    #[note(const_eval_teach_note)]
     pub teach: Option<()>,
 }
 
@@ -128,7 +128,7 @@ pub(crate) struct UnallowedMutableRefsRaw {
     #[primary_span]
     pub span: Span,
     pub kind: ConstContext,
-    #[note(teach_note)]
+    #[note(const_eval_teach_note)]
     pub teach: Option<()>,
 }
 #[derive(Diagnostic)]
@@ -163,7 +163,7 @@ pub(crate) struct UnallowedHeapAllocations {
     #[label]
     pub span: Span,
     pub kind: ConstContext,
-    #[note(teach_note)]
+    #[note(const_eval_teach_note)]
     pub teach: Option<()>,
 }
 
@@ -184,7 +184,7 @@ pub(crate) struct InteriorMutableDataRefer {
     #[help]
     pub opt_help: Option<()>,
     pub kind: ConstContext,
-    #[note(teach_note)]
+    #[note(const_eval_teach_note)]
     pub teach: Option<()>,
 }
 
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 24b157054d3..3db102e484d 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -489,7 +489,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
     /// Call this on things you got out of the MIR (so it is as generic as the current
     /// stack frame), to bring it into the proper environment for this interpreter.
-    pub(super) fn subst_from_current_frame_and_normalize_erasing_regions<T: TypeFoldable<'tcx>>(
+    pub(super) fn subst_from_current_frame_and_normalize_erasing_regions<
+        T: TypeFoldable<TyCtxt<'tcx>>,
+    >(
         &self,
         value: T,
     ) -> Result<T, InterpError<'tcx>> {
@@ -498,7 +500,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
     /// Call this on things you got out of the MIR (so it is as generic as the provided
     /// stack frame), to bring it into the proper environment for this interpreter.
-    pub(super) fn subst_from_frame_and_normalize_erasing_regions<T: TypeFoldable<'tcx>>(
+    pub(super) fn subst_from_frame_and_normalize_erasing_regions<T: TypeFoldable<TyCtxt<'tcx>>>(
         &self,
         frame: &Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>,
         value: T,
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs
index 21ef1836188..b220d21f68b 100644
--- a/compiler/rustc_const_eval/src/interpret/intern.rs
+++ b/compiler/rustc_const_eval/src/interpret/intern.rs
@@ -135,7 +135,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx, const_eval:
     };
     // link the alloc id to the actual allocation
     leftover_allocations.extend(alloc.provenance().ptrs().iter().map(|&(_, alloc_id)| alloc_id));
-    let alloc = tcx.intern_const_alloc(alloc);
+    let alloc = tcx.mk_const_alloc(alloc);
     tcx.set_alloc_id_memory(alloc_id, alloc);
     None
 }
@@ -437,7 +437,7 @@ pub fn intern_const_alloc_recursive<
                     alloc.mutability = Mutability::Not;
                 }
             }
-            let alloc = tcx.intern_const_alloc(alloc);
+            let alloc = tcx.mk_const_alloc(alloc);
             tcx.set_alloc_id_memory(alloc_id, alloc);
             for &(_, alloc_id) in alloc.inner().provenance().ptrs().iter() {
                 if leftover_allocations.insert(alloc_id) {
@@ -479,6 +479,6 @@ impl<'mir, 'tcx: 'mir, M: super::intern::CompileTimeMachine<'mir, 'tcx, !>>
         f(self, &dest.into())?;
         let mut alloc = self.memory.alloc_map.remove(&dest.ptr.provenance.unwrap()).unwrap().1;
         alloc.mutability = Mutability::Not;
-        Ok(self.tcx.intern_const_alloc(alloc))
+        Ok(self.tcx.mk_const_alloc(alloc))
     }
 }
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index c5d558aeb6c..6e47646caed 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -45,7 +45,7 @@ fn numeric_intrinsic<Prov>(name: Symbol, bits: u128, kind: Primitive) -> Scalar<
 pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAllocation<'tcx> {
     let path = crate::util::type_name(tcx, ty);
     let alloc = Allocation::from_bytes_byte_aligned_immutable(path.into_bytes());
-    tcx.intern_const_alloc(alloc)
+    tcx.mk_const_alloc(alloc)
 }
 
 /// The logic for all nullary intrinsics is implemented here. These intrinsics don't get evaluated
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs
index f6a3937870e..cf52299b7ba 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs
@@ -96,7 +96,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         let loc_ty = self
             .tcx
             .type_of(self.tcx.require_lang_item(LangItem::PanicLocation, None))
-            .subst(*self.tcx, self.tcx.intern_substs(&[self.tcx.lifetimes.re_erased.into()]));
+            .subst(*self.tcx, self.tcx.mk_substs(&[self.tcx.lifetimes.re_erased.into()]));
         let loc_layout = self.layout_of(loc_ty).unwrap();
         let location = self.allocate(loc_layout, MemoryKind::CallerLocation).unwrap();
 
diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs
index 422120084d3..4decfe863e6 100644
--- a/compiler/rustc_const_eval/src/interpret/operator.rs
+++ b/compiler/rustc_const_eval/src/interpret/operator.rs
@@ -19,7 +19,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     ) -> InterpResult<'tcx> {
         let (val, overflowed, ty) = self.overflowing_binary_op(op, &left, &right)?;
         debug_assert_eq!(
-            self.tcx.intern_tup(&[ty, self.tcx.types.bool]),
+            self.tcx.mk_tup(&[ty, self.tcx.types.bool]),
             dest.layout.ty,
             "type mismatch for result of {:?}",
             op,
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index d934cfbbb84..2aea7c79b6d 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -73,7 +73,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 let fn_sig =
                     self.tcx.normalize_erasing_late_bound_regions(self.param_env, fn_sig_binder);
                 let extra_args = &args[fn_sig.inputs().len()..];
-                let extra_args = self.tcx.mk_type_list(extra_args.iter().map(|arg| arg.layout.ty));
+                let extra_args =
+                    self.tcx.mk_type_list_from_iter(extra_args.iter().map(|arg| arg.layout.ty));
 
                 let (fn_val, fn_abi, with_caller_location) = match *func.layout.ty.kind() {
                     ty::FnPtr(_sig) => {
diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs
index 581cb6421f7..bf2b4ee69ab 100644
--- a/compiler/rustc_const_eval/src/interpret/util.rs
+++ b/compiler/rustc_const_eval/src/interpret/util.rs
@@ -1,5 +1,7 @@
 use rustc_middle::mir::interpret::InterpResult;
-use rustc_middle::ty::{self, ir::TypeVisitor, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable};
+use rustc_middle::ty::{
+    self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
+};
 use std::ops::ControlFlow;
 
 /// Checks whether a type contains generic parameters which require substitution.
@@ -9,7 +11,7 @@ use std::ops::ControlFlow;
 /// case these parameters are unused.
 pub(crate) fn ensure_monomorphic_enough<'tcx, T>(tcx: TyCtxt<'tcx>, ty: T) -> InterpResult<'tcx>
 where
-    T: TypeVisitable<'tcx>,
+    T: TypeVisitable<TyCtxt<'tcx>>,
 {
     debug!("ensure_monomorphic_enough: ty={:?}", ty);
     if !ty.needs_subst() {
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index 964efcc9062..fc6d61c79c2 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -34,10 +34,14 @@ pub mod interpret;
 pub mod transform;
 pub mod util;
 
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_macros::fluent_messages;
 use rustc_middle::ty;
 use rustc_middle::ty::query::Providers;
 use rustc_target::abi::InitKind;
 
+fluent_messages! { "../locales/en-US.ftl" }
+
 pub fn provide(providers: &mut Providers) {
     const_eval::provide(providers);
     providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider;
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index faf741de60a..e4366f655e4 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -10,7 +10,7 @@ use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceC
 use rustc_middle::mir::*;
 use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
 use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty, TyCtxt};
-use rustc_middle::ty::{Binder, TraitRef, TypeVisitable};
+use rustc_middle::ty::{Binder, TraitRef, TypeVisitableExt};
 use rustc_mir_dataflow::{self, Analysis};
 use rustc_span::{sym, Span, Symbol};
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs
index 19367d708ee..3f3b66b0645 100644
--- a/compiler/rustc_const_eval/src/transform/promote_consts.rs
+++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs
@@ -18,7 +18,7 @@ use rustc_middle::mir::traversal::ReversePostorderIter;
 use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::*;
 use rustc_middle::ty::subst::InternalSubsts;
-use rustc_middle::ty::{self, List, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, List, TyCtxt, TypeVisitableExt};
 use rustc_span::Span;
 
 use rustc_index::vec::{Idx, IndexVec};
@@ -866,7 +866,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
 
             let mut projection = vec![PlaceElem::Deref];
             projection.extend(place.projection);
-            place.projection = tcx.intern_place_elems(&projection);
+            place.projection = tcx.mk_place_elems(&projection);
 
             // Create a temp to hold the promoted reference.
             // This is because `*r` requires `r` to be a local,
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 67dbf29da3b..068491646f4 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -13,7 +13,7 @@ use rustc_middle::mir::{
     RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator,
     TerminatorKind, UnOp, START_BLOCK,
 };
-use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt};
 use rustc_mir_dataflow::impls::MaybeStorageLive;
 use rustc_mir_dataflow::storage::always_storage_live_locals;
 use rustc_mir_dataflow::{Analysis, ResultsCursor};
@@ -315,7 +315,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                 }
             }
             ProjectionElem::Field(f, ty) => {
-                let parent = Place { local, projection: self.tcx.intern_place_elems(proj_base) };
+                let parent = Place { local, projection: self.tcx.mk_place_elems(proj_base) };
                 let parent_ty = parent.ty(&self.body.local_decls, self.tcx);
                 let fail_out_of_bounds = |this: &Self, location| {
                     this.fail(location, format!("Out of bounds field {:?} for {:?}", f, parent_ty));
diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml
index 0366fb0a148..decbb6519ba 100644
--- a/compiler/rustc_data_structures/Cargo.toml
+++ b/compiler/rustc_data_structures/Cargo.toml
@@ -29,8 +29,9 @@ smallvec = { version = "1.8.1", features = [
 stable_deref_trait = "1.0.0"
 stacker = "0.1.15"
 tempfile = "3.2"
-thin-vec = "0.2.9"
+thin-vec = "0.2.12"
 tracing = "0.1"
+elsa = "1.8"
 
 [dependencies.parking_lot]
 version = "0.11"
diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs
index c8e66eb672c..c4b11951ab7 100644
--- a/compiler/rustc_data_structures/src/graph/scc/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs
@@ -27,7 +27,7 @@ pub struct Sccs<N: Idx, S: Idx> {
     scc_data: SccData<S>,
 }
 
-struct SccData<S: Idx> {
+pub struct SccData<S: Idx> {
     /// For each SCC, the range of `all_successors` where its
     /// successors can be found.
     ranges: IndexVec<S, Range<usize>>,
@@ -43,6 +43,14 @@ impl<N: Idx, S: Idx + Ord> Sccs<N, S> {
         SccsConstruction::construct(graph)
     }
 
+    pub fn scc_indices(&self) -> &IndexVec<N, S> {
+        &self.scc_indices
+    }
+
+    pub fn scc_data(&self) -> &SccData<S> {
+        &self.scc_data
+    }
+
     /// Returns the number of SCCs in the graph.
     pub fn num_sccs(&self) -> usize {
         self.scc_data.len()
@@ -115,6 +123,14 @@ impl<S: Idx> SccData<S> {
         self.ranges.len()
     }
 
+    pub fn ranges(&self) -> &IndexVec<S, Range<usize>> {
+        &self.ranges
+    }
+
+    pub fn all_successors(&self) -> &Vec<S> {
+        &self.all_successors
+    }
+
     /// Returns the successors of the given SCC.
     fn successors(&self, scc: S) -> &[S] {
         // Annoyingly, `range` does not implement `Copy`, so we have
diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs
index ad71dcdf9d9..31323c21df0 100644
--- a/compiler/rustc_data_structures/src/sync.rs
+++ b/compiler/rustc_data_structures/src/sync.rs
@@ -26,6 +26,10 @@ use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe};
 pub use std::sync::atomic::Ordering;
 pub use std::sync::atomic::Ordering::SeqCst;
 
+pub use vec::AppendOnlyVec;
+
+mod vec;
+
 cfg_if! {
     if #[cfg(not(parallel_compiler))] {
         pub auto trait Send {}
diff --git a/compiler/rustc_data_structures/src/sync/vec.rs b/compiler/rustc_data_structures/src/sync/vec.rs
new file mode 100644
index 00000000000..cbea4f05999
--- /dev/null
+++ b/compiler/rustc_data_structures/src/sync/vec.rs
@@ -0,0 +1,41 @@
+use std::marker::PhantomData;
+
+use rustc_index::vec::Idx;
+
+pub struct AppendOnlyVec<I: Idx, T: Copy> {
+    #[cfg(not(parallel_compiler))]
+    vec: elsa::vec::FrozenVec<T>,
+    #[cfg(parallel_compiler)]
+    vec: elsa::sync::LockFreeFrozenVec<T>,
+    _marker: PhantomData<fn(&I)>,
+}
+
+impl<I: Idx, T: Copy> AppendOnlyVec<I, T> {
+    pub fn new() -> Self {
+        Self {
+            #[cfg(not(parallel_compiler))]
+            vec: elsa::vec::FrozenVec::new(),
+            #[cfg(parallel_compiler)]
+            vec: elsa::sync::LockFreeFrozenVec::new(),
+            _marker: PhantomData,
+        }
+    }
+
+    pub fn push(&self, val: T) -> I {
+        #[cfg(not(parallel_compiler))]
+        let i = self.vec.len();
+        #[cfg(not(parallel_compiler))]
+        self.vec.push(val);
+        #[cfg(parallel_compiler)]
+        let i = self.vec.push(val);
+        I::new(i)
+    }
+
+    pub fn get(&self, i: I) -> Option<T> {
+        let i = i.index();
+        #[cfg(not(parallel_compiler))]
+        return self.vec.get_copy(i);
+        #[cfg(parallel_compiler)]
+        return self.vec.get(i);
+    }
+}
diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml
index cdec4f91277..7b59a52cffe 100644
--- a/compiler/rustc_driver_impl/Cargo.toml
+++ b/compiler/rustc_driver_impl/Cargo.toml
@@ -9,6 +9,27 @@ edition = "2021"
 tracing = { version = "0.1.35" }
 serde_json = "1.0.59"
 rustc_log = { path = "../rustc_log" }
+rustc_ast_lowering = { path = "../rustc_ast_lowering" }
+rustc_ast_passes = { path = "../rustc_ast_passes" }
+rustc_attr = { path = "../rustc_attr" }
+rustc_borrowck = { path = "../rustc_borrowck" }
+rustc_builtin_macros = { path = "../rustc_builtin_macros" }
+rustc_const_eval = { path = "../rustc_const_eval" }
+rustc_error_messages = { path = "../rustc_error_messages" }
+rustc_expand = { path = "../rustc_expand" }
+rustc_hir_typeck = { path = "../rustc_hir_typeck" }
+rustc_incremental = { path = "../rustc_incremental" }
+rustc_infer = { path = "../rustc_infer" }
+rustc_mir_build = { path = "../rustc_mir_build" }
+rustc_mir_dataflow = { path = "../rustc_mir_dataflow" }
+rustc_monomorphize = { path = "../rustc_monomorphize" }
+rustc_passes = { path = "../rustc_passes" }
+rustc_privacy = { path = "../rustc_privacy" }
+rustc_query_system = { path = "../rustc_query_system" }
+rustc_resolve = { path = "../rustc_resolve" }
+rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
+rustc_trait_selection = { path = "../rustc_trait_selection" }
+rustc_ty_utils = { path = "../rustc_ty_utils" }
 rustc_middle = { path = "../rustc_middle" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_target = { path = "../rustc_target" }
diff --git a/compiler/rustc_error_messages/locales/en-US/driver.ftl b/compiler/rustc_driver_impl/locales/en-US.ftl
index f19b1ff6426..f19b1ff6426 100644
--- a/compiler/rustc_error_messages/locales/en-US/driver.ftl
+++ b/compiler/rustc_driver_impl/locales/en-US.ftl
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index d7e9e00f3b6..464ddae476a 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -23,11 +23,14 @@ use rustc_codegen_ssa::{traits::CodegenBackend, CodegenErrors, CodegenResults};
 use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
 use rustc_data_structures::sync::SeqCst;
 use rustc_errors::registry::{InvalidErrorCode, Registry};
-use rustc_errors::{ErrorGuaranteed, PResult, TerminalUrl};
+use rustc_errors::{
+    DiagnosticMessage, ErrorGuaranteed, PResult, SubdiagnosticMessage, TerminalUrl,
+};
 use rustc_feature::find_gated_cfg;
 use rustc_interface::util::{self, collect_crate_types, get_codegen_backend};
 use rustc_interface::{interface, Queries};
 use rustc_lint::LintStore;
+use rustc_macros::fluent_messages;
 use rustc_metadata::locator;
 use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS};
 use rustc_session::config::{ErrorOutputType, Input, OutputType, PrintRequest, TrimmedDefPaths};
@@ -61,6 +64,44 @@ use crate::session_diagnostics::{
     RLinkWrongFileType, RlinkNotAFile, RlinkUnableToRead,
 };
 
+fluent_messages! { "../locales/en-US.ftl" }
+
+pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[
+    // tidy-alphabetical-start
+    crate::DEFAULT_LOCALE_RESOURCE,
+    rustc_ast_lowering::DEFAULT_LOCALE_RESOURCE,
+    rustc_ast_passes::DEFAULT_LOCALE_RESOURCE,
+    rustc_attr::DEFAULT_LOCALE_RESOURCE,
+    rustc_borrowck::DEFAULT_LOCALE_RESOURCE,
+    rustc_builtin_macros::DEFAULT_LOCALE_RESOURCE,
+    rustc_codegen_ssa::DEFAULT_LOCALE_RESOURCE,
+    rustc_const_eval::DEFAULT_LOCALE_RESOURCE,
+    rustc_error_messages::DEFAULT_LOCALE_RESOURCE,
+    rustc_expand::DEFAULT_LOCALE_RESOURCE,
+    rustc_hir_analysis::DEFAULT_LOCALE_RESOURCE,
+    rustc_hir_typeck::DEFAULT_LOCALE_RESOURCE,
+    rustc_incremental::DEFAULT_LOCALE_RESOURCE,
+    rustc_infer::DEFAULT_LOCALE_RESOURCE,
+    rustc_interface::DEFAULT_LOCALE_RESOURCE,
+    rustc_lint::DEFAULT_LOCALE_RESOURCE,
+    rustc_metadata::DEFAULT_LOCALE_RESOURCE,
+    rustc_middle::DEFAULT_LOCALE_RESOURCE,
+    rustc_mir_build::DEFAULT_LOCALE_RESOURCE,
+    rustc_mir_dataflow::DEFAULT_LOCALE_RESOURCE,
+    rustc_monomorphize::DEFAULT_LOCALE_RESOURCE,
+    rustc_parse::DEFAULT_LOCALE_RESOURCE,
+    rustc_passes::DEFAULT_LOCALE_RESOURCE,
+    rustc_plugin_impl::DEFAULT_LOCALE_RESOURCE,
+    rustc_privacy::DEFAULT_LOCALE_RESOURCE,
+    rustc_query_system::DEFAULT_LOCALE_RESOURCE,
+    rustc_resolve::DEFAULT_LOCALE_RESOURCE,
+    rustc_session::DEFAULT_LOCALE_RESOURCE,
+    rustc_symbol_mangling::DEFAULT_LOCALE_RESOURCE,
+    rustc_trait_selection::DEFAULT_LOCALE_RESOURCE,
+    rustc_ty_utils::DEFAULT_LOCALE_RESOURCE,
+    // tidy-alphabetical-end
+];
+
 /// Exit status code used for successful compilation and help output.
 pub const EXIT_SUCCESS: i32 = 0;
 
@@ -218,6 +259,7 @@ fn run_compiler(
         output_file: ofile,
         output_dir: odir,
         file_loader,
+        locale_resources: DEFAULT_LOCALE_RESOURCES,
         lint_caps: Default::default(),
         parse_sess_created: None,
         register_lints: None,
@@ -443,7 +485,7 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) {
     let normalised =
         if upper_cased_code.starts_with('E') { upper_cased_code } else { format!("E{code:0>4}") };
     match registry.try_find_description(&normalised) {
-        Ok(Some(description)) => {
+        Ok(description) => {
             let mut is_in_code_block = false;
             let mut text = String::new();
             // Slice off the leading newline and print.
@@ -467,9 +509,6 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) {
                 print!("{text}");
             }
         }
-        Ok(None) => {
-            early_error(output, &format!("no extended information for {code}"));
-        }
         Err(InvalidErrorCode) => {
             early_error(output, &format!("{code} is not a valid error code"));
         }
@@ -1162,7 +1201,7 @@ static DEFAULT_HOOK: LazyLock<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send +
 /// hook.
 pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
     let fallback_bundle =
-        rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
+        rustc_errors::fallback_fluent_bundle(crate::DEFAULT_LOCALE_RESOURCES.to_vec(), false);
     let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr(
         rustc_errors::ColorConfig::Auto,
         None,
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index 800f3c52177..df857be85ad 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -253,6 +253,7 @@ E0466: include_str!("./error_codes/E0466.md"),
 E0468: include_str!("./error_codes/E0468.md"),
 E0469: include_str!("./error_codes/E0469.md"),
 E0472: include_str!("./error_codes/E0472.md"),
+E0476: include_str!("./error_codes/E0476.md"),
 E0477: include_str!("./error_codes/E0477.md"),
 E0478: include_str!("./error_codes/E0478.md"),
 E0482: include_str!("./error_codes/E0482.md"),
@@ -512,7 +513,9 @@ E0790: include_str!("./error_codes/E0790.md"),
 E0791: include_str!("./error_codes/E0791.md"),
 E0792: include_str!("./error_codes/E0792.md"),
 E0793: include_str!("./error_codes/E0793.md"),
-;
+}
+
+// Undocumented removed error codes. Note that many removed error codes are documented.
 //  E0006, // merged with E0005
 //  E0008, // cannot bind by-move into a pattern guard
 //  E0019, // merged into E0015
@@ -569,7 +572,7 @@ E0793: include_str!("./error_codes/E0793.md"),
 //  E0246, // invalid recursive type
 //  E0247,
 //  E0248, // value used as a type, now reported earlier during resolution
-           // as E0412
+//         // as E0412
 //  E0249,
 //  E0257,
 //  E0258,
@@ -611,7 +614,6 @@ E0793: include_str!("./error_codes/E0793.md"),
 //  E0473, // dereference of reference outside its lifetime
 //  E0474, // captured variable `..` does not outlive the enclosing closure
 //  E0475, // index of slice outside its lifetime
-    E0476, // lifetime of the source pointer does not outlive lifetime bound...
 //  E0479, // the type `..` (provided as the value of a type parameter) is...
 //  E0480, // lifetime of method receiver does not outlive the method call
 //  E0481, // lifetime of function argument does not outlive the function call
@@ -631,14 +633,14 @@ E0793: include_str!("./error_codes/E0793.md"),
 //  E0558, // replaced with a generic attribute input check
 //  E0563, // cannot determine a type for this `impl Trait` removed in 6383de15
 //  E0564, // only named lifetimes are allowed in `impl Trait`,
-           // but `{}` was found in the type `{}`
+//         // but `{}` was found in the type `{}`
 //  E0598, // lifetime of {} is too short to guarantee its contents can be...
 //  E0611, // merged into E0616
 //  E0612, // merged into E0609
 //  E0613, // Removed (merged with E0609)
 //  E0629, // missing 'feature' (rustc_const_unstable)
 //  E0630, // rustc_const_unstable attribute must be paired with stable/unstable
-           // attribute
+//         // attribute
 //  E0645, // trait aliases not finished
 //  E0694, // an unknown tool name found in scoped attributes
 //  E0702, // replaced with a generic attribute input check
@@ -647,4 +649,3 @@ E0793: include_str!("./error_codes/E0793.md"),
 //  E0721, // `await` keyword
 //  E0723, // unstable feature in `const` context
 //  E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
-}
diff --git a/compiler/rustc_error_codes/src/error_codes/E0476.md b/compiler/rustc_error_codes/src/error_codes/E0476.md
new file mode 100644
index 00000000000..fc141ba77f5
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0476.md
@@ -0,0 +1,21 @@
+The coerced type does not outlive the value being coerced to.
+
+Example of erroneous code:
+
+```compile_fail,E0476
+#![feature(coerce_unsized)]
+#![feature(unsize)]
+
+use std::marker::Unsize;
+use std::ops::CoerceUnsized;
+
+// error: lifetime of the source pointer does not outlive lifetime bound of the
+//        object type
+impl<'a, 'b, T, S> CoerceUnsized<&'a T> for &'b S where S: Unsize<T> {}
+```
+
+During a coercion, the "source pointer" (the coerced type) did not outlive the
+"object type" (value being coerced to). In the above example, `'b` is not a
+subtype of `'a`. This error can currently only be encountered with the unstable
+`CoerceUnsized` trait which allows custom coercions of unsized types behind a
+smart pointer to be implemented.
diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs
index bd424dd9d06..d6b120e4dfc 100644
--- a/compiler/rustc_error_codes/src/lib.rs
+++ b/compiler/rustc_error_codes/src/lib.rs
@@ -5,10 +5,9 @@
 //! the goal being to make their maintenance easier.
 
 macro_rules! register_diagnostics {
-    ($($ecode:ident: $message:expr,)* ; $($code:ident,)*) => (
-        pub static DIAGNOSTICS: &[(&str, Option<&str>)] = &[
-            $( (stringify!($ecode), Some($message)), )*
-            $( (stringify!($code), None), )*
+    ($($ecode:ident: $message:expr,)*) => (
+        pub static DIAGNOSTICS: &[(&str, &str)] = &[
+            $( (stringify!($ecode), $message), )*
         ];
     )
 }
diff --git a/compiler/rustc_error_messages/locales/en-US.ftl b/compiler/rustc_error_messages/locales/en-US.ftl
new file mode 100644
index 00000000000..e6292374448
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US.ftl
@@ -0,0 +1 @@
+# satisfy tidy lint by having a line in this file
diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
deleted file mode 100644
index 5f28839f136..00000000000
--- a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
+++ /dev/null
@@ -1,92 +0,0 @@
-ast_passes_forbidden_let =
-    `let` expressions are not supported here
-    .note = only supported directly in conditions of `if` and `while` expressions
-    .not_supported_or = `||` operators are not supported in let chain expressions
-    .not_supported_parentheses = `let`s wrapped in parentheses are not supported in a context with let chains
-
-ast_passes_forbidden_let_stable =
-    expected expression, found statement (`let`)
-    .note = variable declaration using `let` is a statement
-
-ast_passes_deprecated_where_clause_location =
-    where clause not allowed here
-
-ast_passes_forbidden_assoc_constraint =
-    associated type bounds are not allowed within structs, enums, or unions
-
-ast_passes_keyword_lifetime =
-    lifetimes cannot use keyword names
-
-ast_passes_invalid_label =
-    invalid label name `{$name}`
-
-ast_passes_invalid_visibility =
-    unnecessary visibility qualifier
-    .implied = `pub` not permitted here because it's implied
-    .individual_impl_items = place qualifiers on individual impl items instead
-    .individual_foreign_items = place qualifiers on individual foreign items instead
-
-ast_passes_trait_fn_const =
-    functions in traits cannot be declared const
-    .label = functions in traits cannot be const
-
-ast_passes_forbidden_lifetime_bound =
-    lifetime bounds cannot be used in this context
-
-ast_passes_forbidden_non_lifetime_param =
-    only lifetime parameters can be used in this context
-
-ast_passes_fn_param_too_many =
-    function can not have more than {$max_num_args} arguments
-
-ast_passes_fn_param_c_var_args_only =
-    C-variadic function must be declared with at least one named argument
-
-ast_passes_fn_param_c_var_args_not_last =
-    `...` must be the last argument of a C-variadic function
-
-ast_passes_fn_param_doc_comment =
-    documentation comments cannot be applied to function parameters
-    .label = doc comments are not allowed here
-
-ast_passes_fn_param_forbidden_attr =
-    allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters
-
-ast_passes_fn_param_forbidden_self =
-    `self` parameter is only allowed in associated functions
-    .label = not semantically valid as function parameter
-    .note = associated functions are those in `impl` or `trait` definitions
-
-ast_passes_forbidden_default =
-    `default` is only allowed on items in trait impls
-    .label = `default` because of this
-
-ast_passes_assoc_const_without_body =
-    associated constant in `impl` without body
-    .suggestion = provide a definition for the constant
-
-ast_passes_assoc_fn_without_body =
-    associated function in `impl` without body
-    .suggestion = provide a definition for the function
-
-ast_passes_assoc_type_without_body =
-    associated type in `impl` without body
-    .suggestion = provide a definition for the type
-
-ast_passes_const_without_body =
-    free constant item without body
-    .suggestion = provide a definition for the constant
-
-ast_passes_static_without_body =
-    free static item without body
-    .suggestion = provide a definition for the static
-
-ast_passes_ty_alias_without_body =
-    free type alias without body
-    .suggestion = provide a definition for the type
-
-ast_passes_fn_without_body =
-    free function without a body
-    .suggestion = provide a definition for the function
-
-ast_passes_extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block
diff --git a/compiler/rustc_error_messages/locales/en-US/errors.ftl b/compiler/rustc_error_messages/locales/en-US/errors.ftl
deleted file mode 100644
index 429bdd2777f..00000000000
--- a/compiler/rustc_error_messages/locales/en-US/errors.ftl
+++ /dev/null
@@ -1,13 +0,0 @@
-errors_target_invalid_address_space = invalid address space `{$addr_space}` for `{$cause}` in "data-layout": {$err}
-
-errors_target_invalid_bits = invalid {$kind} `{$bit}` for `{$cause}` in "data-layout": {$err}
-
-errors_target_missing_alignment = missing alignment for `{$cause}` in "data-layout"
-
-errors_target_invalid_alignment = invalid alignment for `{$cause}` in "data-layout": {$err}
-
-errors_target_inconsistent_architecture = inconsistent target specification: "data-layout" claims architecture is {$dl}-endian, while "target-endian" is `{$target}`
-
-errors_target_inconsistent_pointer_width = inconsistent target specification: "data-layout" claims pointers are {$pointer_size}-bit, while "target-pointer-width" is `{$target}`
-
-errors_target_invalid_bits_size = {$err}
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index 579466ed366..010e5f060bf 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -34,47 +34,7 @@ use intl_memoizer::IntlLangMemoizer;
 pub use fluent_bundle::{self, types::FluentType, FluentArgs, FluentError, FluentValue};
 pub use unic_langid::{langid, LanguageIdentifier};
 
-// Generates `DEFAULT_LOCALE_RESOURCES` static and `fluent_generated` module.
-fluent_messages! {
-    // tidy-alphabetical-start
-    ast_lowering => "../locales/en-US/ast_lowering.ftl",
-    ast_passes => "../locales/en-US/ast_passes.ftl",
-    attr => "../locales/en-US/attr.ftl",
-    borrowck => "../locales/en-US/borrowck.ftl",
-    builtin_macros => "../locales/en-US/builtin_macros.ftl",
-    codegen_gcc => "../locales/en-US/codegen_gcc.ftl",
-    codegen_llvm => "../locales/en-US/codegen_llvm.ftl",
-    codegen_ssa => "../locales/en-US/codegen_ssa.ftl",
-    compiletest => "../locales/en-US/compiletest.ftl",
-    const_eval => "../locales/en-US/const_eval.ftl",
-    driver => "../locales/en-US/driver.ftl",
-    errors => "../locales/en-US/errors.ftl",
-    expand => "../locales/en-US/expand.ftl",
-    hir_analysis => "../locales/en-US/hir_analysis.ftl",
-    hir_typeck => "../locales/en-US/hir_typeck.ftl",
-    incremental => "../locales/en-US/incremental.ftl",
-    infer => "../locales/en-US/infer.ftl",
-    interface => "../locales/en-US/interface.ftl",
-    lint => "../locales/en-US/lint.ftl",
-    metadata => "../locales/en-US/metadata.ftl",
-    middle => "../locales/en-US/middle.ftl",
-    mir_build => "../locales/en-US/mir_build.ftl",
-    mir_dataflow => "../locales/en-US/mir_dataflow.ftl",
-    monomorphize => "../locales/en-US/monomorphize.ftl",
-    parse => "../locales/en-US/parse.ftl",
-    passes => "../locales/en-US/passes.ftl",
-    plugin_impl => "../locales/en-US/plugin_impl.ftl",
-    privacy => "../locales/en-US/privacy.ftl",
-    query_system => "../locales/en-US/query_system.ftl",
-    resolve => "../locales/en-US/resolve.ftl",
-    session => "../locales/en-US/session.ftl",
-    symbol_mangling => "../locales/en-US/symbol_mangling.ftl",
-    trait_selection => "../locales/en-US/trait_selection.ftl",
-    ty_utils => "../locales/en-US/ty_utils.ftl",
-    // tidy-alphabetical-end
-}
-
-pub use fluent_generated::{self as fluent, DEFAULT_LOCALE_RESOURCES};
+fluent_messages! { "../locales/en-US.ftl" }
 
 pub type FluentBundle = fluent_bundle::bundle::FluentBundle<FluentResource, IntlLangMemoizer>;
 
@@ -175,7 +135,10 @@ pub fn fluent_bundle(
 
     let fallback_locale = langid!("en-US");
     let requested_fallback_locale = requested_locale.as_ref() == Some(&fallback_locale);
-
+    trace!(?requested_fallback_locale);
+    if requested_fallback_locale && additional_ftl_path.is_none() {
+        return Ok(None);
+    }
     // If there is only `-Z additional-ftl-path`, assume locale is "en-US", otherwise use user
     // provided locale.
     let locale = requested_locale.clone().unwrap_or(fallback_locale);
@@ -193,7 +156,7 @@ pub fn fluent_bundle(
     bundle.set_use_isolating(with_directionality_markers);
 
     // If the user requests the default locale then don't try to load anything.
-    if !requested_fallback_locale && let Some(requested_locale) = requested_locale {
+    if let Some(requested_locale) = requested_locale {
         let mut found_resources = false;
         for sysroot in user_provided_sysroot.iter_mut().chain(sysroot_candidates.iter_mut()) {
             sysroot.push("share");
@@ -263,7 +226,7 @@ pub type LazyFallbackBundle = Lrc<Lazy<FluentBundle, impl FnOnce() -> FluentBund
 /// Return the default `FluentBundle` with standard "en-US" diagnostic messages.
 #[instrument(level = "trace")]
 pub fn fallback_fluent_bundle(
-    resources: &'static [&'static str],
+    resources: Vec<&'static str>,
     with_directionality_markers: bool,
 ) -> LazyFallbackBundle {
     Lrc::new(Lazy::new(move || {
diff --git a/compiler/rustc_errors/locales/en-US.ftl b/compiler/rustc_errors/locales/en-US.ftl
new file mode 100644
index 00000000000..dde1d6c0a81
--- /dev/null
+++ b/compiler/rustc_errors/locales/en-US.ftl
@@ -0,0 +1,19 @@
+errors_target_invalid_address_space =
+    invalid address space `{$addr_space}` for `{$cause}` in "data-layout": {$err}
+
+errors_target_invalid_bits =
+    invalid {$kind} `{$bit}` for `{$cause}` in "data-layout": {$err}
+
+errors_target_missing_alignment =
+    missing alignment for `{$cause}` in "data-layout"
+
+errors_target_invalid_alignment =
+    invalid alignment for `{$cause}` in "data-layout": {$err}
+
+errors_target_inconsistent_architecture =
+    inconsistent target specification: "data-layout" claims architecture is {$dl}-endian, while "target-endian" is `{$target}`
+
+errors_target_inconsistent_pointer_width =
+    inconsistent target specification: "data-layout" claims pointers are {$pointer_size}-bit, while "target-pointer-width" is `{$target}`
+
+errors_target_invalid_bits_size = {$err}
diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs
index 5ada85d04b0..e82bad67b21 100644
--- a/compiler/rustc_errors/src/diagnostic_impls.rs
+++ b/compiler/rustc_errors/src/diagnostic_impls.rs
@@ -1,6 +1,5 @@
-use crate::{
-    fluent, DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg,
-};
+use crate::fluent_generated as fluent;
+use crate::{DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg};
 use rustc_ast as ast;
 use rustc_ast_pretty::pprust;
 use rustc_hir as hir;
@@ -55,6 +54,7 @@ macro_rules! into_diagnostic_arg_using_display {
 }
 
 into_diagnostic_arg_using_display!(
+    ast::ParamKindOrd,
     i8,
     u8,
     i16,
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs
index e475fc725c3..f32d6b96b9b 100644
--- a/compiler/rustc_errors/src/json.rs
+++ b/compiler/rustc_errors/src/json.rs
@@ -580,7 +580,7 @@ impl DiagnosticCode {
             let je_result =
                 je.registry.as_ref().map(|registry| registry.try_find_description(&s)).unwrap();
 
-            DiagnosticCode { code: s, explanation: je_result.unwrap_or(None) }
+            DiagnosticCode { code: s, explanation: je_result.ok() }
         })
     }
 }
diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs
index f161532d3b7..671dc449eaa 100644
--- a/compiler/rustc_errors/src/json/tests.rs
+++ b/compiler/rustc_errors/src/json/tests.rs
@@ -46,7 +46,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         sm.new_source_file(Path::new("test.rs").to_owned().into(), code.to_owned());
         let fallback_bundle =
-            crate::fallback_fluent_bundle(rustc_error_messages::DEFAULT_LOCALE_RESOURCES, false);
+            crate::fallback_fluent_bundle(vec![crate::DEFAULT_LOCALE_RESOURCE], false);
 
         let output = Arc::new(Mutex::new(Vec::new()));
         let je = JsonEmitter::new(
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 8c39feca88a..cbf595089cc 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -36,13 +36,13 @@ use rustc_data_structures::stable_hasher::StableHasher;
 use rustc_data_structures::sync::{self, Lock, Lrc};
 use rustc_data_structures::AtomicRef;
 pub use rustc_error_messages::{
-    fallback_fluent_bundle, fluent, fluent_bundle, DelayDm, DiagnosticMessage, FluentBundle,
+    fallback_fluent_bundle, fluent_bundle, DelayDm, DiagnosticMessage, FluentBundle,
     LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagnosticMessage,
-    DEFAULT_LOCALE_RESOURCES,
 };
 pub use rustc_lint_defs::{pluralize, Applicability};
+use rustc_macros::fluent_messages;
 use rustc_span::source_map::SourceMap;
-use rustc_span::HashStableContext;
+pub use rustc_span::ErrorGuaranteed;
 use rustc_span::{Loc, Span};
 
 use std::borrow::Cow;
@@ -76,6 +76,8 @@ pub use snippet::Style;
 pub type PErr<'a> = DiagnosticBuilder<'a, ErrorGuaranteed>;
 pub type PResult<'a, T> = Result<T, PErr<'a>>;
 
+fluent_messages! { "../locales/en-US.ftl" }
+
 // `PResult` is used a lot. Make sure it doesn't unintentionally get bigger.
 // (See also the comment on `DiagnosticBuilderInner`'s `diagnostic` field.)
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
@@ -1475,9 +1477,7 @@ impl HandlerInner {
                 .emitted_diagnostic_codes
                 .iter()
                 .filter_map(|x| match &x {
-                    DiagnosticId::Error(s)
-                        if registry.try_find_description(s).map_or(false, |o| o.is_some()) =>
-                    {
+                    DiagnosticId::Error(s) if registry.try_find_description(s).is_ok() => {
                         Some(s.clone())
                     }
                     _ => None,
@@ -1844,17 +1844,3 @@ pub enum TerminalUrl {
     Yes,
     Auto,
 }
-
-/// Useful type to use with `Result<>` indicate that an error has already
-/// been reported to the user, so no need to continue checking.
-#[derive(Clone, Copy, Debug, Encodable, Decodable, Hash, PartialEq, Eq, PartialOrd, Ord)]
-#[derive(HashStable_Generic)]
-pub struct ErrorGuaranteed(());
-
-impl ErrorGuaranteed {
-    /// To be used only if you really know what you are doing... ideally, we would find a way to
-    /// eliminate all calls to this method.
-    pub fn unchecked_claim_error_was_emitted() -> Self {
-        ErrorGuaranteed(())
-    }
-}
diff --git a/compiler/rustc_errors/src/registry.rs b/compiler/rustc_errors/src/registry.rs
index da764d993bb..f26d8e7ebdc 100644
--- a/compiler/rustc_errors/src/registry.rs
+++ b/compiler/rustc_errors/src/registry.rs
@@ -5,21 +5,17 @@ pub struct InvalidErrorCode;
 
 #[derive(Clone)]
 pub struct Registry {
-    long_descriptions: FxHashMap<&'static str, Option<&'static str>>,
+    long_descriptions: FxHashMap<&'static str, &'static str>,
 }
 
 impl Registry {
-    pub fn new(long_descriptions: &[(&'static str, Option<&'static str>)]) -> Registry {
+    pub fn new(long_descriptions: &[(&'static str, &'static str)]) -> Registry {
         Registry { long_descriptions: long_descriptions.iter().copied().collect() }
     }
 
     /// Returns `InvalidErrorCode` if the code requested does not exist in the
-    /// registry. Otherwise, returns an `Option` where `None` means the error
-    /// code is valid but has no extended information.
-    pub fn try_find_description(
-        &self,
-        code: &str,
-    ) -> Result<Option<&'static str>, InvalidErrorCode> {
+    /// registry.
+    pub fn try_find_description(&self, code: &str) -> Result<&'static str, InvalidErrorCode> {
         self.long_descriptions.get(code).copied().ok_or(InvalidErrorCode)
     }
 }
diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs
index addfc9726ca..ed35eb1b6c4 100644
--- a/compiler/rustc_errors/src/translation.rs
+++ b/compiler/rustc_errors/src/translation.rs
@@ -1,9 +1,10 @@
-use crate::error::TranslateError;
+use crate::error::{TranslateError, TranslateErrorKind};
 use crate::snippet::Style;
 use crate::{DiagnosticArg, DiagnosticMessage, FluentBundle};
 use rustc_data_structures::sync::Lrc;
 use rustc_error_messages::FluentArgs;
 use std::borrow::Cow;
+use std::env;
 use std::error::Report;
 
 /// Convert diagnostic arguments (a rustc internal type that exists to implement
@@ -94,12 +95,29 @@ pub trait Translate {
                 // The primary bundle was present and translation succeeded
                 Some(Ok(t)) => t,
 
-                // Always yeet out for errors on debug
-                Some(Err(primary)) if cfg!(debug_assertions) => do yeet primary,
-
                 // If `translate_with_bundle` returns `Err` with the primary bundle, this is likely
-                // just that the primary bundle doesn't contain the message being translated or
-                // something else went wrong) so proceed to the fallback bundle.
+                // just that the primary bundle doesn't contain the message being translated, so
+                // proceed to the fallback bundle.
+                Some(Err(
+                    primary @ TranslateError::One {
+                        kind: TranslateErrorKind::MessageMissing, ..
+                    },
+                )) => translate_with_bundle(self.fallback_fluent_bundle())
+                    .map_err(|fallback| primary.and(fallback))?,
+
+                // Always yeet out for errors on debug (unless
+                // `RUSTC_TRANSLATION_NO_DEBUG_ASSERT` is set in the environment - this allows
+                // local runs of the test suites, of builds with debug assertions, to test the
+                // behaviour in a normal build).
+                Some(Err(primary))
+                    if cfg!(debug_assertions)
+                        && env::var("RUSTC_TRANSLATION_NO_DEBUG_ASSERT").is_err() =>
+                {
+                    do yeet primary
+                }
+
+                // ..otherwise, for end users, an error about this wouldn't be useful or actionable, so
+                // just hide it and try with the fallback bundle.
                 Some(Err(primary)) => translate_with_bundle(self.fallback_fluent_bundle())
                     .map_err(|fallback| primary.and(fallback))?,
 
diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml
index 192f54171ce..c971714e05b 100644
--- a/compiler/rustc_expand/Cargo.toml
+++ b/compiler/rustc_expand/Cargo.toml
@@ -24,5 +24,5 @@ rustc_serialize = { path = "../rustc_serialize" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-thin-vec = "0.2.8"
+thin-vec = "0.2.12"
 tracing = "0.1"
diff --git a/compiler/rustc_error_messages/locales/en-US/expand.ftl b/compiler/rustc_expand/locales/en-US.ftl
index dbd80954382..b475d285f6b 100644
--- a/compiler/rustc_error_messages/locales/en-US/expand.ftl
+++ b/compiler/rustc_expand/locales/en-US.ftl
@@ -129,3 +129,7 @@ expand_module_multiple_candidates =
     .help = delete or rename one of them to remove the ambiguity
 
 expand_trace_macro = trace_macro
+
+expand_proc_macro_panicked =
+    proc macro panicked
+    .help = message: {$message}
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 00c5fe791f9..22bc90f5cac 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -29,10 +29,11 @@ use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{BytePos, FileName, Span, DUMMY_SP};
 use smallvec::{smallvec, SmallVec};
-
+use std::default::Default;
 use std::iter;
 use std::path::{Path, PathBuf};
 use std::rc::Rc;
+use thin_vec::ThinVec;
 
 pub(crate) use rustc_span::hygiene::MacroKind;
 
@@ -554,7 +555,7 @@ impl DummyResult {
     pub fn raw_expr(sp: Span, is_error: bool) -> P<ast::Expr> {
         P(ast::Expr {
             id: ast::DUMMY_NODE_ID,
-            kind: if is_error { ast::ExprKind::Err } else { ast::ExprKind::Tup(Vec::new()) },
+            kind: if is_error { ast::ExprKind::Err } else { ast::ExprKind::Tup(ThinVec::new()) },
             span: sp,
             attrs: ast::AttrVec::new(),
             tokens: None,
@@ -570,7 +571,7 @@ impl DummyResult {
     pub fn raw_ty(sp: Span, is_error: bool) -> P<ast::Ty> {
         P(ast::Ty {
             id: ast::DUMMY_NODE_ID,
-            kind: if is_error { ast::TyKind::Err } else { ast::TyKind::Tup(Vec::new()) },
+            kind: if is_error { ast::TyKind::Err } else { ast::TyKind::Tup(ThinVec::new()) },
             span: sp,
             tokens: None,
         })
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index b4c12651e7a..8a78c3296f9 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -5,7 +5,7 @@ use rustc_ast::{attr, token, util::literal};
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
-use thin_vec::ThinVec;
+use thin_vec::{thin_vec, ThinVec};
 
 impl<'a> ExtCtxt<'a> {
     pub fn path(&self, span: Span, strs: Vec<Ident>) -> ast::Path {
@@ -125,7 +125,7 @@ impl<'a> ExtCtxt<'a> {
 
     pub fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef {
         ast::PolyTraitRef {
-            bound_generic_params: Vec::new(),
+            bound_generic_params: ThinVec::new(),
             trait_ref: self.trait_ref(path),
             span,
         }
@@ -221,14 +221,14 @@ impl<'a> ExtCtxt<'a> {
     pub fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> {
         self.block(
             expr.span,
-            vec![ast::Stmt {
+            thin_vec![ast::Stmt {
                 id: ast::DUMMY_NODE_ID,
                 span: expr.span,
                 kind: ast::StmtKind::Expr(expr),
             }],
         )
     }
-    pub fn block(&self, span: Span, stmts: Vec<ast::Stmt>) -> P<ast::Block> {
+    pub fn block(&self, span: Span, stmts: ThinVec<ast::Stmt>) -> P<ast::Block> {
         P(ast::Block {
             stmts,
             id: ast::DUMMY_NODE_ID,
@@ -284,18 +284,23 @@ impl<'a> ExtCtxt<'a> {
         &self,
         span: Span,
         expr: P<ast::Expr>,
-        args: Vec<P<ast::Expr>>,
+        args: ThinVec<P<ast::Expr>>,
     ) -> P<ast::Expr> {
         self.expr(span, ast::ExprKind::Call(expr, args))
     }
-    pub fn expr_call_ident(&self, span: Span, id: Ident, args: Vec<P<ast::Expr>>) -> P<ast::Expr> {
+    pub fn expr_call_ident(
+        &self,
+        span: Span,
+        id: Ident,
+        args: ThinVec<P<ast::Expr>>,
+    ) -> P<ast::Expr> {
         self.expr(span, ast::ExprKind::Call(self.expr_ident(span, id), args))
     }
     pub fn expr_call_global(
         &self,
         sp: Span,
         fn_path: Vec<Ident>,
-        args: Vec<P<ast::Expr>>,
+        args: ThinVec<P<ast::Expr>>,
     ) -> P<ast::Expr> {
         let pathexpr = self.expr_path(self.path_global(sp, fn_path));
         self.expr_call(sp, pathexpr, args)
@@ -318,7 +323,7 @@ impl<'a> ExtCtxt<'a> {
         &self,
         span: Span,
         path: ast::Path,
-        fields: Vec<ast::ExprField>,
+        fields: ThinVec<ast::ExprField>,
     ) -> P<ast::Expr> {
         self.expr(
             span,
@@ -334,7 +339,7 @@ impl<'a> ExtCtxt<'a> {
         &self,
         span: Span,
         id: Ident,
-        fields: Vec<ast::ExprField>,
+        fields: ThinVec<ast::ExprField>,
     ) -> P<ast::Expr> {
         self.expr_struct(span, self.path_ident(span, id), fields)
     }
@@ -372,12 +377,12 @@ impl<'a> ExtCtxt<'a> {
     }
 
     /// `[expr1, expr2, ...]`
-    pub fn expr_array(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
+    pub fn expr_array(&self, sp: Span, exprs: ThinVec<P<ast::Expr>>) -> P<ast::Expr> {
         self.expr(sp, ast::ExprKind::Array(exprs))
     }
 
     /// `&[expr1, expr2, ...]`
-    pub fn expr_array_ref(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
+    pub fn expr_array_ref(&self, sp: Span, exprs: ThinVec<P<ast::Expr>>) -> P<ast::Expr> {
         self.expr_addr_of(sp, self.expr_array(sp, exprs))
     }
 
@@ -387,14 +392,14 @@ impl<'a> ExtCtxt<'a> {
 
     pub fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
         let some = self.std_path(&[sym::option, sym::Option, sym::Some]);
-        self.expr_call_global(sp, some, vec![expr])
+        self.expr_call_global(sp, some, thin_vec![expr])
     }
 
     pub fn expr_none(&self, sp: Span) -> P<ast::Expr> {
         let none = self.std_path(&[sym::option, sym::Option, sym::None]);
         self.expr_path(self.path_global(sp, none))
     }
-    pub fn expr_tuple(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
+    pub fn expr_tuple(&self, sp: Span, exprs: ThinVec<P<ast::Expr>>) -> P<ast::Expr> {
         self.expr(sp, ast::ExprKind::Tup(exprs))
     }
 
@@ -402,7 +407,7 @@ impl<'a> ExtCtxt<'a> {
         self.expr_call_global(
             span,
             [sym::std, sym::rt, sym::begin_panic].iter().map(|s| Ident::new(*s, span)).collect(),
-            vec![self.expr_str(span, msg)],
+            thin_vec![self.expr_str(span, msg)],
         )
     }
 
@@ -412,7 +417,7 @@ impl<'a> ExtCtxt<'a> {
 
     pub fn expr_ok(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
         let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]);
-        self.expr_call_global(sp, ok, vec![expr])
+        self.expr_call_global(sp, ok, thin_vec![expr])
     }
 
     pub fn expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr> {
@@ -426,12 +431,12 @@ impl<'a> ExtCtxt<'a> {
         let binding_expr = self.expr_ident(sp, binding_variable);
 
         // `Ok(__try_var)` pattern
-        let ok_pat = self.pat_tuple_struct(sp, ok_path, vec![binding_pat.clone()]);
+        let ok_pat = self.pat_tuple_struct(sp, ok_path, thin_vec![binding_pat.clone()]);
 
         // `Err(__try_var)` (pattern and expression respectively)
-        let err_pat = self.pat_tuple_struct(sp, err_path.clone(), vec![binding_pat]);
+        let err_pat = self.pat_tuple_struct(sp, err_path.clone(), thin_vec![binding_pat]);
         let err_inner_expr =
-            self.expr_call(sp, self.expr_path(err_path), vec![binding_expr.clone()]);
+            self.expr_call(sp, self.expr_path(err_path), thin_vec![binding_expr.clone()]);
         // `return Err(__try_var)`
         let err_expr = self.expr(sp, ast::ExprKind::Ret(Some(err_inner_expr)));
 
@@ -441,7 +446,7 @@ impl<'a> ExtCtxt<'a> {
         let err_arm = self.arm(sp, err_pat, err_expr);
 
         // `match head { Ok() => ..., Err() => ... }`
-        self.expr_match(sp, head, vec![ok_arm, err_arm])
+        self.expr_match(sp, head, thin_vec![ok_arm, err_arm])
     }
 
     pub fn pat(&self, span: Span, kind: PatKind) -> P<ast::Pat> {
@@ -473,7 +478,7 @@ impl<'a> ExtCtxt<'a> {
         &self,
         span: Span,
         path: ast::Path,
-        subpats: Vec<P<ast::Pat>>,
+        subpats: ThinVec<P<ast::Pat>>,
     ) -> P<ast::Pat> {
         self.pat(span, PatKind::TupleStruct(None, path, subpats))
     }
@@ -481,18 +486,18 @@ impl<'a> ExtCtxt<'a> {
         &self,
         span: Span,
         path: ast::Path,
-        field_pats: Vec<ast::PatField>,
+        field_pats: ThinVec<ast::PatField>,
     ) -> P<ast::Pat> {
         self.pat(span, PatKind::Struct(None, path, field_pats, false))
     }
-    pub fn pat_tuple(&self, span: Span, pats: Vec<P<ast::Pat>>) -> P<ast::Pat> {
+    pub fn pat_tuple(&self, span: Span, pats: ThinVec<P<ast::Pat>>) -> P<ast::Pat> {
         self.pat(span, PatKind::Tuple(pats))
     }
 
     pub fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
         let some = self.std_path(&[sym::option, sym::Option, sym::Some]);
         let path = self.path_global(span, some);
-        self.pat_tuple_struct(span, path, vec![pat])
+        self.pat_tuple_struct(span, path, thin_vec![pat])
     }
 
     pub fn arm(&self, span: Span, pat: P<ast::Pat>, expr: P<ast::Expr>) -> ast::Arm {
@@ -511,7 +516,7 @@ impl<'a> ExtCtxt<'a> {
         self.arm(span, self.pat_wild(span), self.expr_unreachable(span))
     }
 
-    pub fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: Vec<ast::Arm>) -> P<Expr> {
+    pub fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: ThinVec<ast::Arm>) -> P<Expr> {
         self.expr(span, ast::ExprKind::Match(arg, arms))
     }
 
@@ -562,7 +567,12 @@ impl<'a> ExtCtxt<'a> {
         self.lambda(span, vec![ident], body)
     }
 
-    pub fn lambda_stmts_1(&self, span: Span, stmts: Vec<ast::Stmt>, ident: Ident) -> P<ast::Expr> {
+    pub fn lambda_stmts_1(
+        &self,
+        span: Span,
+        stmts: ThinVec<ast::Stmt>,
+        ident: Ident,
+    ) -> P<ast::Expr> {
         self.lambda1(span, self.expr_block(self.block(span, stmts)), ident)
     }
 
@@ -579,7 +589,7 @@ impl<'a> ExtCtxt<'a> {
     }
 
     // `self` is unused but keep it as method for the convenience use.
-    pub fn fn_decl(&self, inputs: Vec<ast::Param>, output: ast::FnRetTy) -> P<ast::FnDecl> {
+    pub fn fn_decl(&self, inputs: ThinVec<ast::Param>, output: ast::FnRetTy) -> P<ast::FnDecl> {
         P(ast::FnDecl { inputs, output })
     }
 
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index 5c845ae6d0b..01500c2c77c 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -24,6 +24,7 @@ use rustc_session::Session;
 use rustc_span::edition::{Edition, ALL_EDITIONS};
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{Span, DUMMY_SP};
+use thin_vec::ThinVec;
 
 /// A folder that strips out items that do not belong in the current configuration.
 pub struct StripUnconfigured<'a> {
@@ -206,7 +207,7 @@ pub fn features(
         None => {
             // The entire crate is unconfigured.
             krate.attrs = ast::AttrVec::new();
-            krate.items = Vec::new();
+            krate.items = ThinVec::new();
             Features::default()
         }
         Some(attrs) => {
diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs
index 9b9697ab13d..70ab222b484 100644
--- a/compiler/rustc_expand/src/errors.rs
+++ b/compiler/rustc_expand/src/errors.rs
@@ -65,7 +65,7 @@ pub(crate) struct MacroConstStability {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(label2)]
+    #[label(expand_label2)]
     pub head_span: Span,
 }
 
@@ -75,7 +75,7 @@ pub(crate) struct MacroBodyStability {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(label2)]
+    #[label(expand_label2)]
     pub head_span: Span,
 }
 
@@ -188,7 +188,7 @@ pub(crate) struct FeatureRemoved<'a> {
 }
 
 #[derive(Subdiagnostic)]
-#[note(reason)]
+#[note(expand_reason)]
 pub(crate) struct FeatureRemovedReason<'a> {
     pub reason: &'a str,
 }
@@ -223,12 +223,12 @@ pub(crate) struct MalformedFeatureAttribute {
 
 #[derive(Subdiagnostic)]
 pub(crate) enum MalformedFeatureAttributeHelp {
-    #[label(expected)]
+    #[label(expand_expected)]
     Label {
         #[primary_span]
         span: Span,
     },
-    #[suggestion(expected, code = "{suggestion}", applicability = "maybe-incorrect")]
+    #[suggestion(expand_expected, code = "{suggestion}", applicability = "maybe-incorrect")]
     Suggestion {
         #[primary_span]
         span: Span,
@@ -306,7 +306,7 @@ pub(crate) struct IncompleteParse<'a> {
     pub kind_name: &'a str,
 
     #[suggestion(
-        suggestion_add_semi,
+        expand_suggestion_add_semi,
         style = "verbose",
         code = ";",
         applicability = "maybe-incorrect"
@@ -340,7 +340,7 @@ pub(crate) struct ModuleInBlock {
 }
 
 #[derive(Subdiagnostic)]
-#[note(note)]
+#[note(expand_note)]
 pub(crate) struct ModuleInBlockName {
     #[primary_span]
     pub span: Span,
@@ -375,3 +375,18 @@ pub struct TraceMacro {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(expand_proc_macro_panicked)]
+pub(crate) struct ProcMacroPanicked {
+    #[primary_span]
+    pub span: Span,
+    #[subdiagnostic]
+    pub message: Option<ProcMacroPanickedHelp>,
+}
+
+#[derive(Subdiagnostic)]
+#[help(expand_help)]
+pub(crate) struct ProcMacroPanickedHelp {
+    pub message: String,
+}
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index 89726856635..634e206e58a 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -20,6 +20,9 @@ extern crate tracing;
 
 extern crate proc_macro as pm;
 
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_macros::fluent_messages;
+
 mod placeholders;
 mod proc_macro_server;
 
@@ -60,3 +63,5 @@ mod tokenstream {
 mod mut_visit {
     mod tests;
 }
+
+fluent_messages! { "../locales/en-US.ftl" }
diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs
index 07f47a9c3a4..3779af19e12 100644
--- a/compiler/rustc_expand/src/module.rs
+++ b/compiler/rustc_expand/src/module.rs
@@ -12,8 +12,8 @@ use rustc_session::Session;
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::Span;
 use std::iter::once;
-
 use std::path::{self, Path, PathBuf};
+use thin_vec::ThinVec;
 
 #[derive(Copy, Clone)]
 pub enum DirOwnership {
@@ -31,7 +31,7 @@ pub struct ModulePathSuccess {
 }
 
 pub(crate) struct ParsedExternalMod {
-    pub items: Vec<P<Item>>,
+    pub items: ThinVec<P<Item>>,
     pub spans: ModSpans,
     pub file_path: PathBuf,
     pub dir_path: PathBuf,
diff --git a/compiler/rustc_expand/src/parse/tests.rs b/compiler/rustc_expand/src/parse/tests.rs
index 0726d922c84..8b37728b60f 100644
--- a/compiler/rustc_expand/src/parse/tests.rs
+++ b/compiler/rustc_expand/src/parse/tests.rs
@@ -18,7 +18,10 @@ use rustc_span::{BytePos, FileName, Pos, Span};
 use std::path::PathBuf;
 
 fn sess() -> ParseSess {
-    ParseSess::new(FilePathMapping::empty())
+    ParseSess::new(
+        vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
+        FilePathMapping::empty(),
+    )
 }
 
 /// Parses an item.
diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs
index e9a69192068..cef64a10479 100644
--- a/compiler/rustc_expand/src/proc_macro.rs
+++ b/compiler/rustc_expand/src/proc_macro.rs
@@ -1,4 +1,5 @@
 use crate::base::{self, *};
+use crate::errors;
 use crate::proc_macro_server;
 
 use rustc_ast as ast;
@@ -60,11 +61,12 @@ impl base::BangProcMacro for BangProcMacro {
         let strategy = exec_strategy(ecx);
         let server = proc_macro_server::Rustc::new(ecx);
         self.client.run(&strategy, server, input, proc_macro_backtrace).map_err(|e| {
-            let mut err = ecx.struct_span_err(span, "proc macro panicked");
-            if let Some(s) = e.as_str() {
-                err.help(&format!("message: {}", s));
-            }
-            err.emit()
+            ecx.sess.emit_err(errors::ProcMacroPanicked {
+                span,
+                message: e
+                    .as_str()
+                    .map(|message| errors::ProcMacroPanickedHelp { message: message.into() }),
+            })
         })
     }
 }
diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs
index f80141403bf..14918d3c190 100644
--- a/compiler/rustc_expand/src/tests.rs
+++ b/compiler/rustc_expand/src/tests.rs
@@ -34,7 +34,10 @@ where
 
 /// Maps a string to tts, using a made-up filename.
 pub(crate) fn string_to_stream(source_str: String) -> TokenStream {
-    let ps = ParseSess::new(FilePathMapping::empty());
+    let ps = ParseSess::new(
+        vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
+        FilePathMapping::empty(),
+    );
     source_file_to_stream(
         &ps,
         ps.source_map().new_source_file(PathBuf::from("bogofile").into(), source_str),
@@ -45,7 +48,10 @@ pub(crate) fn string_to_stream(source_str: String) -> TokenStream {
 
 /// Parses a string, returns a crate.
 pub(crate) fn string_to_crate(source_str: String) -> ast::Crate {
-    let ps = ParseSess::new(FilePathMapping::empty());
+    let ps = ParseSess::new(
+        vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
+        FilePathMapping::empty(),
+    );
     with_error_checking_parse(source_str, &ps, |p| p.parse_crate_mod())
 }
 
@@ -127,8 +133,10 @@ fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &
     create_default_session_if_not_set_then(|_| {
         let output = Arc::new(Mutex::new(Vec::new()));
 
-        let fallback_bundle =
-            rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
+        let fallback_bundle = rustc_errors::fallback_fluent_bundle(
+            vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
+            false,
+        );
         let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         source_map.new_source_file(Path::new("test.rs").to_owned().into(), file_text.to_owned());
 
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 0599ae04a90..8c58129c800 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -124,6 +124,11 @@ pub enum DefKind {
 }
 
 impl DefKind {
+    /// Get an English description for the item's kind.
+    ///
+    /// If you have access to `TyCtxt`, use `TyCtxt::def_descr` or
+    /// `TyCtxt::def_kind_descr` instead, because they give better
+    /// information for generators and associated functions.
     pub fn descr(self, def_id: DefId) -> &'static str {
         match self {
             DefKind::Fn => "function",
@@ -166,6 +171,10 @@ impl DefKind {
     }
 
     /// Gets an English article for the definition.
+    ///
+    /// If you have access to `TyCtxt`, use `TyCtxt::def_descr_article` or
+    /// `TyCtxt::def_kind_descr_article` instead, because they give better
+    /// information for generators and associated functions.
     pub fn article(&self) -> &'static str {
         match *self {
             DefKind::AssocTy
diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs
index cd3c620cbb7..8ceb176491b 100644
--- a/compiler/rustc_hir/src/definitions.rs
+++ b/compiler/rustc_hir/src/definitions.rs
@@ -280,6 +280,8 @@ pub enum DefPathData {
     AnonConst,
     /// An `impl Trait` type node.
     ImplTrait,
+    /// `impl Trait` generated associated type node.
+    ImplTraitAssocTy,
 }
 
 impl Definitions {
@@ -403,7 +405,7 @@ impl DefPathData {
             TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name),
 
             Impl | ForeignMod | CrateRoot | Use | GlobalAsm | ClosureExpr | Ctor | AnonConst
-            | ImplTrait => None,
+            | ImplTrait | ImplTraitAssocTy => None,
         }
     }
 
@@ -422,7 +424,7 @@ impl DefPathData {
             ClosureExpr => DefPathDataName::Anon { namespace: sym::closure },
             Ctor => DefPathDataName::Anon { namespace: sym::constructor },
             AnonConst => DefPathDataName::Anon { namespace: sym::constant },
-            ImplTrait => DefPathDataName::Anon { namespace: sym::opaque },
+            ImplTrait | ImplTraitAssocTy => DefPathDataName::Anon { namespace: sym::opaque },
         }
     }
 }
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 3f52f174cdf..72e9f7c1343 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -369,10 +369,10 @@ impl<'hir> GenericArgs<'hir> {
 
     pub fn has_err(&self) -> bool {
         self.args.iter().any(|arg| match arg {
-            GenericArg::Type(ty) => matches!(ty.kind, TyKind::Err),
+            GenericArg::Type(ty) => matches!(ty.kind, TyKind::Err(_)),
             _ => false,
         }) || self.bindings.iter().any(|arg| match arg.kind {
-            TypeBindingKind::Equality { term: Term::Ty(ty) } => matches!(ty.kind, TyKind::Err),
+            TypeBindingKind::Equality { term: Term::Ty(ty) } => matches!(ty.kind, TyKind::Err(_)),
             _ => false,
         })
     }
@@ -1688,7 +1688,7 @@ impl Expr<'_> {
             ExprKind::Struct(..) => ExprPrecedence::Struct,
             ExprKind::Repeat(..) => ExprPrecedence::Repeat,
             ExprKind::Yield(..) => ExprPrecedence::Yield,
-            ExprKind::Err => ExprPrecedence::Err,
+            ExprKind::Err(_) => ExprPrecedence::Err,
         }
     }
 
@@ -1754,7 +1754,7 @@ impl Expr<'_> {
             | ExprKind::Yield(..)
             | ExprKind::Cast(..)
             | ExprKind::DropTemps(..)
-            | ExprKind::Err => false,
+            | ExprKind::Err(_) => false,
         }
     }
 
@@ -1840,7 +1840,7 @@ impl Expr<'_> {
             | ExprKind::Binary(..)
             | ExprKind::Yield(..)
             | ExprKind::DropTemps(..)
-            | ExprKind::Err => true,
+            | ExprKind::Err(_) => true,
         }
     }
 
@@ -2013,7 +2013,7 @@ pub enum ExprKind<'hir> {
     Yield(&'hir Expr<'hir>, YieldSource),
 
     /// A placeholder for an expression that wasn't syntactically well formed in some way.
-    Err,
+    Err(rustc_span::ErrorGuaranteed),
 }
 
 /// Represents an optionally `Self`-qualified value/type path or associated extension.
@@ -2676,7 +2676,7 @@ pub enum TyKind<'hir> {
     /// specified. This can appear anywhere in a type.
     Infer,
     /// Placeholder for a type that has failed to be defined.
-    Err,
+    Err(rustc_span::ErrorGuaranteed),
 }
 
 #[derive(Debug, HashStable_Generic)]
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index f632babab0b..cc0f64017e4 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -790,7 +790,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
         ExprKind::Yield(ref subexpression, _) => {
             visitor.visit_expr(subexpression);
         }
-        ExprKind::Lit(_) | ExprKind::Err => {}
+        ExprKind::Lit(_) | ExprKind::Err(_) => {}
     }
 }
 
@@ -844,7 +844,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) {
             visitor.visit_lifetime(lifetime);
         }
         TyKind::Typeof(ref expression) => visitor.visit_anon_const(expression),
-        TyKind::Infer | TyKind::Err => {}
+        TyKind::Infer | TyKind::Err(_) => {}
     }
 }
 
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index 04546330915..60fa5a99e10 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -302,8 +302,6 @@ language_item_table! {
     Context,                 sym::Context,             context,                    Target::Struct,         GenericRequirement::None;
     FuturePoll,              sym::poll,                future_poll_fn,             Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
 
-    FromFrom,                sym::from,                from_fn,                    Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
-
     OptionSome,              sym::Some,                option_some_variant,        Target::Variant,        GenericRequirement::None;
     OptionNone,              sym::None,                option_none_variant,        Target::Variant,        GenericRequirement::None;
 
diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml
index c939c8303bf..fab16b80fb5 100644
--- a/compiler/rustc_hir_analysis/Cargo.toml
+++ b/compiler/rustc_hir_analysis/Cargo.toml
@@ -9,7 +9,6 @@ doctest = false
 
 [dependencies]
 rustc_arena = { path = "../rustc_arena" }
-tracing = "0.1"
 rustc_macros = { path = "../rustc_macros" }
 rustc_middle = { path = "../rustc_middle" }
 rustc_attr = { path = "../rustc_attr" }
@@ -27,3 +26,5 @@ rustc_trait_selection = { path = "../rustc_trait_selection" }
 rustc_lint = { path = "../rustc_lint" }
 rustc_type_ir = { path = "../rustc_type_ir" }
 rustc_feature = { path = "../rustc_feature" }
+thin-vec = "0.2.12"
+tracing = "0.1"
diff --git a/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl b/compiler/rustc_hir_analysis/locales/en-US.ftl
index 41f458f6c17..50b0816889b 100644
--- a/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl
+++ b/compiler/rustc_hir_analysis/locales/en-US.ftl
@@ -33,20 +33,7 @@ hir_analysis_field_already_declared =
     .label = field already declared
     .previous_decl_label = `{$field_name}` first declared here
 
-hir_analysis_copy_impl_on_type_with_dtor =
-    the trait `Copy` may not be implemented for this type; the type has a destructor
-    .label = `Copy` not allowed on types with destructors
-
-hir_analysis_multiple_relaxed_default_bounds =
-    type parameter has more than one relaxed default bound, only one is supported
-
-hir_analysis_copy_impl_on_non_adt =
-    the trait `Copy` may not be implemented for this type
-    .label = type is not a structure or enumeration
-
-hir_analysis_trait_object_declared_with_no_traits =
-    at least one trait is required for an object type
-    .alias_span = this alias does not contain a trait
+hir_analysis_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)`
 
 hir_analysis_ambiguous_lifetime_bound =
     ambiguous lifetime bound, explicit lifetime bound required
@@ -68,6 +55,25 @@ hir_analysis_value_of_associated_struct_already_specified =
 hir_analysis_unconstrained_opaque_type = unconstrained opaque type
     .note = `{$name}` must be used in combination with a concrete type within the same {$what}
 
+hir_analysis_manual_implementation =
+    manual implementations of `{$trait_name}` are experimental
+    .label = manual implementations of `{$trait_name}` are experimental
+    .help = add `#![feature(unboxed_closures)]` to the crate attributes to enable
+
+hir_analysis_substs_on_overridden_impl = could not resolve substs on overridden impl
+
+hir_analysis_unused_extern_crate =
+    unused extern crate
+    .suggestion = remove it
+
+hir_analysis_extern_crate_not_idiomatic =
+    `extern crate` is not idiomatic in the new edition
+    .suggestion = convert it to a `{$msg_code}`
+
+hir_analysis_trait_object_declared_with_no_traits =
+    at least one trait is required for an object type
+    .alias_span = this alias does not contain a trait
+
 hir_analysis_missing_type_params =
     the type {$parameterCount ->
         [one] parameter
@@ -90,20 +96,16 @@ hir_analysis_missing_type_params =
     } to {$parameters}
     .note = because of the default `Self` reference, type parameters must be specified on object types
 
-hir_analysis_manual_implementation =
-    manual implementations of `{$trait_name}` are experimental
-    .label = manual implementations of `{$trait_name}` are experimental
-    .help = add `#![feature(unboxed_closures)]` to the crate attributes to enable
-
-hir_analysis_substs_on_overridden_impl = could not resolve substs on overridden impl
+hir_analysis_copy_impl_on_type_with_dtor =
+    the trait `Copy` may not be implemented for this type; the type has a destructor
+    .label = `Copy` not allowed on types with destructors
 
-hir_analysis_unused_extern_crate =
-    unused extern crate
-    .suggestion = remove it
+hir_analysis_multiple_relaxed_default_bounds =
+    type parameter has more than one relaxed default bound, only one is supported
 
-hir_analysis_extern_crate_not_idiomatic =
-    `extern crate` is not idiomatic in the new edition
-    .suggestion = convert it to a `{$msg_code}`
+hir_analysis_copy_impl_on_non_adt =
+    the trait `Copy` may not be implemented for this type
+    .label = type is not a structure or enumeration
 
 hir_analysis_const_impl_for_non_const_trait =
     const `impl` for trait `{$trait_name}` which is not marked with `#[const_trait]`
@@ -124,3 +126,32 @@ hir_analysis_linkage_type =
 hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
     .label = deref recursion limit reached
     .help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
+
+hir_analysis_where_clause_on_main = `main` function is not allowed to have a `where` clause
+    .label = `main` cannot have a `where` clause
+
+hir_analysis_track_caller_on_main = `main` function is not allowed to be `#[track_caller]`
+    .suggestion = remove this annotation
+
+hir_analysis_start_not_track_caller = `start` is not allowed to be `#[track_caller]`
+    .label = `start` is not allowed to be `#[track_caller]`
+
+hir_analysis_start_not_async = `start` is not allowed to be `async`
+    .label = `start` is not allowed to be `async`
+
+hir_analysis_start_function_where = start function is not allowed to have a `where` clause
+    .label = start function cannot have a `where` clause
+
+hir_analysis_start_function_parameters = start function is not allowed to have type parameters
+    .label = start function cannot have type parameters
+
+hir_analysis_main_function_return_type_generic = `main` function return type is not allowed to have generic parameters
+
+hir_analysis_main_function_async = `main` function is not allowed to be `async`
+    .label = `main` function is not allowed to be `async`
+
+hir_analysis_main_function_generic_parameters = `main` function is not allowed to have generic parameters
+    .label = `main` cannot have generic parameters
+
+hir_analysis_variadic_function_compatible_convention = C-variadic function must have a compatible calling convention, like {$conventions}
+    .label = C-variadic function must have a compatible calling convention
diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs
index a68e0e0ac5b..c49e4d9d581 100644
--- a/compiler/rustc_hir_analysis/src/astconv/errors.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs
@@ -304,10 +304,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             if let Some(did) = adt_did {
                 err.span_label(
                     tcx.def_span(did),
-                    format!(
-                        "associated item `{name}` not found for this {}",
-                        tcx.def_kind(did).descr(did)
-                    ),
+                    format!("associated item `{name}` not found for this {}", tcx.def_descr(did)),
                 );
             }
         };
@@ -380,7 +377,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     // `<Foo as Iterator>::Item = String`.
                     let projection_ty = pred.skip_binder().projection_ty;
 
-                    let substs_with_infer_self = tcx.mk_substs(
+                    let substs_with_infer_self = tcx.mk_substs_from_iter(
                         std::iter::once(tcx.mk_ty_var(ty::TyVid::from_u32(0)).into())
                             .chain(projection_ty.substs.iter().skip(1)),
                     );
diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs
index 630becc09d2..7f6518ffd71 100644
--- a/compiler/rustc_hir_analysis/src/astconv/generics.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs
@@ -370,7 +370,7 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
         }
     }
 
-    tcx.intern_substs(&substs)
+    tcx.mk_substs(&substs)
 }
 
 /// Checks that the correct number of generic arguments have been provided.
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index c0cd54cc916..a15cf454df7 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -35,7 +35,7 @@ use rustc_middle::middle::stability::AllowUnstable;
 use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
 use rustc_middle::ty::DynKind;
 use rustc_middle::ty::GenericParamDefKind;
-use rustc_middle::ty::{self, Const, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, Const, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
 use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS};
 use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::edition::Edition;
@@ -381,7 +381,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         // here and so associated type bindings will be handled regardless of whether there are any
         // non-`Self` generic parameters.
         if generics.params.is_empty() {
-            return (tcx.intern_substs(parent_substs), arg_count);
+            return (tcx.mk_substs(parent_substs), arg_count);
         }
 
         struct SubstsForAstPathCtxt<'a, 'tcx> {
@@ -429,7 +429,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     }
                     if let (hir::TyKind::Infer, false) = (&ty.kind, self.astconv.allow_ty_infer()) {
                         self.inferred_params.push(ty.span);
-                        tcx.ty_error().into()
+                        tcx.ty_error_misc().into()
                     } else {
                         self.astconv.ast_ty_to_ty(ty).into()
                     }
@@ -502,14 +502,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                                 _ => false,
                             }) {
                                 // Avoid ICE #86756 when type error recovery goes awry.
-                                return tcx.ty_error().into();
+                                return tcx.ty_error_misc().into();
                             }
                             tcx.at(self.span).type_of(param.def_id).subst(tcx, substs).into()
                         } else if infer_args {
                             self.astconv.ty_infer(Some(param), self.span).into()
                         } else {
                             // We've already errored above about the mismatch.
-                            tcx.ty_error().into()
+                            tcx.ty_error_misc().into()
                         }
                     }
                     GenericParamDefKind::Const { has_default } => {
@@ -518,8 +518,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                             .type_of(param.def_id)
                             .no_bound_vars()
                             .expect("const parameter types cannot be generic");
-                        if ty.references_error() {
-                            return tcx.const_error(ty).into();
+                        if let Err(guar) = ty.error_reported() {
+                            return tcx.const_error_with_guaranteed(ty, guar).into();
                         }
                         if !infer_args && has_default {
                             tcx.const_param_default(param.def_id).subst(tcx, substs.unwrap()).into()
@@ -1217,7 +1217,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     | (hir::def::DefKind::AssocConst, ty::TermKind::Const(_)) => (),
                     (_, _) => {
                         let got = if let Some(_) = term.ty() { "type" } else { "constant" };
-                        let expected = def_kind.descr(assoc_item_def_id);
+                        let expected = tcx.def_descr(assoc_item_def_id);
                         let mut err = tcx.sess.struct_span_err(
                             binding.span,
                             &format!("expected {expected} bound, found {got}"),
@@ -1239,9 +1239,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         }
                         let reported = err.emit();
                         term = match def_kind {
-                            hir::def::DefKind::AssocTy => {
-                                tcx.ty_error_with_guaranteed(reported).into()
-                            }
+                            hir::def::DefKind::AssocTy => tcx.ty_error(reported).into(),
                             hir::def::DefKind::AssocConst => tcx
                                 .const_error_with_guaranteed(
                                     tcx.type_of(assoc_item_def_id)
@@ -1397,7 +1395,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 .map(|trait_ref| tcx.def_span(trait_ref));
             let reported =
                 tcx.sess.emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span });
-            return tcx.ty_error_with_guaranteed(reported);
+            return tcx.ty_error(reported);
         }
 
         // Check that there are no gross object safety violations;
@@ -1414,7 +1412,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     &object_safety_violations,
                 )
                 .emit();
-                return tcx.ty_error_with_guaranteed(reported);
+                return tcx.ty_error(reported);
             }
         }
 
@@ -1523,15 +1521,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         if arg == dummy_self.into() {
                             let param = &generics.params[index];
                             missing_type_params.push(param.name);
-                            return tcx.ty_error().into();
+                            return tcx.ty_error_misc().into();
                         } else if arg.walk().any(|arg| arg == dummy_self.into()) {
                             references_self = true;
-                            return tcx.ty_error().into();
+                            return tcx.ty_error_misc().into();
                         }
                         arg
                     })
                     .collect();
-                let substs = tcx.intern_substs(&substs[..]);
+                let substs = tcx.mk_substs(&substs);
 
                 let span = i.bottom().1;
                 let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| {
@@ -1552,7 +1550,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         i.bottom().1,
                         E0038,
                         "the {} `{}` cannot be made into an object",
-                        tcx.def_kind(def_id).descr(def_id),
+                        tcx.def_descr(def_id),
                         tcx.item_name(def_id),
                     );
                     err.note(
@@ -1579,7 +1577,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     false
                 });
                 if references_self {
-                    tcx.sess
+                    let guar = tcx
+                        .sess
                         .delay_span_bug(span, "trait object projection bounds reference `Self`");
                     let substs: Vec<_> = b
                         .projection_ty
@@ -1587,12 +1586,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         .iter()
                         .map(|arg| {
                             if arg.walk().any(|arg| arg == dummy_self.into()) {
-                                return tcx.ty_error().into();
+                                return tcx.ty_error(guar).into();
                             }
                             arg
                         })
                         .collect();
-                    b.projection_ty.substs = tcx.intern_substs(&substs[..]);
+                    b.projection_ty.substs = tcx.mk_substs(&substs);
                 }
 
                 ty::ExistentialProjection::erase_self_ty(tcx, b)
@@ -1614,7 +1613,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             .collect::<SmallVec<[_; 8]>>();
         v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
         v.dedup();
-        let existential_predicates = tcx.intern_poly_existential_predicates(&v);
+        let existential_predicates = tcx.mk_poly_existential_predicates(&v);
 
         // Use explicitly-specified region bound.
         let region_bound = if !lifetime.is_elided() {
@@ -2174,7 +2173,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                             "`{}` could{} refer to the {} defined here",
                             assoc_ident,
                             also,
-                            kind.descr(def_id)
+                            tcx.def_kind_descr(kind, def_id)
                         );
                         lint.span_note(tcx.def_span(def_id), &note_msg);
                     };
@@ -2350,7 +2349,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         let kind = DefKind::AssocTy;
 
         if !tcx.visibility(item).is_accessible_from(def_scope, tcx) {
-            let kind = kind.descr(item);
+            let kind = tcx.def_kind_descr(kind, item);
             let msg = format!("{kind} `{name}` is private");
             let def_span = tcx.def_span(item);
             tcx.sess
@@ -2473,7 +2472,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 &[path_str],
                 item_segment.ident.name,
             );
-            return tcx.ty_error_with_guaranteed(reported)
+            return tcx.ty_error(reported)
         };
 
         debug!("qpath_to_ty: self_type={:?}", self_ty);
@@ -2811,7 +2810,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                             var: ty::BoundVar::from_u32(index),
                             kind: ty::BoundTyKind::Param(def_id, name),
                         };
-                        tcx.mk_ty(ty::Bound(debruijn, br))
+                        tcx.mk_bound(debruijn, br)
                     }
                     Some(rbv::ResolvedArg::EarlyBound(_)) => {
                         let def_id = def_id.expect_local();
@@ -2820,7 +2819,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         let index = generics.param_def_id_to_index[&def_id.to_def_id()];
                         tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id))
                     }
-                    Some(rbv::ResolvedArg::Error(guar)) => tcx.ty_error_with_guaranteed(guar),
+                    Some(rbv::ResolvedArg::Error(guar)) => tcx.ty_error(guar),
                     arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"),
                 }
             }
@@ -2932,7 +2931,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     {
                         err.span_note(impl_.self_ty.span, "not a concrete type");
                     }
-                    tcx.ty_error_with_guaranteed(err.emit())
+                    tcx.ty_error(err.emit())
                 } else {
                     ty
                 }
@@ -2985,7 +2984,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     .sess
                     .delay_span_bug(path.span, "path with `Res::Err` but no error emitted");
                 self.set_tainted_by_errors(e);
-                self.tcx().ty_error_with_guaranteed(e)
+                self.tcx().ty_error(e)
             }
             _ => span_bug!(span, "unexpected resolution: {:?}", path.res),
         }
@@ -3021,7 +3020,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 tcx.mk_ref(r, ty::TypeAndMut { ty: t, mutbl: mt.mutbl })
             }
             hir::TyKind::Never => tcx.types.never,
-            hir::TyKind::Tup(fields) => tcx.mk_tup(fields.iter().map(|t| self.ast_ty_to_ty(t))),
+            hir::TyKind::Tup(fields) => {
+                tcx.mk_tup_from_iter(fields.iter().map(|t| self.ast_ty_to_ty(t)))
+            }
             hir::TyKind::BareFn(bf) => {
                 require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, ast_ty.span);
 
@@ -3064,7 +3065,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 let ty = self.ast_ty_to_ty_inner(qself, false, true);
                 self.associated_path_to_ty(ast_ty.hir_id, ast_ty.span, ty, qself, segment, false)
                     .map(|(ty, _, _)| ty)
-                    .unwrap_or_else(|_| tcx.ty_error())
+                    .unwrap_or_else(|guar| tcx.ty_error(guar))
             }
             &hir::TyKind::Path(hir::QPath::LangItem(lang_item, span, _)) => {
                 let def_id = tcx.require_lang_item(lang_item, Some(span));
@@ -3112,7 +3113,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 // handled specially and will not descend into this routine.
                 self.ty_infer(None, ast_ty.span)
             }
-            hir::TyKind::Err => tcx.ty_error(),
+            hir::TyKind::Err(guar) => tcx.ty_error(*guar),
         };
 
         self.record_ty(ast_ty.hir_id, result_ty, ast_ty.span);
diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs
index a5c96a8b016..ba2d4319af6 100644
--- a/compiler/rustc_hir_analysis/src/autoderef.rs
+++ b/compiler/rustc_hir_analysis/src/autoderef.rs
@@ -3,7 +3,7 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt;
 use crate::traits::NormalizeExt;
 use crate::traits::{self, TraitEngine, TraitEngineExt};
 use rustc_infer::infer::InferCtxt;
-use rustc_middle::ty::TypeVisitable;
+use rustc_middle::ty::TypeVisitableExt;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::Limit;
 use rustc_span::def_id::LocalDefId;
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 04396c883d3..4ea471f8f05 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -23,6 +23,7 @@ use rustc_middle::ty::subst::GenericArgKind;
 use rustc_middle::ty::util::{Discr, IntTypeExt};
 use rustc_middle::ty::{
     self, AdtDef, DefIdTree, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
+    TypeVisitableExt,
 };
 use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS};
 use rustc_span::symbol::sym;
@@ -255,7 +256,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
         selftys: Vec<(Span, Option<String>)>,
     }
 
-    impl<'tcx> ty::visit::ir::TypeVisitor<TyCtxt<'tcx>> for ProhibitOpaqueVisitor<'tcx> {
+    impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for ProhibitOpaqueVisitor<'tcx> {
         type BreakTy = Ty<'tcx>;
 
         fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
@@ -1418,7 +1419,7 @@ fn opaque_type_cycle_error(
                     opaques: Vec<DefId>,
                     closures: Vec<DefId>,
                 }
-                impl<'tcx> ty::visit::ir::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector {
+                impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector {
                     fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
                         match *t.kind() {
                             ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => {
@@ -1460,7 +1461,7 @@ fn opaque_type_cycle_error(
                                     span,
                                     format!(
                                         "{} captures itself here",
-                                        tcx.def_kind(closure_def_id).descr(closure_def_id)
+                                        tcx.def_descr(closure_def_id)
                                     ),
                                 );
                             }
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 a9fcc8e6250..89b4e6227bd 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -16,7 +16,8 @@ use rustc_infer::traits::util;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::util::ExplicitSelf;
 use rustc_middle::ty::{
-    self, ir::TypeFolder, DefIdTree, InternalSubsts, Ty, TypeFoldable, TypeSuperFoldable,
+    self, DefIdTree, InternalSubsts, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable,
+    TypeVisitableExt,
 };
 use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt};
 use rustc_span::Span;
@@ -195,7 +196,7 @@ fn compare_method_predicate_entailment<'tcx>(
     // the new hybrid bounds we computed.
     let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id);
     let param_env = ty::ParamEnv::new(
-        tcx.intern_predicates(&hybrid_preds.predicates),
+        tcx.mk_predicates(&hybrid_preds.predicates),
         Reveal::UserFacing,
         hir::Constness::NotConst,
     );
@@ -789,7 +790,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
                     return_span,
                     format!("could not fully resolve: {ty} => {err:?}"),
                 );
-                collected_tys.insert(def_id, tcx.ty_error_with_guaranteed(reported));
+                collected_tys.insert(def_id, tcx.ty_error(reported));
             }
         }
     }
@@ -1794,7 +1795,7 @@ fn compare_type_predicate_entailment<'tcx>(
     let impl_ty_span = tcx.def_span(impl_ty_def_id);
     let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_def_id);
     let param_env = ty::ParamEnv::new(
-        tcx.intern_predicates(&hybrid_preds.predicates),
+        tcx.mk_predicates(&hybrid_preds.predicates),
         Reveal::UserFacing,
         hir::Constness::NotConst,
     );
@@ -1936,8 +1937,8 @@ pub(super) fn check_type_bounds<'tcx>(
             .into()
         }
     });
-    let bound_vars = tcx.intern_bound_variable_kinds(&bound_vars);
-    let impl_ty_substs = tcx.intern_substs(&substs);
+    let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars);
+    let impl_ty_substs = tcx.mk_substs(&substs);
     let container_id = impl_ty.container_id(tcx);
 
     let rebased_substs = impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs);
@@ -1977,11 +1978,7 @@ pub(super) fn check_type_bounds<'tcx>(
                 .to_predicate(tcx),
             ),
         };
-        ty::ParamEnv::new(
-            tcx.intern_predicates(&predicates),
-            Reveal::UserFacing,
-            param_env.constness(),
-        )
+        ty::ParamEnv::new(tcx.mk_predicates(&predicates), Reveal::UserFacing, param_env.constness())
     };
     debug!(?normalize_param_env);
 
diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs
index c84e3461226..2bb724138f5 100644
--- a/compiler/rustc_hir_analysis/src/check/dropck.rs
+++ b/compiler/rustc_hir_analysis/src/check/dropck.rs
@@ -71,7 +71,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
 
     let drop_impl_span = tcx.def_span(drop_impl_did);
     let item_span = tcx.def_span(self_type_did);
-    let self_descr = tcx.def_kind(self_type_did).descr(self_type_did);
+    let self_descr = tcx.def_descr(self_type_did);
     let mut err =
         struct_span_err!(tcx.sess, drop_impl_span, E0366, "`Drop` impls cannot be specialized");
     match arg {
@@ -217,7 +217,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
 
         if !assumptions_in_impl_context.iter().copied().any(predicate_matches_closure) {
             let item_span = tcx.def_span(self_type_did);
-            let self_descr = tcx.def_kind(self_type_did).descr(self_type_did.to_def_id());
+            let self_descr = tcx.def_descr(self_type_did.to_def_id());
             let reported = struct_span_err!(
                 tcx.sess,
                 predicate_sp,
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 4720fea8ef4..054284cced5 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -137,7 +137,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
     let intrinsic_name = tcx.item_name(intrinsic_id);
     let name_str = intrinsic_name.as_str();
 
-    let bound_vars = tcx.intern_bound_variable_kinds(&[
+    let bound_vars = tcx.mk_bound_variable_kinds(&[
         ty::BoundVariableKind::Region(ty::BrAnon(0, None)),
         ty::BoundVariableKind::Region(ty::BrEnv),
     ]);
@@ -165,7 +165,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
             "cxchg" | "cxchgweak" => (
                 1,
                 vec![tcx.mk_mut_ptr(param(0)), param(0), param(0)],
-                tcx.intern_tup(&[param(0), tcx.types.bool]),
+                tcx.mk_tup(&[param(0), tcx.types.bool]),
             ),
             "load" => (1, vec![tcx.mk_imm_ptr(param(0))], param(0)),
             "store" => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()),
@@ -317,7 +317,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
             | sym::bitreverse => (1, vec![param(0)], param(0)),
 
             sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => {
-                (1, vec![param(0), param(0)], tcx.intern_tup(&[param(0), tcx.types.bool]))
+                (1, vec![param(0), param(0)], tcx.mk_tup(&[param(0), tcx.types.bool]))
             }
 
             sym::ptr_guaranteed_cmp => {
@@ -372,7 +372,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
                 (
                     1,
                     vec![tcx.mk_imm_ref(tcx.mk_re_late_bound(ty::INNERMOST, br), param(0))],
-                    tcx.mk_projection(discriminant_def_id, tcx.intern_substs(&[param(0).into()])),
+                    tcx.mk_projection(discriminant_def_id, tcx.mk_substs(&[param(0).into()])),
                 )
             }
 
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index b3e76010da3..b1d5a27be93 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -1,7 +1,7 @@
 use rustc_ast::InlineAsmTemplatePiece;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
-use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitable, UintTy};
+use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy};
 use rustc_session::lint;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::{Symbol, DUMMY_SP};
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 5743f086f89..4cccdf30c5f 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -16,8 +16,8 @@ use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::trait_def::TraitSpecializationKind;
 use rustc_middle::ty::{
-    self, ir::TypeVisitor, AdtKind, DefIdTree, GenericParamDefKind, Ty, TyCtxt, TypeFoldable,
-    TypeSuperVisitable,
+    self, AdtKind, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
+    TypeVisitable, TypeVisitableExt, TypeVisitor,
 };
 use rustc_middle::ty::{GenericArgKind, InternalSubsts};
 use rustc_session::parse::feature_err;
@@ -56,7 +56,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
     // `ObligationCtxt::normalize`, but provides a nice `ObligationCauseCode`.
     fn normalize<T>(&self, span: Span, loc: Option<WellFormedLoc>, value: T) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         self.ocx.normalize(
             &ObligationCause::new(span, self.body_def_id, ObligationCauseCode::WellFormed(loc)),
@@ -277,56 +277,6 @@ fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) {
     };
     check_object_unsafe_self_trait_by_name(tcx, trait_item);
     check_associated_item(tcx, def_id, span, method_sig);
-
-    let encl_trait_def_id = tcx.local_parent(def_id);
-    let encl_trait = tcx.hir().expect_item(encl_trait_def_id);
-    let encl_trait_def_id = encl_trait.owner_id.to_def_id();
-    let fn_lang_item_name = if Some(encl_trait_def_id) == tcx.lang_items().fn_trait() {
-        Some("fn")
-    } else if Some(encl_trait_def_id) == tcx.lang_items().fn_mut_trait() {
-        Some("fn_mut")
-    } else {
-        None
-    };
-
-    if let (Some(fn_lang_item_name), "call") =
-        (fn_lang_item_name, trait_item.ident.name.to_ident_string().as_str())
-    {
-        // We are looking at the `call` function of the `fn` or `fn_mut` lang item.
-        // Do some rudimentary sanity checking to avoid an ICE later (issue #83471).
-        if let Some(hir::FnSig { decl, span, .. }) = method_sig {
-            if let [self_ty, _] = decl.inputs {
-                if !matches!(self_ty.kind, hir::TyKind::Ref(_, _)) {
-                    tcx.sess
-                        .struct_span_err(
-                            self_ty.span,
-                            &format!(
-                                "first argument of `call` in `{fn_lang_item_name}` lang item must be a reference",
-                            ),
-                        )
-                        .emit();
-                }
-            } else {
-                tcx.sess
-                    .struct_span_err(
-                        *span,
-                        &format!(
-                            "`call` function in `{fn_lang_item_name}` lang item takes exactly two arguments",
-                        ),
-                    )
-                    .emit();
-            }
-        } else {
-            tcx.sess
-                .struct_span_err(
-                    trait_item.span,
-                    &format!(
-                        "`call` trait item in `{fn_lang_item_name}` lang item must be a function",
-                    ),
-                )
-                .emit();
-        }
-    }
 }
 
 /// Require that the user writes where clauses on GATs for the implicit
@@ -543,8 +493,9 @@ fn augment_param_env<'tcx>(
         return param_env;
     }
 
-    let bounds =
-        tcx.mk_predicates(param_env.caller_bounds().iter().chain(new_predicates.iter().cloned()));
+    let bounds = tcx.mk_predicates_from_iter(
+        param_env.caller_bounds().iter().chain(new_predicates.iter().cloned()),
+    );
     // FIXME(compiler-errors): Perhaps there is a case where we need to normalize this
     // i.e. traits::normalize_param_env_or_error
     ty::ParamEnv::new(bounds, param_env.reveal(), param_env.constness())
@@ -560,7 +511,7 @@ fn augment_param_env<'tcx>(
 ///     fn into_iter<'a>(&'a self) -> Self::Iter<'a>;
 /// }
 /// ```
-fn gather_gat_bounds<'tcx, T: TypeFoldable<'tcx>>(
+fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
     tcx: TyCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     item_def_id: hir::OwnerId,
@@ -758,7 +709,7 @@ struct GATSubstCollector<'tcx> {
 }
 
 impl<'tcx> GATSubstCollector<'tcx> {
-    fn visit<T: TypeFoldable<'tcx>>(
+    fn visit<T: TypeFoldable<TyCtxt<'tcx>>>(
         gat: DefId,
         t: T,
     ) -> (FxHashSet<(ty::Region<'tcx>, usize)>, FxHashSet<(Ty<'tcx>, usize)>) {
@@ -1432,7 +1383,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
             struct CountParams {
                 params: FxHashSet<u32>,
             }
-            impl<'tcx> ty::visit::ir::TypeVisitor<TyCtxt<'tcx>> for CountParams {
+            impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for CountParams {
                 type BreakTy = ();
 
                 fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
@@ -1526,7 +1477,7 @@ fn check_fn_or_method<'tcx>(
         |idx| hir_decl.inputs.get(idx).map_or(hir_decl.output.span(), |arg: &hir::Ty<'_>| arg.span);
 
     sig.inputs_and_output =
-        tcx.mk_type_list(sig.inputs_and_output.iter().enumerate().map(|(idx, ty)| {
+        tcx.mk_type_list_from_iter(sig.inputs_and_output.iter().enumerate().map(|(idx, ty)| {
             wfcx.normalize(
                 arg_span(idx),
                 Some(WellFormedLoc::Param {
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index 51c5f297051..875c5f1fd00 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -11,7 +11,7 @@ use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::infer::{self, RegionResolutionError};
 use rustc_middle::ty::adjustment::CoerceUnsizedInfo;
-use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitableExt};
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
 use rustc_trait_selection::traits::misc::{
     type_allowed_to_implement_copy, CopyImplementationError, InfringingFieldsReason,
diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs
index bbde59c953a..23490bc091c 100644
--- a/compiler/rustc_hir_analysis/src/coherence/mod.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs
@@ -8,7 +8,7 @@
 use rustc_errors::{error_code, struct_span_err};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
 use rustc_span::sym;
 use rustc_trait_selection::traits;
 
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index f0a0e7e3e92..1f2de3f21f8 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -8,7 +8,8 @@ use rustc_hir as hir;
 use rustc_middle::ty::subst::InternalSubsts;
 use rustc_middle::ty::util::IgnoreRegions;
 use rustc_middle::ty::{
-    self, ir::TypeVisitor, AliasKind, ImplPolarity, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
+    self, AliasKind, ImplPolarity, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
+    TypeVisitor,
 };
 use rustc_session::lint;
 use rustc_span::def_id::{DefId, LocalDefId};
@@ -531,7 +532,7 @@ fn lint_auto_trait_impl<'tcx>(
         }),
         |lint| {
             let item_span = tcx.def_span(self_type_did);
-            let self_descr = tcx.def_kind(self_type_did).descr(self_type_did);
+            let self_descr = tcx.def_descr(self_type_did);
             match arg {
                 ty::util::NotUniqueParam::DuplicateParam(arg) => {
                     lint.note(&format!("`{}` is mentioned multiple times", arg));
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index ed3d50bfafa..604d54cafb5 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -499,7 +499,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
                 }
                 _ => {}
             }
-            self.tcx().ty_error_with_guaranteed(err.emit())
+            self.tcx().ty_error(err.emit())
         }
     }
 
@@ -905,7 +905,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AdtDef<'_> {
         }
         _ => bug!(),
     };
-    tcx.alloc_adt_def(def_id.to_def_id(), kind, variants, repr)
+    tcx.mk_adt_def(def_id.to_def_id(), kind, variants, repr)
 }
 
 fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index 8d479f1c3e3..9cf3ff65a91 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -103,7 +103,7 @@ pub(super) fn item_bounds(
     tcx: TyCtxt<'_>,
     def_id: DefId,
 ) -> ty::EarlyBinder<&'_ ty::List<ty::Predicate<'_>>> {
-    let bounds = tcx.mk_predicates(
+    let bounds = tcx.mk_predicates_from_iter(
         util::elaborate_predicates(
             tcx,
             tcx.explicit_item_bounds(def_id).iter().map(|&(bound, _span)| bound),
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 c0c90e47a75..6c00b8ff7bd 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -17,7 +17,8 @@ use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirIdMap, LifetimeNa
 use rustc_middle::bug;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::resolve_bound_vars::*;
-use rustc_middle::ty::{self, ir::TypeVisitor, DefIdTree, TyCtxt, TypeSuperVisitable};
+use rustc_middle::ty::{self, DefIdTree, TyCtxt, TypeSuperVisitable, TypeVisitor};
+use rustc_session::lint;
 use rustc_span::def_id::DefId;
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::Span;
@@ -923,17 +924,16 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                         origin,
                         ..
                     }) => {
-
                         let (bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) =
                             bound_generic_params
-                            .iter()
-                            .enumerate()
-                            .map(|(late_bound_idx, param)| {
-                                let pair = ResolvedArg::late(late_bound_idx as u32, param);
-                                let r = late_arg_as_bound_arg(this.tcx, &pair.1, param);
-                                (pair, r)
-                            })
-                            .unzip();
+                                .iter()
+                                .enumerate()
+                                .map(|(late_bound_idx, param)| {
+                                    let pair = ResolvedArg::late(late_bound_idx as u32, param);
+                                    let r = late_arg_as_bound_arg(this.tcx, &pair.1, param);
+                                    (pair, r)
+                                })
+                                .unzip();
                         this.record_late_bound_vars(hir_id, binders.clone());
                         // Even if there are no lifetimes defined here, we still wrap it in a binder
                         // scope. If there happens to be a nested poly trait ref (an error), that
@@ -968,20 +968,22 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                                     continue;
                                 }
                                 this.insert_lifetime(lt, ResolvedArg::StaticLifetime);
-                                this.tcx
-                                    .sess
-                                    .struct_span_warn(
-                                        lifetime.ident.span,
-                                        &format!(
-                                            "unnecessary lifetime parameter `{}`",
+                                this.tcx.struct_span_lint_hir(
+                                    lint::builtin::UNUSED_LIFETIMES,
+                                    lifetime.hir_id,
+                                    lifetime.ident.span,
+                                    format!(
+                                        "unnecessary lifetime parameter `{}`",
+                                        lifetime.ident
+                                    ),
+                                    |lint| {
+                                        let help = &format!(
+                                            "you can use the `'static` lifetime directly, in place of `{}`",
                                             lifetime.ident,
-                                        ),
-                                    )
-                                    .help(&format!(
-                                        "you can use the `'static` lifetime directly, in place of `{}`",
-                                        lifetime.ident,
-                                    ))
-                                    .emit();
+                                        );
+                                        lint.help(help)
+                                    },
+                                );
                             }
                         }
                     }
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index a3bc0082ef2..50073d94ea5 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -9,7 +9,7 @@ use rustc_middle::ty::print::with_forced_trimmed_paths;
 use rustc_middle::ty::subst::InternalSubsts;
 use rustc_middle::ty::util::IntTypeExt;
 use rustc_middle::ty::{
-    self, ir::TypeFolder, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeSuperFoldable, TypeVisitable,
+    self, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
 };
 use rustc_span::symbol::Ident;
 use rustc_span::{Span, DUMMY_SP};
@@ -319,8 +319,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
                 ItemKind::Impl(hir::Impl { self_ty, .. }) => {
                     match self_ty.find_self_aliases() {
                         spans if spans.len() > 0 => {
-                            tcx.sess.emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: (), });
-                            tcx.ty_error()
+                            let guar = tcx.sess.emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: () });
+                            tcx.ty_error(guar)
                         },
                         _ => icx.to_ty(*self_ty),
                     }
@@ -599,8 +599,9 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
             // // constant does not contain interior mutability.
             // ```
             let tables = self.tcx.typeck(item_def_id);
-            if let Some(_) = tables.tainted_by_errors {
-                self.found = Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: self.tcx.ty_error() });
+            if let Some(guar) = tables.tainted_by_errors {
+                self.found =
+                    Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: self.tcx.ty_error(guar) });
                 return;
             }
             let Some(&typeck_hidden_ty) = tables.concrete_opaque_types.get(&self.def_id) else {
@@ -618,8 +619,8 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
                 debug!(?concrete_type, "found constraint");
                 if let Some(prev) = &mut self.found {
                     if concrete_type.ty != prev.ty && !(concrete_type, prev.ty).references_error() {
-                        prev.report_mismatch(&concrete_type, self.tcx);
-                        prev.ty = self.tcx.ty_error();
+                        let guar = prev.report_mismatch(&concrete_type, self.tcx);
+                        prev.ty = self.tcx.ty_error(guar);
                     }
                 } else {
                     self.found = Some(concrete_type);
@@ -706,7 +707,7 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
                 _ => "item",
             },
         });
-        return tcx.ty_error_with_guaranteed(reported);
+        return tcx.ty_error(reported);
     };
 
     // Only check against typeck if we didn't already error
@@ -814,11 +815,11 @@ fn find_opaque_ty_constraints_for_rpit(
 
     concrete.map(|concrete| concrete.ty).unwrap_or_else(|| {
         let table = tcx.typeck(owner_def_id);
-        if let Some(_) = table.tainted_by_errors {
+        if let Some(guar) = table.tainted_by_errors {
             // Some error in the
             // owner fn prevented us from populating
             // the `concrete_opaque_types` table.
-            tcx.ty_error()
+            tcx.ty_error(guar)
         } else {
             table.concrete_opaque_types.get(&def_id).map(|ty| ty.ty).unwrap_or_else(|| {
                 // We failed to resolve the opaque type or it
diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
index 072676c400d..e18b0f08279 100644
--- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
+++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
@@ -1,5 +1,5 @@
 use rustc_data_structures::fx::FxHashSet;
-use rustc_middle::ty::visit::{ir::TypeVisitor, TypeSuperVisitable, TypeVisitable};
+use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::source_map::Span;
 use std::ops::ControlFlow;
@@ -43,7 +43,7 @@ pub fn parameters_for_impl<'tcx>(
 /// of parameters whose values are needed in order to constrain `ty` - these
 /// differ, with the latter being a superset, in the presence of projections.
 pub fn parameters_for<'tcx>(
-    t: &impl TypeVisitable<'tcx>,
+    t: &impl TypeVisitable<TyCtxt<'tcx>>,
     include_nonconstraining: bool,
 ) -> Vec<Parameter> {
     let mut collector = ParameterCollector { parameters: vec![], include_nonconstraining };
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 04f5f3f6276..a566e73912e 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1,7 +1,10 @@
 //! Errors emitted by `rustc_hir_analysis`.
 
-use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler};
-use rustc_errors::{IntoDiagnostic, MultiSpan};
+use crate::fluent_generated as fluent;
+use rustc_errors::{
+    error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic,
+    MultiSpan,
+};
 use rustc_macros::{Diagnostic, LintDiagnostic};
 use rustc_middle::ty::Ty;
 use rustc_span::{symbol::Ident, Span, Symbol};
@@ -41,11 +44,11 @@ pub struct LifetimesOrBoundsMismatchOnTrait {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(generics_label)]
+    #[label(hir_analysis_generics_label)]
     pub generics_span: Option<Span>,
-    #[label(where_label)]
+    #[label(hir_analysis_where_label)]
     pub where_span: Option<Span>,
-    #[label(bounds_label)]
+    #[label(hir_analysis_bounds_label)]
     pub bounds_span: Vec<Span>,
     pub item_kind: &'static str,
     pub ident: Ident,
@@ -57,7 +60,7 @@ pub struct AsyncTraitImplShouldBeAsync {
     #[primary_span]
     // #[label]
     pub span: Span,
-    #[label(trait_item_label)]
+    #[label(hir_analysis_trait_item_label)]
     pub trait_item_span: Option<Span>,
     pub method_name: Symbol,
 }
@@ -77,7 +80,7 @@ pub struct FieldAlreadyDeclared {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(previous_decl_label)]
+    #[label(hir_analysis_previous_decl_label)]
     pub prev_span: Span,
 }
 
@@ -109,7 +112,7 @@ pub struct CopyImplOnNonAdt {
 pub struct TraitObjectDeclaredWithNoTraits {
     #[primary_span]
     pub span: Span,
-    #[label(alias_span)]
+    #[label(hir_analysis_alias_span)]
     pub trait_alias_span: Option<Span>,
 }
 
@@ -145,7 +148,7 @@ pub struct ValueOfAssociatedStructAlreadySpecified {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(previous_bound_label)]
+    #[label(hir_analysis_previous_bound_label)]
     pub prev_span: Span,
     pub item_name: Ident,
     pub def_path: String,
@@ -175,7 +178,7 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams {
     fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
         let mut err = handler.struct_span_err_with_code(
             self.span,
-            rustc_errors::fluent::hir_analysis_missing_type_params,
+            fluent::hir_analysis_missing_type_params,
             error_code!(E0393),
         );
         err.set_arg("parameterCount", self.missing_type_params.len());
@@ -188,7 +191,7 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams {
                 .join(", "),
         );
 
-        err.span_label(self.def_span, rustc_errors::fluent::label);
+        err.span_label(self.def_span, fluent::hir_analysis_label);
 
         let mut suggested = false;
         // Don't suggest setting the type params if there are some already: the order is
@@ -203,7 +206,7 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams {
                 // least we can clue them to the correct syntax `Iterator<Type>`.
                 err.span_suggestion(
                     self.span,
-                    rustc_errors::fluent::suggestion,
+                    fluent::hir_analysis_suggestion,
                     format!(
                         "{}<{}>",
                         snippet,
@@ -219,10 +222,10 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams {
             }
         }
         if !suggested {
-            err.span_label(self.span, rustc_errors::fluent::no_suggestion_label);
+            err.span_label(self.span, fluent::hir_analysis_no_suggestion_label);
         }
 
-        err.note(rustc_errors::fluent::note);
+        err.note(fluent::hir_analysis_note);
         err
     }
 }
@@ -274,7 +277,7 @@ pub struct ConstImplForNonConstTrait {
     pub local_trait_span: Option<Span>,
     #[note]
     pub marking: (),
-    #[note(adding)]
+    #[note(hir_analysis_adding)]
     pub adding: (),
 }
 
@@ -312,3 +315,89 @@ pub struct AutoDerefReachedRecursionLimit<'a> {
     pub suggested_limit: rustc_session::Limit,
     pub crate_name: Symbol,
 }
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_where_clause_on_main, code = "E0646")]
+pub(crate) struct WhereClauseOnMain {
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub generics_span: Option<Span>,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_track_caller_on_main)]
+pub(crate) struct TrackCallerOnMain {
+    #[primary_span]
+    #[suggestion(applicability = "maybe-incorrect", code = "")]
+    pub span: Span,
+    #[label(hir_analysis_track_caller_on_main)]
+    pub annotated: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_start_not_track_caller)]
+pub(crate) struct StartTrackCaller {
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub start: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_start_not_async, code = "E0752")]
+pub(crate) struct StartAsync {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_start_function_where, code = "E0647")]
+pub(crate) struct StartFunctionWhere {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_start_function_parameters, code = "E0132")]
+pub(crate) struct StartFunctionParameters {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_main_function_return_type_generic, code = "E0131")]
+pub(crate) struct MainFunctionReturnTypeGeneric {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_main_function_async, code = "E0752")]
+pub(crate) struct MainFunctionAsync {
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub asyncness: Option<Span>,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_main_function_generic_parameters, code = "E0131")]
+pub(crate) struct MainFunctionGenericParameters {
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub label_span: Option<Span>,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_variadic_function_compatible_convention, code = "E0045")]
+pub(crate) struct VariadicFunctionCompatibleConvention<'a> {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    pub conventions: &'a str,
+}
diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
index 8fc4610ae85..e330fcc7857 100644
--- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
@@ -5,7 +5,7 @@ use rustc_hir::{ForeignItem, ForeignItemKind};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::{ObligationCause, WellFormedLoc};
 use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{self, ir::TypeFolder, Region, TyCtxt, TypeFoldable};
+use rustc_middle::ty::{self, Region, TyCtxt, TypeFoldable, TypeFolder};
 use rustc_span::def_id::LocalDefId;
 use rustc_trait_selection::traits;
 
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
index 8ab9964d810..82a96f8e674 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
@@ -16,7 +16,7 @@ use rustc_errors::struct_span_err;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
 use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
 use rustc_span::{Span, Symbol};
 
 mod min_specialization;
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
index 4741e4b095d..daa5d15704d 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
@@ -76,7 +76,7 @@ use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::specialization_graph::Node;
 use rustc_middle::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
 use rustc_middle::ty::trait_def::TraitSpecializationKind;
-use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
 use rustc_span::Span;
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
 use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 11240cf22e4..33c132fd534 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -98,10 +98,12 @@ mod outlives;
 pub mod structured_errors;
 mod variance;
 
-use rustc_errors::{struct_span_err, ErrorGuaranteed};
+use rustc_errors::ErrorGuaranteed;
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
 use rustc_hir as hir;
 use rustc_hir::Node;
 use rustc_infer::infer::{InferOk, TyCtxtInferExt};
+use rustc_macros::fluent_messages;
 use rustc_middle::middle;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -118,8 +120,9 @@ use std::ops::Not;
 use astconv::AstConv;
 use bounds::Bounds;
 
+fluent_messages! { "../locales/en-US.ftl" }
+
 fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi, span: Span) {
-    const ERROR_HEAD: &str = "C-variadic function must have a compatible calling convention";
     const CONVENTIONS_UNSTABLE: &str = "`C`, `cdecl`, `win64`, `sysv64` or `efiapi`";
     const CONVENTIONS_STABLE: &str = "`C` or `cdecl`";
     const UNSTABLE_EXPLAIN: &str =
@@ -151,8 +154,7 @@ fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi
         (true, false) => CONVENTIONS_UNSTABLE,
     };
 
-    let mut err = struct_span_err!(tcx.sess, span, E0045, "{}, like {}", ERROR_HEAD, conventions);
-    err.span_label(span, ERROR_HEAD).emit();
+    tcx.sess.emit_err(errors::VariadicFunctionCompatibleConvention { span, conventions });
 }
 
 fn require_same_types<'tcx>(
@@ -254,53 +256,30 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
     let main_fn_predicates = tcx.predicates_of(main_def_id);
     if main_fn_generics.count() != 0 || !main_fnsig.bound_vars().is_empty() {
         let generics_param_span = main_fn_generics_params_span(tcx, main_def_id);
-        let msg = "`main` function is not allowed to have generic \
-            parameters";
-        let mut diag =
-            struct_span_err!(tcx.sess, generics_param_span.unwrap_or(main_span), E0131, "{}", msg);
-        if let Some(generics_param_span) = generics_param_span {
-            let label = "`main` cannot have generic parameters";
-            diag.span_label(generics_param_span, label);
-        }
-        diag.emit();
+        tcx.sess.emit_err(errors::MainFunctionGenericParameters {
+            span: generics_param_span.unwrap_or(main_span),
+            label_span: generics_param_span,
+        });
         error = true;
     } else if !main_fn_predicates.predicates.is_empty() {
         // generics may bring in implicit predicates, so we skip this check if generics is present.
         let generics_where_clauses_span = main_fn_where_clauses_span(tcx, main_def_id);
-        let mut diag = struct_span_err!(
-            tcx.sess,
-            generics_where_clauses_span.unwrap_or(main_span),
-            E0646,
-            "`main` function is not allowed to have a `where` clause"
-        );
-        if let Some(generics_where_clauses_span) = generics_where_clauses_span {
-            diag.span_label(generics_where_clauses_span, "`main` cannot have a `where` clause");
-        }
-        diag.emit();
+        tcx.sess.emit_err(errors::WhereClauseOnMain {
+            span: generics_where_clauses_span.unwrap_or(main_span),
+            generics_span: generics_where_clauses_span,
+        });
         error = true;
     }
 
     let main_asyncness = tcx.asyncness(main_def_id);
     if let hir::IsAsync::Async = main_asyncness {
-        let mut diag = struct_span_err!(
-            tcx.sess,
-            main_span,
-            E0752,
-            "`main` function is not allowed to be `async`"
-        );
         let asyncness_span = main_fn_asyncness_span(tcx, main_def_id);
-        if let Some(asyncness_span) = asyncness_span {
-            diag.span_label(asyncness_span, "`main` function is not allowed to be `async`");
-        }
-        diag.emit();
+        tcx.sess.emit_err(errors::MainFunctionAsync { span: main_span, asyncness: asyncness_span });
         error = true;
     }
 
     for attr in tcx.get_attrs(main_def_id, sym::track_caller) {
-        tcx.sess
-            .struct_span_err(attr.span, "`main` function is not allowed to be `#[track_caller]`")
-            .span_label(main_span, "`main` function is not allowed to be `#[track_caller]`")
-            .emit();
+        tcx.sess.emit_err(errors::TrackCallerOnMain { span: attr.span, annotated: main_span });
         error = true;
     }
 
@@ -313,9 +292,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
         let return_ty = main_fnsig.output();
         let return_ty_span = main_fn_return_type_span(tcx, main_def_id).unwrap_or(main_span);
         if !return_ty.bound_vars().is_empty() {
-            let msg = "`main` function return type is not allowed to have generic \
-                    parameters";
-            struct_span_err!(tcx.sess, return_ty_span, E0131, "{}", msg).emit();
+            tcx.sess.emit_err(errors::MainFunctionReturnTypeGeneric { span: return_ty_span });
             error = true;
         }
         let return_ty = return_ty.skip_binder();
@@ -372,56 +349,28 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
                 if let hir::ItemKind::Fn(sig, generics, _) = &it.kind {
                     let mut error = false;
                     if !generics.params.is_empty() {
-                        struct_span_err!(
-                            tcx.sess,
-                            generics.span,
-                            E0132,
-                            "start function is not allowed to have type parameters"
-                        )
-                        .span_label(generics.span, "start function cannot have type parameters")
-                        .emit();
+                        tcx.sess.emit_err(errors::StartFunctionParameters { span: generics.span });
                         error = true;
                     }
                     if generics.has_where_clause_predicates {
-                        struct_span_err!(
-                            tcx.sess,
-                            generics.where_clause_span,
-                            E0647,
-                            "start function is not allowed to have a `where` clause"
-                        )
-                        .span_label(
-                            generics.where_clause_span,
-                            "start function cannot have a `where` clause",
-                        )
-                        .emit();
+                        tcx.sess.emit_err(errors::StartFunctionWhere {
+                            span: generics.where_clause_span,
+                        });
                         error = true;
                     }
                     if let hir::IsAsync::Async = sig.header.asyncness {
                         let span = tcx.def_span(it.owner_id);
-                        struct_span_err!(
-                            tcx.sess,
-                            span,
-                            E0752,
-                            "`start` is not allowed to be `async`"
-                        )
-                        .span_label(span, "`start` is not allowed to be `async`")
-                        .emit();
+                        tcx.sess.emit_err(errors::StartAsync { span: span });
                         error = true;
                     }
 
                     let attrs = tcx.hir().attrs(start_id);
                     for attr in attrs {
                         if attr.has_name(sym::track_caller) {
-                            tcx.sess
-                                .struct_span_err(
-                                    attr.span,
-                                    "`start` is not allowed to be `#[track_caller]`",
-                                )
-                                .span_label(
-                                    start_span,
-                                    "`start` is not allowed to be `#[track_caller]`",
-                                )
-                                .emit();
+                            tcx.sess.emit_err(errors::StartTrackCaller {
+                                span: attr.span,
+                                start: start_span,
+                            });
                             error = true;
                         }
                     }
diff --git a/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs b/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs
index 324df313ef1..089491bef5e 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs
@@ -1,6 +1,6 @@
 use crate::structured_errors::StructuredDiagnostic;
 use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId, ErrorGuaranteed};
-use rustc_middle::ty::{Ty, TypeVisitable};
+use rustc_middle::ty::{Ty, TypeVisitableExt};
 use rustc_session::Session;
 use rustc_span::Span;
 
diff --git a/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs b/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs
index bb608805488..3b9fb367813 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs
@@ -1,6 +1,6 @@
 use crate::structured_errors::StructuredDiagnostic;
 use rustc_errors::{DiagnosticBuilder, DiagnosticId, ErrorGuaranteed};
-use rustc_middle::ty::{Ty, TypeVisitable};
+use rustc_middle::ty::{Ty, TypeVisitableExt};
 use rustc_session::Session;
 use rustc_span::Span;
 
diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
index 560ffc620e0..cae884ae8fb 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
@@ -439,7 +439,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
 
     fn create_error_message(&self) -> String {
         let def_path = self.tcx.def_path_str(self.def_id);
-        let def_kind = self.tcx.def_kind(self.def_id).descr(self.def_id);
+        let def_kind = self.tcx.def_descr(self.def_id);
         let (quantifier, bound) = self.get_quantifier_and_bound();
         let kind = self.kind();
         let provided_lt_args = self.num_provided_lifetime_args();
@@ -462,7 +462,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
 
         if self.gen_args.span_ext().is_some() {
             format!(
-                "this {} takes {}{} {} argument{} but {} {} supplied",
+                "{} takes {}{} {} argument{} but {} {} supplied",
                 def_kind,
                 quantifier,
                 bound,
@@ -990,7 +990,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
         };
 
         let msg = {
-            let def_kind = self.tcx.def_kind(self.def_id).descr(self.def_id);
+            let def_kind = self.tcx.def_descr(self.def_id);
             let (quantifier, bound) = self.get_quantifier_and_bound();
 
             let params = if bound == 0 {
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
index fb63bf22474..5d5c8ca604a 100644
--- a/compiler/rustc_hir_analysis/src/variance/mod.rs
+++ b/compiler/rustc_hir_analysis/src/variance/mod.rs
@@ -7,10 +7,8 @@ use rustc_arena::DroplessArena;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::ty::query::Providers;
-#[cfg(not(bootstrap))]
-use rustc_middle::ty::TypeVisitable;
 use rustc_middle::ty::{self, CrateVariancesMap, SubstsRef, Ty, TyCtxt};
-use rustc_middle::ty::{DefIdTree, TypeSuperVisitable};
+use rustc_middle::ty::{DefIdTree, TypeSuperVisitable, TypeVisitable};
 use std::ops::ControlFlow;
 
 /// Defines the `TermsContext` basically houses an arena where we can
@@ -101,7 +99,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
         }
     }
 
-    impl<'tcx> ty::ir::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeLifetimeCollector<'tcx> {
+    impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeLifetimeCollector<'tcx> {
         #[instrument(level = "trace", skip(self), ret)]
         fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
             if let ty::RegionKind::ReEarlyBound(ebr) = r.kind() {
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 7dcf9d8299f..c021fca7133 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -358,7 +358,7 @@ impl<'a> State<'a> {
                 self.print_anon_const(e);
                 self.word(")");
             }
-            hir::TyKind::Err => {
+            hir::TyKind::Err(_) => {
                 self.popen();
                 self.word("/*ERROR*/");
                 self.pclose();
@@ -1559,7 +1559,7 @@ impl<'a> State<'a> {
                 self.word_space("yield");
                 self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
             }
-            hir::ExprKind::Err => {
+            hir::ExprKind::Err(_) => {
                 self.popen();
                 self.word("/*ERROR*/");
                 self.pclose();
diff --git a/compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl b/compiler/rustc_hir_typeck/locales/en-US.ftl
index 05ac8db0db8..adfcbc36a4d 100644
--- a/compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl
+++ b/compiler/rustc_hir_typeck/locales/en-US.ftl
@@ -1,17 +1,26 @@
-hir_typeck_fru_note = this expression may have been misinterpreted as a `..` range expression
-hir_typeck_fru_expr = this expression does not end in a comma...
-hir_typeck_fru_expr2 = ... so this is interpreted as a `..` range expression, instead of functional record update syntax
-hir_typeck_fru_suggestion =
-    to set the remaining fields{$expr ->
-        [NONE]{""}
-        *[other] {" "}from `{$expr}`
-    }, separate the last named field with a comma
-
 hir_typeck_field_multiply_specified_in_initializer =
     field `{$ident}` specified more than once
     .label = used more than once
     .previous_use_label = first use of `{$ident}`
 
+hir_typeck_copy_impl_on_type_with_dtor =
+    the trait `Copy` may not be implemented for this type; the type has a destructor
+    .label = `Copy` not allowed on types with destructors
+
+hir_typeck_multiple_relaxed_default_bounds =
+    type parameter has more than one relaxed default bound, only one is supported
+
+hir_typeck_copy_impl_on_non_adt =
+    the trait `Copy` may not be implemented for this type
+    .label = type is not a structure or enumeration
+
+hir_typeck_trait_object_declared_with_no_traits =
+    at least one trait is required for an object type
+    .alias_span = this alias does not contain a trait
+
+hir_typeck_functional_record_update_on_non_struct =
+    functional record update syntax requires a struct
+
 hir_typeck_return_stmt_outside_of_fn_body =
     return statement outside of function body
     .encl_body_label = the return is part of this body...
@@ -26,9 +35,6 @@ hir_typeck_struct_expr_non_exhaustive =
 hir_typeck_method_call_on_unknown_type =
     the type of this value must be known to call a method on a raw pointer on it
 
-hir_typeck_functional_record_update_on_non_struct =
-    functional record update syntax requires a struct
-
 hir_typeck_address_of_temporary_taken = cannot take address of a temporary
     .label = temporary value
 
@@ -44,9 +50,6 @@ hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on
 
 hir_typeck_add_missing_parentheses_in_range = you must surround the range in parentheses to call its `{$func_name}` function
 
-hir_typeck_op_trait_generic_params =
-    `{$method_name}` must not have any generic parameters
-
 hir_typeck_lang_start_incorrect_number_params = incorrect number of parameters for the `start` lang item
 hir_typeck_lang_start_incorrect_number_params_note_expected_count = the `start` lang item should have four parameters, but found {$found_param_count}
 
@@ -63,3 +66,14 @@ hir_typeck_help_set_edition_standalone = pass `--edition {$edition}` to `rustc`
 hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide
 
 hir_typeck_convert_to_str = try converting the passed type into a `&str`
+
+hir_typeck_op_trait_generic_params = `{$method_name}` must not have any generic parameters
+
+hir_typeck_fru_note = this expression may have been misinterpreted as a `..` range expression
+hir_typeck_fru_expr = this expression does not end in a comma...
+hir_typeck_fru_expr2 = ... so this is interpreted as a `..` range expression, instead of functional record update syntax
+hir_typeck_fru_suggestion =
+    to set the remaining fields{$expr ->
+        [NONE]{""}
+        *[other] {" "}from `{$expr}`
+    }, separate the last named field with a comma
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 089863a66e7..6a0d5c01109 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -21,7 +21,7 @@ use rustc_middle::ty::adjustment::{
     Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
 };
 use rustc_middle::ty::SubstsRef;
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::Span;
@@ -232,7 +232,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let Some(trait_def_id) = opt_trait_def_id else { continue };
 
             let opt_input_type = opt_arg_exprs.map(|arg_exprs| {
-                self.tcx.mk_tup(arg_exprs.iter().map(|e| {
+                self.tcx.mk_tup_from_iter(arg_exprs.iter().map(|e| {
                     self.next_ty_var(TypeVariableOrigin {
                         kind: TypeVariableOriginKind::TypeInference,
                         span: e.span,
@@ -247,6 +247,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 adjusted_ty,
                 opt_input_type.as_ref().map(slice::from_ref),
             ) {
+                // Check for `self` receiver on the method, otherwise we can't use this as a `Fn*` trait.
+                if !self.tcx.associated_item(ok.value.def_id).fn_has_self_parameter {
+                    self.tcx.sess.delay_span_bug(
+                        call_expr.span,
+                        "input to overloaded call fn is not a self receiver",
+                    );
+                    return None;
+                }
+
                 let method = self.register_infer_ok_obligations(ok);
                 let mut autoref = None;
                 if borrow {
@@ -257,7 +266,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         // caused an error elsewhere.
                         self.tcx
                             .sess
-                            .delay_span_bug(call_expr.span, "input to call/call_mut is not a ref?");
+                            .delay_span_bug(call_expr.span, "input to call/call_mut is not a ref");
                         return None;
                     };
 
@@ -271,6 +280,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         target: method.sig.inputs()[0],
                     });
                 }
+
                 return Some((autoref, method));
             }
         }
@@ -428,7 +438,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 let err = self.report_invalid_callee(call_expr, callee_expr, callee_ty, arg_exprs);
 
-                return self.tcx.ty_error_with_guaranteed(err);
+                return self.tcx.ty_error(err);
             }
         };
 
@@ -661,7 +671,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 && !self.type_is_sized_modulo_regions(self.param_env, output_ty, callee_expr.span)
             {
                 let descr = match maybe_def {
-                    DefIdOrName::DefId(def_id) => self.tcx.def_kind(def_id).descr(def_id),
+                    DefIdOrName::DefId(def_id) => self.tcx.def_descr(def_id),
                     DefIdOrName::Name(name) => name,
                 };
                 err.span_label(
@@ -823,7 +833,7 @@ impl<'a, 'tcx> DeferredCallResolution<'tcx> {
                 );
                 err.help(
                     "make sure the `fn`/`fn_mut`/`fn_once` lang items are defined \
-                     and have associated `call`/`call_mut`/`call_once` functions",
+                     and have correctly defined `call`/`call_mut`/`call_once` methods",
                 );
                 err.emit();
             }
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 8e21c084841..316c2a7eeeb 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -41,7 +41,7 @@ use rustc_middle::mir::Mutability;
 use rustc_middle::ty::adjustment::AllowTwoPhase;
 use rustc_middle::ty::cast::{CastKind, CastTy};
 use rustc_middle::ty::error::TypeError;
-use rustc_middle::ty::{self, Ty, TypeAndMut, TypeVisitable, VariantDef};
+use rustc_middle::ty::{self, Ty, TypeAndMut, TypeVisitableExt, VariantDef};
 use rustc_session::lint;
 use rustc_session::Session;
 use rustc_span::def_id::{DefId, LOCAL_CRATE};
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index cf296a7bf65..d84fabb7834 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -3,6 +3,7 @@
 use super::{check_fn, Expectation, FnCtxt, GeneratorTypes};
 
 use hir::def::DefKind;
+use rustc_errors::ErrorGuaranteed;
 use rustc_hir as hir;
 use rustc_hir::lang_items::LangItem;
 use rustc_hir_analysis::astconv::AstConv;
@@ -11,8 +12,8 @@ use rustc_infer::infer::LateBoundRegionConversionTime;
 use rustc_infer::infer::{InferOk, InferResult};
 use rustc_macros::{TypeFoldable, TypeVisitable};
 use rustc_middle::ty::subst::InternalSubsts;
-use rustc_middle::ty::visit::TypeVisitable;
-use rustc_middle::ty::{self, ir::TypeVisitor, Ty, TyCtxt, TypeSuperVisitable};
+use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::source_map::Span;
 use rustc_span::sym;
@@ -126,7 +127,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // the `closures` table.
         let sig = bound_sig.map_bound(|sig| {
             self.tcx.mk_fn_sig(
-                [self.tcx.intern_tup(sig.inputs())],
+                [self.tcx.mk_tup(sig.inputs())],
                 sig.output(),
                 sig.c_variadic,
                 sig.unsafety,
@@ -488,17 +489,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             };
         let expected_span =
             expected_sig.cause_span.unwrap_or_else(|| self.tcx.def_span(expr_def_id));
-        self.report_arg_count_mismatch(
-            expected_span,
-            closure_span,
-            expected_args,
-            found_args,
-            true,
-            closure_arg_span,
-        )
-        .emit();
-
-        let error_sig = self.error_sig_of_closure(decl);
+        let guar = self
+            .report_arg_count_mismatch(
+                expected_span,
+                closure_span,
+                expected_args,
+                found_args,
+                true,
+                closure_arg_span,
+            )
+            .emit();
+
+        let error_sig = self.error_sig_of_closure(decl, guar);
 
         self.closure_sigs(expr_def_id, body, error_sig)
     }
@@ -561,8 +563,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ) {
                 // Check that E' = S'.
                 let cause = self.misc(hir_ty.span);
-                let InferOk { value: (), obligations } =
-                    self.at(&cause, self.param_env).eq(*expected_ty, supplied_ty)?;
+                let InferOk { value: (), obligations } = self
+                    .at(&cause, self.param_env)
+                    .define_opaque_types(true)
+                    .eq(*expected_ty, supplied_ty)?;
                 all_obligations.extend(obligations);
             }
 
@@ -574,6 +578,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let cause = &self.misc(decl.output.span());
             let InferOk { value: (), obligations } = self
                 .at(cause, self.param_env)
+                .define_opaque_types(true)
                 .eq(expected_sigs.liberated_sig.output(), supplied_output_ty)?;
             all_obligations.extend(obligations);
 
@@ -789,13 +794,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Converts the types that the user supplied, in case that doing
     /// so should yield an error, but returns back a signature where
     /// all parameters are of type `TyErr`.
-    fn error_sig_of_closure(&self, decl: &hir::FnDecl<'_>) -> ty::PolyFnSig<'tcx> {
+    fn error_sig_of_closure(
+        &self,
+        decl: &hir::FnDecl<'_>,
+        guar: ErrorGuaranteed,
+    ) -> ty::PolyFnSig<'tcx> {
         let astconv: &dyn AstConv<'_> = self;
+        let err_ty = self.tcx.ty_error(guar);
 
         let supplied_arguments = decl.inputs.iter().map(|a| {
             // Convert the types that the user supplied (if any), but ignore them.
             astconv.ast_ty_to_ty(a);
-            self.tcx.ty_error()
+            err_ty
         });
 
         if let hir::FnRetTy::Return(ref output) = decl.output {
@@ -804,7 +814,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let result = ty::Binder::dummy(self.tcx.mk_fn_sig(
             supplied_arguments,
-            self.tcx.ty_error(),
+            err_ty,
             decl.c_variadic,
             hir::Unsafety::Normal,
             Abi::RustCall,
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index ba503bf47e7..00b86890b33 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -54,7 +54,7 @@ use rustc_middle::ty::adjustment::{
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::relate::RelateResult;
 use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::visit::TypeVisitable;
+use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{self, Ty, TypeAndMut};
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::sym;
@@ -143,11 +143,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
     fn unify(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> InferResult<'tcx, Ty<'tcx>> {
         debug!("unify(a: {:?}, b: {:?}, use_lub: {})", a, b, self.use_lub);
         self.commit_if_ok(|_| {
+            let at = self.at(&self.cause, self.fcx.param_env).define_opaque_types(true);
             if self.use_lub {
-                self.at(&self.cause, self.fcx.param_env).lub(b, a)
+                at.lub(b, a)
             } else {
-                self.at(&self.cause, self.fcx.param_env)
-                    .sup(b, a)
+                at.sup(b, a)
                     .map(|InferOk { value: (), obligations }| InferOk { value: a, obligations })
             }
         })
@@ -170,12 +170,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         debug!("Coerce.tys({:?} => {:?})", a, b);
 
         // Just ignore error types.
-        if a.references_error() || b.references_error() {
+        if let Err(guar) = (a, b).error_reported() {
             // Best-effort try to unify these types -- we're already on the error path,
             // so this will have the side-effect of making sure we have no ambiguities
             // due to `[type error]` and `_` not coercing together.
-            let _ = self.commit_if_ok(|_| self.at(&self.cause, self.param_env).eq(a, b));
-            return success(vec![], self.fcx.tcx.ty_error(), vec![]);
+            let _ = self.commit_if_ok(|_| {
+                self.at(&self.cause, self.param_env).define_opaque_types(true).eq(a, b)
+            });
+            return success(vec![], self.fcx.tcx.ty_error(guar), vec![]);
         }
 
         // Coercing from `!` to any type is allowed:
@@ -995,7 +997,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let (adjustments, _) = self.register_infer_ok_obligations(ok);
         self.apply_adjustments(expr, adjustments);
-        Ok(if expr_ty.references_error() { self.tcx.ty_error() } else { target })
+        Ok(if let Err(guar) = expr_ty.error_reported() { self.tcx.ty_error(guar) } else { target })
     }
 
     /// Same as `try_coerce()`, but without side-effects.
@@ -1432,8 +1434,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
 
         // If we see any error types, just propagate that error
         // upwards.
-        if expression_ty.references_error() || self.merged_ty().references_error() {
-            self.final_ty = Some(fcx.tcx.ty_error());
+        if let Err(guar) = (expression_ty, self.merged_ty()).error_reported() {
+            self.final_ty = Some(fcx.tcx.ty_error(guar));
             return;
         }
 
@@ -1484,6 +1486,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
             // Another example is `break` with no argument expression.
             assert!(expression_ty.is_unit(), "if let hack without unit type");
             fcx.at(cause, fcx.param_env)
+                // needed for tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs
+                .define_opaque_types(true)
                 .eq_exp(label_expression_as_expected, expression_ty, self.merged_ty())
                 .map(|infer_ok| {
                     fcx.register_infer_ok_obligations(infer_ok);
@@ -1616,7 +1620,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
 
                 let reported = err.emit_unless(unsized_return);
 
-                self.final_ty = Some(fcx.tcx.ty_error_with_guaranteed(reported));
+                self.final_ty = Some(fcx.tcx.ty_error(reported));
             }
         }
     }
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 879a64fc0fb..34d62987c3b 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -16,7 +16,7 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::fold::{BottomUpFolder, TypeFolder};
 use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths};
 use rustc_middle::ty::relate::TypeRelation;
-use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeVisitable};
+use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeVisitableExt};
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{BytePos, Span};
 use rustc_trait_selection::infer::InferCtxtExt as _;
@@ -113,7 +113,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected: Ty<'tcx>,
         actual: Ty<'tcx>,
     ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
-        match self.at(cause, self.param_env).sup(expected, actual) {
+        match self.at(cause, self.param_env).define_opaque_types(true).sup(expected, actual) {
             Ok(InferOk { obligations, value: () }) => {
                 self.register_predicates(obligations);
                 None
@@ -143,7 +143,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected: Ty<'tcx>,
         actual: Ty<'tcx>,
     ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
-        match self.at(cause, self.param_env).eq(expected, actual) {
+        match self.at(cause, self.param_env).define_opaque_types(true).eq(expected, actual) {
             Ok(InferOk { obligations, value: () }) => {
                 self.register_predicates(obligations);
                 None
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index 2c8979402b6..3eee2278dca 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -1,4 +1,5 @@
 //! Errors emitted by `rustc_hir_typeck`.
+use crate::fluent_generated as fluent;
 use rustc_errors::{AddToDiagnostic, Applicability, Diagnostic, MultiSpan, SubdiagnosticMessage};
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_middle::ty::Ty;
@@ -14,7 +15,7 @@ pub struct FieldMultiplySpecifiedInInitializer {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(previous_use_label)]
+    #[label(hir_typeck_previous_use_label)]
     pub prev_span: Span,
     pub ident: Ident,
 }
@@ -24,9 +25,9 @@ pub struct FieldMultiplySpecifiedInInitializer {
 pub struct ReturnStmtOutsideOfFnBody {
     #[primary_span]
     pub span: Span,
-    #[label(encl_body_label)]
+    #[label(hir_typeck_encl_body_label)]
     pub encl_body_span: Option<Span>,
-    #[label(encl_fn_label)]
+    #[label(hir_typeck_encl_fn_label)]
     pub encl_fn_span: Option<Span>,
 }
 
@@ -157,20 +158,17 @@ impl AddToDiagnostic for TypeMismatchFruTypo {
 
         // Only explain that `a ..b` is a range if it's split up
         if self.expr_span.between(self.fru_span).is_empty() {
-            diag.span_note(
-                self.expr_span.to(self.fru_span),
-                rustc_errors::fluent::hir_typeck_fru_note,
-            );
+            diag.span_note(self.expr_span.to(self.fru_span), fluent::hir_typeck_fru_note);
         } else {
             let mut multispan: MultiSpan = vec![self.expr_span, self.fru_span].into();
-            multispan.push_span_label(self.expr_span, rustc_errors::fluent::hir_typeck_fru_expr);
-            multispan.push_span_label(self.fru_span, rustc_errors::fluent::hir_typeck_fru_expr2);
-            diag.span_note(multispan, rustc_errors::fluent::hir_typeck_fru_note);
+            multispan.push_span_label(self.expr_span, fluent::hir_typeck_fru_expr);
+            multispan.push_span_label(self.fru_span, fluent::hir_typeck_fru_expr2);
+            diag.span_note(multispan, fluent::hir_typeck_fru_note);
         }
 
         diag.span_suggestion(
             self.expr_span.shrink_to_hi(),
-            rustc_errors::fluent::hir_typeck_fru_suggestion,
+            fluent::hir_typeck_fru_suggestion,
             ", ",
             Applicability::MaybeIncorrect,
         );
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 08cbfffdd17..7fc4ccb04ee 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -42,7 +42,7 @@ use rustc_middle::middle::stability;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
 use rustc_middle::ty::error::TypeError::FieldMisMatch;
 use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::{self, AdtKind, Ty, TypeVisitable};
+use rustc_middle::ty::{self, AdtKind, Ty, TypeVisitableExt};
 use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_session::parse::feature_err;
 use rustc_span::edit_distance::find_best_match_for_name;
@@ -88,7 +88,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &adjustments[..] {
                     target.to_owned()
                 } else {
-                    self.tcx().ty_error_with_guaranteed(reported)
+                    self.tcx().ty_error(reported)
                 };
             }
 
@@ -313,7 +313,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     tcx.types.never
                 } else {
                     // There was an error; make type-check fail.
-                    tcx.ty_error()
+                    tcx.ty_error_misc()
                 }
             }
             ExprKind::Ret(ref expr_opt) => self.check_expr_return(expr_opt.as_deref(), expr),
@@ -354,7 +354,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ExprKind::Field(base, field) => self.check_field(expr, &base, field, expected),
             ExprKind::Index(base, idx) => self.check_expr_index(base, idx, expr),
             ExprKind::Yield(value, ref src) => self.check_expr_yield(value, expr, src),
-            hir::ExprKind::Err => tcx.ty_error(),
+            hir::ExprKind::Err(guar) => tcx.ty_error(guar),
         }
     }
 
@@ -402,7 +402,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         {
                             err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
                         }
-                        oprnd_t = tcx.ty_error_with_guaranteed(err.emit());
+                        oprnd_t = tcx.ty_error(err.emit());
                     }
                 }
                 hir::UnOp::Not => {
@@ -452,7 +452,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let tm = ty::TypeAndMut { ty, mutbl };
         match kind {
-            _ if tm.ty.references_error() => self.tcx.ty_error(),
+            _ if tm.ty.references_error() => self.tcx.ty_error_misc(),
             hir::BorrowKind::Raw => {
                 self.check_named_place_expr(oprnd);
                 self.tcx.mk_ptr(tm)
@@ -531,11 +531,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let e =
                     self.tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted");
                 self.set_tainted_by_errors(e);
-                tcx.ty_error_with_guaranteed(e)
+                tcx.ty_error(e)
             }
             Res::Def(DefKind::Variant, _) => {
                 let e = report_unexpected_variant_res(tcx, res, qpath, expr.span, "E0533", "value");
-                tcx.ty_error_with_guaranteed(e)
+                tcx.ty_error(e)
             }
             _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0,
         };
@@ -634,7 +634,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // If the loop context is not a `loop { }`, then break with
                 // a value is illegal, and `opt_coerce_to` will be `None`.
                 // Just set expectation to error in that case.
-                let coerce_to = opt_coerce_to.unwrap_or_else(|| tcx.ty_error());
+                let coerce_to = opt_coerce_to.unwrap_or_else(|| tcx.ty_error_misc());
 
                 // Recurse without `enclosing_breakables` borrowed.
                 e_ty = self.check_expr_with_hint(e, coerce_to);
@@ -1033,7 +1033,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         let result_ty = coerce.complete(self);
-        if cond_ty.references_error() { self.tcx.ty_error() } else { result_ty }
+        if let Err(guar) = cond_ty.error_reported() { self.tcx.ty_error(guar) } else { result_ty }
     }
 
     /// Type check assignment expression `expr` of form `lhs = rhs`.
@@ -1109,7 +1109,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // If the assignment expression itself is ill-formed, don't
             // bother emitting another error
             let reported = err.emit_unless(lhs_ty.references_error() || rhs_ty.references_error());
-            return self.tcx.ty_error_with_guaranteed(reported);
+            return self.tcx.ty_error(reported);
         }
 
         let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
@@ -1155,8 +1155,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
 
-        if lhs_ty.references_error() || rhs_ty.references_error() {
-            self.tcx.ty_error()
+        if let Err(guar) = (lhs_ty, rhs_ty).error_reported() {
+            self.tcx.ty_error(guar)
         } else {
             self.tcx.mk_unit()
         }
@@ -1274,8 +1274,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let t_expr = self.resolve_vars_if_possible(t_expr);
 
         // Eagerly check for some obvious errors.
-        if t_expr.references_error() || t_cast.references_error() {
-            self.tcx.ty_error()
+        if let Err(guar) = (t_expr, t_cast).error_reported() {
+            self.tcx.ty_error(guar)
         } else {
             // Defer other checks until we're done type checking.
             let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
@@ -1296,7 +1296,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     deferred_cast_checks.push(cast_check);
                     t_cast
                 }
-                Err(_) => self.tcx.ty_error(),
+                Err(guar) => self.tcx.ty_error(guar),
             }
         }
     }
@@ -1423,8 +1423,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         };
 
-        if element_ty.references_error() {
-            return tcx.ty_error();
+        if let Err(guar) = element_ty.error_reported() {
+            return tcx.ty_error(guar);
         }
 
         self.check_repeat_element_needs_copy_bound(element, count, element_ty);
@@ -1492,9 +1492,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             _ => self.check_expr_with_expectation(&e, NoExpectation),
         });
-        let tuple = self.tcx.mk_tup(elt_ts_iter);
-        if tuple.references_error() {
-            self.tcx.ty_error()
+        let tuple = self.tcx.mk_tup_from_iter(elt_ts_iter);
+        if let Err(guar) = tuple.error_reported() {
+            self.tcx.ty_error(guar)
         } else {
             self.require_type_is_sized(tuple, expr.span, traits::TupleInitializerSized);
             tuple
@@ -1510,9 +1510,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>,
     ) -> Ty<'tcx> {
         // Find the relevant variant
-        let Some((variant, adt_ty)) = self.check_struct_path(qpath, expr.hir_id) else {
-            self.check_struct_fields_on_error(fields, base_expr);
-            return self.tcx.ty_error();
+        let (variant, adt_ty) = match self.check_struct_path(qpath, expr.hir_id) {
+            Ok(data) => data,
+            Err(guar) => {
+                self.check_struct_fields_on_error(fields, base_expr);
+                return self.tcx.ty_error(guar);
+            }
         };
 
         // Prohibit struct expressions when non-exhaustive flag is set.
@@ -1594,12 +1597,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.field_ty(field.span, v_field, substs)
             } else {
                 error_happened = true;
-                if let Some(prev_span) = seen_fields.get(&ident) {
+                let guar = if let Some(prev_span) = seen_fields.get(&ident) {
                     tcx.sess.emit_err(FieldMultiplySpecifiedInInitializer {
                         span: field.ident.span,
                         prev_span: *prev_span,
                         ident,
-                    });
+                    })
                 } else {
                     self.report_unknown_field(
                         adt_ty,
@@ -1608,10 +1611,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         ast_fields,
                         adt.variant_descr(),
                         expr_span,
-                    );
-                }
+                    )
+                };
 
-                tcx.ty_error()
+                tcx.ty_error(guar)
             };
 
             // Make sure to give a type to the field even if there's
@@ -1994,14 +1997,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         skip_fields: &[hir::ExprField<'_>],
         kind_name: &str,
         expr_span: Span,
-    ) {
+    ) -> ErrorGuaranteed {
         if variant.is_recovered() {
-            self.set_tainted_by_errors(
-                self.tcx
-                    .sess
-                    .delay_span_bug(expr_span, "parser recovered but no error was emitted"),
-            );
-            return;
+            let guar = self
+                .tcx
+                .sess
+                .delay_span_bug(expr_span, "parser recovered but no error was emitted");
+            self.set_tainted_by_errors(guar);
+            return guar;
         }
         let mut err = self.err_ctxt().type_error_struct_with_diag(
             field.ident.span,
@@ -2115,7 +2118,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 };
             }
         }
-        err.emit();
+        err.emit()
     }
 
     // Return a hint about the closest match in field names
@@ -2256,11 +2259,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // (#90483) apply adjustments to avoid ExprUseVisitor from
             // creating erroneous projection.
             self.apply_adjustments(base, adjustments);
-            self.ban_private_field_access(expr, base_ty, field, did, expected.only_has_type(self));
-            return self.tcx().ty_error();
+            let guar = self.ban_private_field_access(
+                expr,
+                base_ty,
+                field,
+                did,
+                expected.only_has_type(self),
+            );
+            return self.tcx().ty_error(guar);
         }
 
-        if field.name == kw::Empty {
+        let guar = if field.name == kw::Empty {
+            self.tcx.sess.delay_span_bug(field.span, "field name with no name")
         } else if self.method_exists(
             field,
             base_ty,
@@ -2268,9 +2278,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             true,
             expected.only_has_type(self),
         ) {
-            self.ban_take_value_of_method(expr, base_ty, field);
+            self.ban_take_value_of_method(expr, base_ty, field)
         } else if !base_ty.is_primitive_ty() {
-            self.ban_nonexisting_field(field, base, expr, base_ty);
+            self.ban_nonexisting_field(field, base, expr, base_ty)
         } else {
             let field_name = field.to_string();
             let mut err = type_error_struct!(
@@ -2339,10 +2349,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     );
                 }
             }
-            err.emit();
-        }
+            err.emit()
+        };
 
-        self.tcx().ty_error()
+        self.tcx().ty_error(guar)
     }
 
     fn suggest_await_on_field_access(
@@ -2388,7 +2398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         base: &'tcx hir::Expr<'tcx>,
         expr: &'tcx hir::Expr<'tcx>,
         base_ty: Ty<'tcx>,
-    ) {
+    ) -> ErrorGuaranteed {
         debug!(
             "ban_nonexisting_field: field={:?}, base={:?}, expr={:?}, base_ty={:?}",
             ident, base, expr, base_ty
@@ -2436,7 +2446,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             HelpUseLatestEdition::new().add_to_diagnostic(&mut err);
         }
 
-        err.emit();
+        err.emit()
     }
 
     fn ban_private_field_access(
@@ -2446,9 +2456,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         field: Ident,
         base_did: DefId,
         return_ty: Option<Ty<'tcx>>,
-    ) {
+    ) -> ErrorGuaranteed {
         let struct_path = self.tcx().def_path_str(base_did);
-        let kind_name = self.tcx().def_kind(base_did).descr(base_did);
+        let kind_name = self.tcx().def_descr(base_did);
         let mut err = struct_span_err!(
             self.tcx().sess,
             field.span,
@@ -2469,10 +2479,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 None,
             );
         }
-        err.emit();
+        err.emit()
     }
 
-    fn ban_take_value_of_method(&self, expr: &hir::Expr<'tcx>, expr_t: Ty<'tcx>, field: Ident) {
+    fn ban_take_value_of_method(
+        &self,
+        expr: &hir::Expr<'tcx>,
+        expr_t: Ty<'tcx>,
+        field: Ident,
+    ) -> ErrorGuaranteed {
         let mut err = type_error_struct!(
             self.tcx().sess,
             field.span,
@@ -2544,7 +2559,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             err.help("methods are immutable and cannot be assigned to");
         }
 
-        err.emit();
+        err.emit()
     }
 
     fn point_at_param_definition(&self, err: &mut Diagnostic, param: ty::ParamTy) {
@@ -2829,7 +2844,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
                     }
                     let reported = err.emit();
-                    self.tcx.ty_error_with_guaranteed(reported)
+                    self.tcx.ty_error(reported)
                 }
             }
         }
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index c8cda0dc90c..b9a058d6bba 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -301,7 +301,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
             hir::ExprKind::Continue(..)
             | hir::ExprKind::Lit(..)
             | hir::ExprKind::ConstBlock(..)
-            | hir::ExprKind::Err => {}
+            | hir::ExprKind::Err(_) => {}
 
             hir::ExprKind::Loop(blk, ..) => {
                 self.walk_block(blk);
diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs
index 943dc9b9646..b7ae621c685 100644
--- a/compiler/rustc_hir_typeck/src/fallback.rs
+++ b/compiler/rustc_hir_typeck/src/fallback.rs
@@ -104,7 +104,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         // type, `?T` is not considered unsolved, but `?I` is. The
         // same is true for float variables.)
         let fallback = match ty.kind() {
-            _ if let Some(e) = self.tainted_by_errors() => self.tcx.ty_error_with_guaranteed(e),
+            _ if let Some(e) = self.tainted_by_errors() => self.tcx.ty_error(e),
             ty::Infer(ty::IntVar(_)) => self.tcx.types.i32,
             ty::Infer(ty::FloatVar(_)) => self.tcx.types.f64,
             _ => match diverging_fallback.get(&ty) {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index b2f3a3abb4c..60e55c7b0cf 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -23,9 +23,9 @@ use rustc_infer::infer::InferResult;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::fold::TypeFoldable;
-use rustc_middle::ty::visit::TypeVisitable;
+use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
 use rustc_middle::ty::{
-    self, AdtKind, CanonicalUserType, DefIdTree, GenericParamDefKind, Ty, UserType,
+    self, AdtKind, CanonicalUserType, DefIdTree, GenericParamDefKind, Ty, TyCtxt, UserType,
 };
 use rustc_middle::ty::{GenericArgKind, SubstsRef, UserSelfTy, UserSubsts};
 use rustc_session::lint;
@@ -315,7 +315,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     pub(in super::super) fn normalize<T>(&self, span: Span, value: T) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         self.register_infer_ok_obligations(
             self.at(&self.misc(span), self.param_env).normalize(value),
@@ -443,7 +443,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     // sufficiently enforced with erased regions. =)
     fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
     where
-        T: TypeVisitable<'tcx>,
+        T: TypeVisitable<TyCtxt<'tcx>>,
     {
         t.has_free_regions() || t.has_projections() || t.has_infer_types()
     }
@@ -451,7 +451,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
         match self.typeck_results.borrow().node_types().get(id) {
             Some(&t) => t,
-            None if let Some(e) = self.tainted_by_errors() => self.tcx.ty_error_with_guaranteed(e),
+            None if let Some(e) = self.tainted_by_errors() => self.tcx.ty_error(e),
             None => {
                 bug!(
                     "no type for node {} in fcx {}",
@@ -465,7 +465,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn node_ty_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> {
         match self.typeck_results.borrow().node_types().get(id) {
             Some(&t) => Some(t),
-            None if let Some(e) = self.tainted_by_errors() => Some(self.tcx.ty_error_with_guaranteed(e)),
+            None if let Some(e) = self.tainted_by_errors() => Some(self.tcx.ty_error(e)),
             None => None,
         }
     }
@@ -701,7 +701,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     pub(in super::super) fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
-        vec![self.tcx.ty_error(); len]
+        let ty_error = self.tcx.ty_error_misc();
+        vec![ty_error; len]
     }
 
     /// Unifies the output type with the expected type early, for more coercions
@@ -1161,7 +1162,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
                     }
                     let reported = err.emit();
-                    return (tcx.ty_error_with_guaranteed(reported), res);
+                    return (tcx.ty_error(reported), res);
                 }
             }
         } else {
@@ -1417,7 +1418,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     .emit_inference_failure_err((**self).body_id, sp, ty.into(), E0282, true)
                     .emit()
             });
-            let err = self.tcx.ty_error_with_guaranteed(e);
+            let err = self.tcx.ty_error(e);
             self.demand_suptype(sp, err, ty);
             err
         }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
index 39e0ea98f96..d64492e503d 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
@@ -4,7 +4,7 @@ use rustc_hir::def::Res;
 use rustc_hir::def_id::DefId;
 use rustc_infer::traits::ObligationCauseCode;
 use rustc_middle::ty::{
-    self, ir::TypeVisitor, DefIdTree, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
+    self, DefIdTree, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor,
 };
 use rustc_span::{self, Span};
 use rustc_trait_selection::traits;
@@ -243,7 +243,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         true
     }
 
-    fn find_ambiguous_parameter_in<T: TypeVisitable<'tcx>>(
+    fn find_ambiguous_parameter_in<T: TypeVisitable<TyCtxt<'tcx>>>(
         &self,
         item_def_id: DefId,
         t: T,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 69a7235802b..2e62e13648c 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -10,7 +10,9 @@ use crate::{
 };
 use rustc_ast as ast;
 use rustc_data_structures::fx::FxIndexSet;
-use rustc_errors::{pluralize, Applicability, Diagnostic, DiagnosticId, MultiSpan};
+use rustc_errors::{
+    pluralize, Applicability, Diagnostic, DiagnosticId, ErrorGuaranteed, MultiSpan,
+};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::DefId;
@@ -25,7 +27,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
 use rustc_infer::infer::InferOk;
 use rustc_infer::infer::TypeTrace;
 use rustc_middle::ty::adjustment::AllowTwoPhase;
-use rustc_middle::ty::visit::TypeVisitable;
+use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{self, DefIdTree, IsSuggestable, Ty};
 use rustc_session::Session;
 use rustc_span::symbol::{kw, Ident};
@@ -72,7 +74,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let ty = self.typeck_results.borrow().expr_ty_adjusted(expr);
                 let ty = self.resolve_vars_if_possible(ty);
                 if ty.has_non_region_infer() {
-                    self.tcx.ty_error()
+                    self.tcx.ty_error_misc()
                 } else {
                     self.tcx.erase_regions(ty)
                 }
@@ -100,7 +102,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             let err_inputs = match tuple_arguments {
                 DontTupleArguments => err_inputs,
-                TupleArguments => vec![self.tcx.intern_tup(&err_inputs)],
+                TupleArguments => vec![self.tcx.mk_tup(&err_inputs)],
             };
 
             self.check_argument_types(
@@ -113,7 +115,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 tuple_arguments,
                 method.ok().map(|method| method.def_id),
             );
-            return self.tcx.ty_error();
+            return self.tcx.ty_error_misc();
         }
 
         let method = method.unwrap();
@@ -533,7 +535,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     .typeck_results
                     .borrow()
                     .expr_ty_adjusted_opt(*expr)
-                    .unwrap_or_else(|| tcx.ty_error());
+                    .unwrap_or_else(|| tcx.ty_error_misc());
                 (self.resolve_vars_if_possible(ty), normalize_span(expr.span))
             })
             .collect();
@@ -640,7 +642,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 && provided_arg_tys.len() == formal_and_expected_inputs.len() - 1 + tys.len()
             {
                 // Wrap up the N provided arguments starting at this position in a tuple.
-                let provided_as_tuple = tcx.mk_tup(
+                let provided_as_tuple = tcx.mk_tup_from_iter(
                     provided_arg_tys.iter().map(|(ty, _)| *ty).skip(mismatch_idx).take(tys.len()),
                 );
 
@@ -932,25 +934,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     labels
                         .push((provided_span, format!("unexpected argument{}", provided_ty_name)));
                     let mut span = provided_span;
-                    if arg_idx.index() > 0
+                    if span.can_be_used_for_suggestions() {
+                        if arg_idx.index() > 0
                         && let Some((_, prev)) = provided_arg_tys
                             .get(ProvidedIdx::from_usize(arg_idx.index() - 1)
                     ) {
                         // Include previous comma
-                        span = span.with_lo(prev.hi());
-                    } else if let Some((_, next)) = provided_arg_tys.get(
-                        ProvidedIdx::from_usize(arg_idx.index() + 1),
-                    ) {
-                        // Include next comma
-                        span = span.until(*next);
+                        span = prev.shrink_to_hi().to(span);
                     }
-                    suggestions.push((span, String::new()));
+                        suggestions.push((span, String::new()));
 
-                    suggestion_text = match suggestion_text {
-                        SuggestionText::None => SuggestionText::Remove(false),
-                        SuggestionText::Remove(_) => SuggestionText::Remove(true),
-                        _ => SuggestionText::DidYouMean,
-                    };
+                        suggestion_text = match suggestion_text {
+                            SuggestionText::None => SuggestionText::Remove(false),
+                            SuggestionText::Remove(_) => SuggestionText::Remove(true),
+                            _ => SuggestionText::DidYouMean,
+                        };
+                    }
                 }
                 Error::Missing(expected_idx) => {
                     // If there are multiple missing arguments adjacent to each other,
@@ -1289,7 +1288,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 opt_ty.unwrap_or_else(|| self.next_float_var())
             }
             ast::LitKind::Bool(_) => tcx.types.bool,
-            ast::LitKind::Err => tcx.ty_error(),
+            ast::LitKind::Err => tcx.ty_error_misc(),
         }
     }
 
@@ -1297,15 +1296,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         qpath: &QPath<'_>,
         hir_id: hir::HirId,
-    ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
+    ) -> Result<(&'tcx ty::VariantDef, Ty<'tcx>), ErrorGuaranteed> {
         let path_span = qpath.span();
         let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
         let variant = match def {
             Res::Err => {
-                self.set_tainted_by_errors(
-                    self.tcx.sess.delay_span_bug(path_span, "`Res::Err` but no error emitted"),
-                );
-                return None;
+                let guar =
+                    self.tcx.sess.delay_span_bug(path_span, "`Res::Err` but no error emitted");
+                self.set_tainted_by_errors(guar);
+                return Err(guar);
             }
             Res::Def(DefKind::Variant, _) => match ty.normalized.ty_adt_def() {
                 Some(adt) => {
@@ -1333,28 +1332,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // Check bounds on type arguments used in the path.
             self.add_required_obligations_for_hir(path_span, did, substs, hir_id);
 
-            Some((variant, ty.normalized))
+            Ok((variant, ty.normalized))
         } else {
-            match ty.normalized.kind() {
-                ty::Error(_) => {
+            Err(match *ty.normalized.kind() {
+                ty::Error(guar) => {
                     // E0071 might be caused by a spelling error, which will have
                     // already caused an error message and probably a suggestion
                     // elsewhere. Refrain from emitting more unhelpful errors here
                     // (issue #88844).
+                    guar
                 }
-                _ => {
-                    struct_span_err!(
-                        self.tcx.sess,
-                        path_span,
-                        E0071,
-                        "expected struct, variant or union type, found {}",
-                        ty.normalized.sort_string(self.tcx)
-                    )
-                    .span_label(path_span, "not a struct")
-                    .emit();
-                }
-            }
-            None
+                _ => struct_span_err!(
+                    self.tcx.sess,
+                    path_span,
+                    E0071,
+                    "expected struct, variant or union type, found {}",
+                    ty.normalized.sort_string(self.tcx)
+                )
+                .span_label(path_span, "not a struct")
+                .emit(),
+            })
         }
     }
 
@@ -1718,9 +1715,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         pat: &'tcx hir::Pat<'tcx>,
         ty: Ty<'tcx>,
     ) {
-        if ty.references_error() {
+        if let Err(guar) = ty.error_reported() {
             // Override the types everywhere with `err()` to avoid knock on errors.
-            let err = self.tcx.ty_error();
+            let err = self.tcx.ty_error(guar);
             self.write_ty(hir_id, err);
             self.write_ty(pat.hir_id, err);
             let local_ty = LocalTy { decl_ty: err, revealed_ty: err };
@@ -1749,7 +1746,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let result = self
                     .astconv()
                     .associated_path_to_ty(hir_id, path_span, ty.raw, qself, segment, true);
-                let ty = result.map(|(ty, _, _)| ty).unwrap_or_else(|_| self.tcx().ty_error());
+                let ty =
+                    result.map(|(ty, _, _)| ty).unwrap_or_else(|guar| self.tcx().ty_error(guar));
                 let ty = self.handle_raw_ty(path_span, ty);
                 let result = result.map(|(_, kind, def_id)| (kind, def_id));
 
@@ -1941,8 +1939,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 spans.push_span_label(param.span, "");
             }
 
-            let def_kind = self.tcx.def_kind(def_id);
-            err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
+            err.span_note(spans, &format!("{} defined here", self.tcx.def_descr(def_id)));
         } else if let Some(hir::Node::Expr(e)) = self.tcx.hir().get_if_local(def_id)
             && let hir::ExprKind::Closure(hir::Closure { body, .. }) = &e.kind
         {
@@ -1955,10 +1952,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             };
             err.span_note(span, &format!("{} defined here", kind));
         } else {
-            let def_kind = self.tcx.def_kind(def_id);
             err.span_note(
                 self.tcx.def_span(def_id),
-                &format!("{} defined here", def_kind.descr(def_id)),
+                &format!("{} defined here", self.tcx.def_descr(def_id)),
             );
         }
     }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index 3814ddaf73f..1dea3e6f900 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -18,7 +18,7 @@ use rustc_infer::infer::error_reporting::TypeErrCtxt;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
 use rustc_middle::ty::subst::GenericArgKind;
-use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt};
 use rustc_session::Session;
 use rustc_span::symbol::Ident;
 use rustc_span::{self, Span, DUMMY_SP};
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 3539202d1ca..c49621b7c24 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -1,9 +1,10 @@
 use super::FnCtxt;
 
 use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel};
+use crate::fluent_generated as fluent;
 use crate::method::probe::{IsSuggestion, Mode, ProbeScope};
 use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
-use rustc_errors::{fluent, Applicability, Diagnostic, MultiSpan};
+use rustc_errors::{Applicability, Diagnostic, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind};
 use rustc_hir::lang_items::LangItem;
@@ -16,7 +17,7 @@ use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{
     self, suggest_constraining_type_params, Binder, DefIdTree, IsSuggestable, ToPredicate, Ty,
-    TypeVisitable,
+    TypeVisitableExt,
 };
 use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::source_map::Spanned;
@@ -120,7 +121,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 DefIdOrName::DefId(def_id) => match self.tcx.def_kind(def_id) {
                     DefKind::Ctor(CtorOf::Struct, _) => "construct this tuple struct".to_string(),
                     DefKind::Ctor(CtorOf::Variant, _) => "construct this tuple variant".to_string(),
-                    kind => format!("call this {}", kind.descr(def_id)),
+                    kind => format!("call this {}", self.tcx.def_kind_descr(kind, def_id)),
                 },
                 DefIdOrName::Name(name) => format!("call this {name}"),
             };
@@ -339,7 +340,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     CtorOf::Variant => "an enum variant",
                 }));
             } else {
-                let descr = kind.descr(def_id);
+                let descr = self.tcx.def_kind_descr(kind, def_id);
                 err.span_label(sp, format!("{descr} `{name}` defined here"));
             }
             return true;
diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs
index b3dd3031db2..7c0402b1c7f 100644
--- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs
+++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs
@@ -12,7 +12,7 @@ use rustc_index::vec::IndexVec;
 use rustc_infer::infer::InferCtxt;
 use rustc_middle::{
     hir::map::Map,
-    ty::{ParamEnv, TyCtxt, TypeVisitable, TypeckResults},
+    ty::{ParamEnv, TyCtxt, TypeVisitableExt, TypeckResults},
 };
 use std::mem::swap;
 
@@ -219,7 +219,7 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> {
             | ExprKind::Struct(..)
             | ExprKind::Repeat(..)
             | ExprKind::Yield(..)
-            | ExprKind::Err => (),
+            | ExprKind::Err(_) => (),
         }
     }
 
@@ -483,7 +483,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
             | ExprKind::Closure { .. }
             | ExprKind::ConstBlock(..)
             | ExprKind::DropTemps(..)
-            | ExprKind::Err
+            | ExprKind::Err(_)
             | ExprKind::Field(..)
             | ExprKind::Index(..)
             | ExprKind::InlineAsm(..)
diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs
index ed3d8903157..fa3887362d9 100644
--- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs
+++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs
@@ -9,7 +9,7 @@ use rustc_hir as hir;
 use rustc_middle::ty::{ParamEnv, TyCtxt};
 use rustc_middle::{
     hir::place::{PlaceBase, Projection, ProjectionKind},
-    ty::TypeVisitable,
+    ty::TypeVisitableExt,
 };
 
 pub(super) fn find_consumed_and_borrowed<'a, 'tcx>(
diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs
index 14e3ba83b10..2e41c2041f8 100644
--- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs
+++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs
@@ -16,7 +16,7 @@ use rustc_hir::{Arm, Expr, ExprKind, Guard, HirId, Pat, PatKind};
 use rustc_infer::infer::RegionVariableOrigin;
 use rustc_middle::middle::region::{self, Scope, ScopeData, YieldData};
 use rustc_middle::ty::fold::FnMutDelegate;
-use rustc_middle::ty::{self, BoundVariableKind, RvalueScopes, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, BoundVariableKind, RvalueScopes, Ty, TyCtxt, TypeVisitableExt};
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 use smallvec::{smallvec, SmallVec};
@@ -311,8 +311,8 @@ pub fn resolve_interior<'a, 'tcx>(
     };
 
     // Extract type components to build the witness type.
-    let type_list = fcx.tcx.mk_type_list(type_causes.iter().map(|cause| cause.ty));
-    let bound_vars = fcx.tcx.intern_bound_variable_kinds(&bound_vars);
+    let type_list = fcx.tcx.mk_type_list_from_iter(type_causes.iter().map(|cause| cause.ty));
+    let bound_vars = fcx.tcx.mk_bound_variable_kinds(&bound_vars);
     let witness =
         fcx.tcx.mk_generator_witness(ty::Binder::bind_with_vars(type_list, bound_vars.clone()));
 
diff --git a/compiler/rustc_hir_typeck/src/inherited.rs b/compiler/rustc_hir_typeck/src/inherited.rs
index 87e54025330..26020382d81 100644
--- a/compiler/rustc_hir_typeck/src/inherited.rs
+++ b/compiler/rustc_hir_typeck/src/inherited.rs
@@ -6,7 +6,7 @@ use rustc_hir::def_id::LocalDefId;
 use rustc_hir::HirIdMap;
 use rustc_infer::infer;
 use rustc_infer::infer::{DefiningAnchor, InferCtxt, InferOk, TyCtxtInferExt};
-use rustc_middle::ty::visit::TypeVisitable;
+use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::def_id::LocalDefIdMap;
 use rustc_span::{self, Span};
diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs
index 2c76582f2ec..19d2befc438 100644
--- a/compiler/rustc_hir_typeck/src/intrinsicck.rs
+++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs
@@ -3,7 +3,7 @@ use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_index::vec::Idx;
 use rustc_middle::ty::layout::{LayoutError, SizeSkeleton};
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 use rustc_target::abi::{Pointer, VariantIdx};
 
 use super::FnCtxt;
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 0204beb6fb8..91fd8fad73c 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -53,7 +53,10 @@ use crate::check::check_fn;
 use crate::coercion::DynamicCoerceMany;
 use crate::gather_locals::GatherLocalsVisitor;
 use rustc_data_structures::unord::UnordSet;
-use rustc_errors::{struct_span_err, DiagnosticId, ErrorGuaranteed, MultiSpan};
+use rustc_errors::{
+    struct_span_err, DiagnosticId, DiagnosticMessage, ErrorGuaranteed, MultiSpan,
+    SubdiagnosticMessage,
+};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::Visitor;
@@ -61,13 +64,16 @@ use rustc_hir::{HirIdMap, Node};
 use rustc_hir_analysis::astconv::AstConv;
 use rustc_hir_analysis::check::check_abi;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use rustc_macros::fluent_messages;
 use rustc_middle::traits;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::config;
 use rustc_session::Session;
 use rustc_span::def_id::{DefId, LocalDefId};
-use rustc_span::Span;
+use rustc_span::{sym, Span};
+
+fluent_messages! { "../locales/en-US.ftl" }
 
 #[macro_export]
 macro_rules! type_error_struct {
@@ -201,6 +207,11 @@ fn typeck_with_fallback<'tcx>(
 
     let typeck_results = Inherited::build(tcx, def_id).enter(|inh| {
         let param_env = tcx.param_env(def_id);
+        let param_env = if tcx.has_attr(def_id.to_def_id(), sym::rustc_do_not_const_check) {
+            param_env.without_const()
+        } else {
+            param_env
+        };
         let mut fcx = FnCtxt::new(&inh, param_env, def_id);
 
         if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs
index 4b08832eddc..bcfc61bffb2 100644
--- a/compiler/rustc_hir_typeck/src/mem_categorization.rs
+++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs
@@ -51,7 +51,7 @@
 use rustc_middle::hir::place::*;
 use rustc_middle::ty::adjustment;
 use rustc_middle::ty::fold::TypeFoldable;
-use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_hir as hir;
@@ -126,7 +126,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
 
     fn resolve_vars_if_possible<T>(&self, value: T) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         self.infcx.resolve_vars_if_possible(value)
     }
@@ -383,7 +383,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
             | hir::ExprKind::Repeat(..)
             | hir::ExprKind::InlineAsm(..)
             | hir::ExprKind::Box(..)
-            | hir::ExprKind::Err => Ok(self.cat_rvalue(expr.hir_id, expr.span, expr_ty)),
+            | hir::ExprKind::Err(_) => Ok(self.cat_rvalue(expr.hir_id, expr.span, expr_ty)),
         }
     }
 
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index f7de55c989f..169f128e0a0 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -14,7 +14,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
 use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::subst::{self, SubstsRef};
-use rustc_middle::ty::{self, GenericParamDefKind, Ty};
+use rustc_middle::ty::{self, GenericParamDefKind, Ty, TyCtxt};
 use rustc_middle::ty::{InternalSubsts, UserSubsts, UserType};
 use rustc_span::{Span, DUMMY_SP};
 use rustc_trait_selection::traits;
@@ -635,7 +635,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
 
     fn instantiate_binder_with_fresh_vars<T>(&self, value: ty::Binder<'tcx, T>) -> T
     where
-        T: TypeFoldable<'tcx> + Copy,
+        T: TypeFoldable<TyCtxt<'tcx>> + Copy,
     {
         self.fcx.instantiate_binder_with_fresh_vars(self.span, infer::FnCall, value)
     }
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index d5d10cf272a..0456dd56c34 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -20,7 +20,7 @@ use rustc_hir::def_id::DefId;
 use rustc_infer::infer::{self, InferOk};
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
-use rustc_middle::ty::{self, GenericParamDefKind, Ty, TypeVisitable};
+use rustc_middle::ty::{self, GenericParamDefKind, Ty, TypeVisitableExt};
 use rustc_span::symbol::Ident;
 use rustc_span::Span;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
@@ -380,6 +380,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             );
             return None;
         };
+
+        if method_item.kind != ty::AssocKind::Fn {
+            self.tcx.sess.delay_span_bug(tcx.def_span(method_item.def_id), "not a method");
+            return None;
+        }
+
         let def_id = method_item.def_id;
         let generics = tcx.generics_of(def_id);
 
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 88af554483b..3bef5cfcd78 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -19,7 +19,7 @@ use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
 use rustc_middle::ty::AssocItem;
 use rustc_middle::ty::GenericParamDefKind;
 use rustc_middle::ty::ToPredicate;
-use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFoldable};
+use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
 use rustc_middle::ty::{InternalSubsts, SubstsRef};
 use rustc_session::lint;
 use rustc_span::def_id::DefId;
@@ -1095,17 +1095,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
     }
 
     fn pick_core(&self) -> Option<PickResult<'tcx>> {
-        let pick = self.pick_all_method(Some(&mut vec![]));
-
-        // In this case unstable picking is done by `pick_method`.
-        if !self.tcx.sess.opts.unstable_opts.pick_stable_methods_before_any_unstable {
-            return pick;
-        }
-
-        if pick.is_none() {
-            return self.pick_all_method(None);
-        }
-        pick
+        // Pick stable methods only first, and consider unstable candidates if not found.
+        self.pick_all_method(Some(&mut vec![])).or_else(|| self.pick_all_method(None))
     }
 
     fn pick_all_method(
@@ -1244,54 +1235,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         })
     }
 
-    fn pick_method_with_unstable(&self, self_ty: Ty<'tcx>) -> Option<PickResult<'tcx>> {
-        debug!("pick_method_with_unstable(self_ty={})", self.ty_to_string(self_ty));
-
-        let mut possibly_unsatisfied_predicates = Vec::new();
-
-        for (kind, candidates) in
-            &[("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)]
-        {
-            debug!("searching {} candidates", kind);
-            let res = self.consider_candidates(
-                self_ty,
-                candidates,
-                &mut possibly_unsatisfied_predicates,
-                Some(&mut vec![]),
-            );
-            if res.is_some() {
-                return res;
-            }
-        }
-
-        for (kind, candidates) in
-            &[("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)]
-        {
-            debug!("searching unstable {kind} candidates");
-            let res = self.consider_candidates(
-                self_ty,
-                candidates,
-                &mut possibly_unsatisfied_predicates,
-                None,
-            );
-            if res.is_some() {
-                return res;
-            }
-        }
-
-        self.unsatisfied_predicates.borrow_mut().extend(possibly_unsatisfied_predicates);
-        None
-    }
-
     fn pick_method(
         &self,
         self_ty: Ty<'tcx>,
         mut unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
     ) -> Option<PickResult<'tcx>> {
-        if !self.tcx.sess.opts.unstable_opts.pick_stable_methods_before_any_unstable {
-            return self.pick_method_with_unstable(self_ty);
-        }
-
         debug!("pick_method(self_ty={})", self.ty_to_string(self_ty));
 
         let mut possibly_unsatisfied_predicates = Vec::new();
@@ -1418,8 +1366,8 @@ impl<'tcx> Pick<'tcx> {
             span,
             format!(
                 "{} {} with this name may be added to the standard library in the future",
-                def_kind.article(),
-                def_kind.descr(self.item.def_id),
+                tcx.def_kind_descr_article(def_kind, self.item.def_id),
+                tcx.def_kind_descr(def_kind, self.item.def_id),
             ),
             |lint| {
                 match (self.item.kind, self.item.container) {
@@ -1488,7 +1436,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             TraitCandidate(trait_ref) => self.probe(|_| {
                 let _ = self
                     .at(&ObligationCause::dummy(), self.param_env)
-                    .define_opaque_types(false)
                     .sup(candidate.xform_self_ty, self_ty);
                 match self.select_trait_candidate(trait_ref) {
                     Ok(Some(traits::ImplSource::UserDefined(ref impl_data))) => {
@@ -1518,7 +1465,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             // First check that the self type can be related.
             let sub_obligations = match self
                 .at(&ObligationCause::dummy(), self.param_env)
-                .define_opaque_types(false)
                 .sup(probe.xform_self_ty, self_ty)
             {
                 Ok(InferOk { obligations, value: () }) => obligations,
@@ -1735,7 +1681,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                 if let ProbeResult::Match = result
                     && self
                     .at(&ObligationCause::dummy(), self.param_env)
-                    .define_opaque_types(false)
                     .sup(return_ty, xform_ret_ty)
                     .is_err()
                 {
@@ -1960,7 +1905,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
     ///    so forth.
     fn erase_late_bound_regions<T>(&self, value: ty::Binder<'tcx, T>) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         self.tcx.erase_late_bound_regions(value)
     }
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 4f3dbe03c05..47a4d4e72df 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -27,7 +27,7 @@ use rustc_middle::traits::util::supertraits;
 use rustc_middle::ty::fast_reject::DeepRejectCtxt;
 use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
 use rustc_middle::ty::print::{with_crate_prefix, with_forced_trimmed_paths};
-use rustc_middle::ty::{self, DefIdTree, GenericArgKind, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, DefIdTree, GenericArgKind, Ty, TyCtxt, TypeVisitableExt};
 use rustc_middle::ty::{IsSuggestable, ToPolyTraitRef};
 use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::Symbol;
@@ -160,7 +160,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
 
             MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => {
-                let kind = kind.descr(def_id);
+                let kind = self.tcx.def_kind_descr(kind, def_id);
                 let mut err = struct_span_err!(
                     self.tcx.sess,
                     item_name.span,
@@ -574,7 +574,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         // `<Foo as Iterator>::Item = String`.
                         let projection_ty = pred.skip_binder().projection_ty;
 
-                        let substs_with_infer_self = tcx.mk_substs(
+                        let substs_with_infer_self = tcx.mk_substs_from_iter(
                             iter::once(tcx.mk_ty_var(ty::TyVid::from_u32(0)).into())
                                 .chain(projection_ty.substs.iter().skip(1)),
                         );
@@ -1062,8 +1062,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         span,
                         &format!(
                             "there is {} {} with a similar name",
-                            def_kind.article(),
-                            def_kind.descr(similar_candidate.def_id),
+                            self.tcx.def_kind_descr_article(def_kind, similar_candidate.def_id),
+                            self.tcx.def_kind_descr(def_kind, similar_candidate.def_id)
                         ),
                         similar_candidate.name,
                         Applicability::MaybeIncorrect,
@@ -1172,7 +1172,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             path,
                             ty,
                             item.kind,
-                            item.def_id,
+                            self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id),
                             sugg_span,
                             idx,
                             self.tcx.sess.source_map(),
@@ -1208,7 +1208,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             path,
                             rcvr_ty,
                             item.kind,
-                            item.def_id,
+                            self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id),
                             sugg_span,
                             idx,
                             self.tcx.sess.source_map(),
@@ -1252,7 +1252,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             if let ty::Adt(def, substs) = target_ty.kind() {
                 // If there are any inferred arguments, (`{integer}`), we should replace
                 // them with underscores to allow the compiler to infer them
-                let infer_substs = self.tcx.mk_substs(substs.into_iter().map(|arg| {
+                let infer_substs = self.tcx.mk_substs_from_iter(substs.into_iter().map(|arg| {
                     if !arg.is_suggestable(self.tcx, true) {
                         has_unsuggestable_args = true;
                         match arg.unpack() {
@@ -2853,7 +2853,7 @@ fn print_disambiguation_help<'tcx>(
     trait_name: String,
     rcvr_ty: Ty<'_>,
     kind: ty::AssocKind,
-    def_id: DefId,
+    def_kind_descr: &'static str,
     span: Span,
     candidate: Option<usize>,
     source_map: &source_map::SourceMap,
@@ -2886,7 +2886,7 @@ fn print_disambiguation_help<'tcx>(
         span,
         &format!(
             "disambiguate the {} for {}",
-            kind.as_def_kind().descr(def_id),
+            def_kind_descr,
             if let Some(candidate) = candidate {
                 format!("candidate #{}", candidate)
             } else {
diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs
index c8256e7ec08..a4b325a9b79 100644
--- a/compiler/rustc_hir_typeck/src/op.rs
+++ b/compiler/rustc_hir_typeck/src/op.rs
@@ -13,7 +13,7 @@ use rustc_middle::ty::adjustment::{
 };
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{
-    self, ir::TypeFolder, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeSuperFoldable, TypeVisitable,
+    self, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
 };
 use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::source_map::Spanned;
@@ -297,7 +297,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 method.sig.output()
             }
             // error types are considered "builtin"
-            Err(_) if lhs_ty.references_error() || rhs_ty.references_error() => self.tcx.ty_error(),
+            Err(_) if lhs_ty.references_error() || rhs_ty.references_error() => {
+                self.tcx.ty_error_misc()
+            }
             Err(errors) => {
                 let (_, trait_def_id) =
                     lang_item_for_op(self.tcx, Op::Binary(op, is_assign), op.span);
@@ -518,7 +520,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     }
                 }
                 let reported = err.emit();
-                self.tcx.ty_error_with_guaranteed(reported)
+                self.tcx.ty_error(reported)
             }
         };
 
@@ -631,7 +633,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             Err(errors) => {
                 let actual = self.resolve_vars_if_possible(operand_ty);
-                if !actual.references_error() {
+                let guar = actual.error_reported().err().unwrap_or_else(|| {
                     let mut err = struct_span_err!(
                         self.tcx.sess,
                         ex.span,
@@ -701,9 +703,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             }
                         }
                     }
-                    err.emit();
-                }
-                self.tcx.ty_error()
+                    err.emit()
+                });
+                self.tcx.ty_error(guar)
             }
         }
     }
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index ab6e76ef8aa..c36c75e4443 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -12,7 +12,7 @@ use rustc_hir::{HirId, Pat, PatKind};
 use rustc_infer::infer;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_middle::middle::stability::EvalResult;
-use rustc_middle::ty::{self, Adt, BindingMode, Ty, TypeVisitable};
+use rustc_middle::ty::{self, Adt, BindingMode, Ty, TypeVisitableExt};
 use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
 use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::hygiene::DesugaringKind;
@@ -475,8 +475,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if let (Some((true, ..)), _) | (_, Some((true, ..))) = (lhs, rhs) {
             // There exists a side that didn't meet our criteria that the end-point
             // be of a numeric or char type, as checked in `calc_side` above.
-            self.emit_err_pat_range(span, lhs, rhs);
-            return self.tcx.ty_error();
+            let guar = self.emit_err_pat_range(span, lhs, rhs);
+            return self.tcx.ty_error(guar);
         }
 
         // Unify each side with `expected`.
@@ -496,7 +496,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         demand_eqtype(&mut rhs, lhs);
 
         if let (Some((true, ..)), _) | (_, Some((true, ..))) = (lhs, rhs) {
-            return self.tcx.ty_error();
+            return self.tcx.ty_error_misc();
         }
 
         // Find the unified type and check if it's of numeric or char type again.
@@ -511,8 +511,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             if let Some((ref mut fail, _, _)) = rhs {
                 *fail = true;
             }
-            self.emit_err_pat_range(span, lhs, rhs);
-            return self.tcx.ty_error();
+            let guar = self.emit_err_pat_range(span, lhs, rhs);
+            return self.tcx.ty_error(guar);
         }
         ty
     }
@@ -528,7 +528,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         span: Span,
         lhs: Option<(bool, Ty<'tcx>, Span)>,
         rhs: Option<(bool, Ty<'tcx>, Span)>,
-    ) {
+    ) -> ErrorGuaranteed {
         let span = match (lhs, rhs) {
             (Some((true, ..)), Some((true, ..))) => span,
             (Some((true, _, sp)), _) => sp,
@@ -573,7 +573,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     type between two end-points, you can use a guard.",
             );
         }
-        err.emit();
+        err.emit()
     }
 
     fn check_pat_ident(
@@ -807,29 +807,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn check_dereferenceable(&self, span: Span, expected: Ty<'tcx>, inner: &Pat<'_>) -> bool {
+    pub fn check_dereferenceable(
+        &self,
+        span: Span,
+        expected: Ty<'tcx>,
+        inner: &Pat<'_>,
+    ) -> Result<(), ErrorGuaranteed> {
         if let PatKind::Binding(..) = inner.kind
             && let Some(mt) = self.shallow_resolve(expected).builtin_deref(true)
             && let ty::Dynamic(..) = mt.ty.kind()
         {
-                    // This is "x = SomeTrait" being reduced from
-                    // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
-                    let type_str = self.ty_to_string(expected);
-                    let mut err = struct_span_err!(
-                        self.tcx.sess,
-                        span,
-                        E0033,
-                        "type `{}` cannot be dereferenced",
-                        type_str
-                    );
-                    err.span_label(span, format!("type `{type_str}` cannot be dereferenced"));
-                    if self.tcx.sess.teach(&err.get_code().unwrap()) {
-                        err.note(CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ);
-                    }
-                    err.emit();
-                    return false;
-                }
-        true
+            // This is "x = SomeTrait" being reduced from
+            // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
+            let type_str = self.ty_to_string(expected);
+            let mut err = struct_span_err!(
+                self.tcx.sess,
+                span,
+                E0033,
+                "type `{}` cannot be dereferenced",
+                type_str
+            );
+            err.span_label(span, format!("type `{type_str}` cannot be dereferenced"));
+            if self.tcx.sess.teach(&err.get_code().unwrap()) {
+                err.note(CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ);
+            }
+            return Err(err.emit());
+        }
+        Ok(())
     }
 
     fn check_pat_struct(
@@ -843,13 +847,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         ti: TopInfo<'tcx>,
     ) -> Ty<'tcx> {
         // Resolve the path and check the definition for errors.
-        let Some((variant, pat_ty)) = self.check_struct_path(qpath, pat.hir_id) else {
-            let err = self.tcx.ty_error();
-            for field in fields {
-                let ti = ti;
-                self.check_pat(field.pat, err, def_bm, ti);
+        let (variant, pat_ty) = match self.check_struct_path(qpath, pat.hir_id) {
+            Ok(data) => data,
+            Err(guar) => {
+                let err = self.tcx.ty_error(guar);
+                for field in fields {
+                    let ti = ti;
+                    self.check_pat(field.pat, err, def_bm, ti);
+                }
+                return err;
             }
-            return err;
         };
 
         // Type-check the path.
@@ -859,7 +866,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if self.check_struct_pat_fields(pat_ty, &pat, variant, fields, has_rest_pat, def_bm, ti) {
             pat_ty
         } else {
-            self.tcx.ty_error()
+            self.tcx.ty_error_misc()
         }
     }
 
@@ -879,12 +886,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             Res::Err => {
                 let e = tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted");
                 self.set_tainted_by_errors(e);
-                return tcx.ty_error_with_guaranteed(e);
+                return tcx.ty_error(e);
             }
             Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::Variant, _) => {
                 let expected = "unit struct, unit variant or constant";
                 let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, "E0533", expected);
-                return tcx.ty_error_with_guaranteed(e);
+                return tcx.ty_error(e);
             }
             Res::SelfCtor(..)
             | Res::Def(
@@ -1027,7 +1034,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let tcx = self.tcx;
         let on_error = |e| {
             for pat in subpats {
-                self.check_pat(pat, tcx.ty_error_with_guaranteed(e), def_bm, ti);
+                self.check_pat(pat, tcx.ty_error(e), def_bm, ti);
             }
         };
         let report_unexpected_res = |res: Res| {
@@ -1044,7 +1051,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let e = tcx.sess.delay_span_bug(pat.span, "`Res::Err` but no error emitted");
             self.set_tainted_by_errors(e);
             on_error(e);
-            return tcx.ty_error_with_guaranteed(e);
+            return tcx.ty_error(e);
         }
 
         // Type-check the path.
@@ -1052,7 +1059,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id);
         if !pat_ty.is_fn() {
             let e = report_unexpected_res(res);
-            return tcx.ty_error_with_guaranteed(e);
+            return tcx.ty_error(e);
         }
 
         let variant = match res {
@@ -1060,11 +1067,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let e = tcx.sess.delay_span_bug(pat.span, "`Res::Err` but no error emitted");
                 self.set_tainted_by_errors(e);
                 on_error(e);
-                return tcx.ty_error_with_guaranteed(e);
+                return tcx.ty_error(e);
             }
             Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) => {
                 let e = report_unexpected_res(res);
-                return tcx.ty_error_with_guaranteed(e);
+                return tcx.ty_error(e);
             }
             Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => tcx.expect_variant_res(res),
             _ => bug!("unexpected pattern resolution: {:?}", res),
@@ -1105,7 +1112,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // Pattern has wrong number of fields.
             let e = self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err);
             on_error(e);
-            return tcx.ty_error_with_guaranteed(e);
+            return tcx.ty_error(e);
         }
         pat_ty
     }
@@ -1295,17 +1302,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span },
             )
         });
-        let element_tys = tcx.mk_type_list(element_tys_iter);
-        let pat_ty = tcx.intern_tup(element_tys);
+        let element_tys = tcx.mk_type_list_from_iter(element_tys_iter);
+        let pat_ty = tcx.mk_tup(element_tys);
         if let Some(mut err) = self.demand_eqtype_pat_diag(span, expected, pat_ty, ti) {
             let reported = err.emit();
             // Walk subpatterns with an expected type of `err` in this case to silence
             // further errors being emitted when using the bindings. #50333
-            let element_tys_iter = (0..max_len).map(|_| tcx.ty_error_with_guaranteed(reported));
+            let element_tys_iter = (0..max_len).map(|_| tcx.ty_error(reported));
             for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
-                self.check_pat(elem, tcx.ty_error_with_guaranteed(reported), def_bm, ti);
+                self.check_pat(elem, tcx.ty_error(reported), def_bm, ti);
             }
-            tcx.mk_tup(element_tys_iter)
+            tcx.mk_tup_from_iter(element_tys_iter)
         } else {
             for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
                 self.check_pat(elem, element_tys[i], def_bm, ti);
@@ -1349,9 +1356,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let ident = tcx.adjust_ident(field.ident, variant.def_id);
             let field_ty = match used_fields.entry(ident) {
                 Occupied(occupied) => {
-                    self.error_field_already_bound(span, field.ident, *occupied.get());
                     no_field_errors = false;
-                    tcx.ty_error()
+                    let guar = self.error_field_already_bound(span, field.ident, *occupied.get());
+                    tcx.ty_error(guar)
                 }
                 Vacant(vacant) => {
                     vacant.insert(span);
@@ -1365,7 +1372,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         .unwrap_or_else(|| {
                             inexistent_fields.push(field);
                             no_field_errors = false;
-                            tcx.ty_error()
+                            tcx.ty_error_misc()
                         })
                 }
             };
@@ -1536,7 +1543,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err.emit();
     }
 
-    fn error_field_already_bound(&self, span: Span, ident: Ident, other_field: Span) {
+    fn error_field_already_bound(
+        &self,
+        span: Span,
+        ident: Ident,
+        other_field: Span,
+    ) -> ErrorGuaranteed {
         struct_span_err!(
             self.tcx.sess,
             span,
@@ -1546,7 +1558,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         )
         .span_label(span, format!("multiple uses of `{ident}` in pattern"))
         .span_label(other_field, format!("first use of `{ident}`"))
-        .emit();
+        .emit()
     }
 
     fn error_inexistent_fields(
@@ -1919,19 +1931,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         ti: TopInfo<'tcx>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
-        let (box_ty, inner_ty) = if self.check_dereferenceable(span, expected, inner) {
-            // Here, `demand::subtype` is good enough, but I don't
-            // think any errors can be introduced by using `demand::eqtype`.
-            let inner_ty = self.next_ty_var(TypeVariableOrigin {
-                kind: TypeVariableOriginKind::TypeInference,
-                span: inner.span,
-            });
-            let box_ty = tcx.mk_box(inner_ty);
-            self.demand_eqtype_pat(span, expected, box_ty, ti);
-            (box_ty, inner_ty)
-        } else {
-            let err = tcx.ty_error();
-            (err, err)
+        let (box_ty, inner_ty) = match self.check_dereferenceable(span, expected, inner) {
+            Ok(()) => {
+                // Here, `demand::subtype` is good enough, but I don't
+                // think any errors can be introduced by using `demand::eqtype`.
+                let inner_ty = self.next_ty_var(TypeVariableOrigin {
+                    kind: TypeVariableOriginKind::TypeInference,
+                    span: inner.span,
+                });
+                let box_ty = tcx.mk_box(inner_ty);
+                self.demand_eqtype_pat(span, expected, box_ty, ti);
+                (box_ty, inner_ty)
+            }
+            Err(guar) => {
+                let err = tcx.ty_error(guar);
+                (err, err)
+            }
         };
         self.check_pat(inner, inner_ty, def_bm, ti);
         box_ty
@@ -1949,37 +1964,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
         let expected = self.shallow_resolve(expected);
-        let (ref_ty, inner_ty) = if self.check_dereferenceable(pat.span, expected, inner) {
-            // `demand::subtype` would be good enough, but using `eqtype` turns
-            // out to be equally general. See (note_1) for details.
-
-            // Take region, inner-type from expected type if we can,
-            // to avoid creating needless variables. This also helps with
-            // the bad interactions of the given hack detailed in (note_1).
-            debug!("check_pat_ref: expected={:?}", expected);
-            match *expected.kind() {
-                ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty),
-                _ => {
-                    let inner_ty = self.next_ty_var(TypeVariableOrigin {
-                        kind: TypeVariableOriginKind::TypeInference,
-                        span: inner.span,
-                    });
-                    let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty);
-                    debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty);
-                    let err = self.demand_eqtype_pat_diag(pat.span, expected, ref_ty, ti);
-
-                    // Look for a case like `fn foo(&foo: u32)` and suggest
-                    // `fn foo(foo: &u32)`
-                    if let Some(mut err) = err {
-                        self.borrow_pat_suggestion(&mut err, pat);
-                        err.emit();
+        let (ref_ty, inner_ty) = match self.check_dereferenceable(pat.span, expected, inner) {
+            Ok(()) => {
+                // `demand::subtype` would be good enough, but using `eqtype` turns
+                // out to be equally general. See (note_1) for details.
+
+                // Take region, inner-type from expected type if we can,
+                // to avoid creating needless variables. This also helps with
+                // the bad interactions of the given hack detailed in (note_1).
+                debug!("check_pat_ref: expected={:?}", expected);
+                match *expected.kind() {
+                    ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty),
+                    _ => {
+                        let inner_ty = self.next_ty_var(TypeVariableOrigin {
+                            kind: TypeVariableOriginKind::TypeInference,
+                            span: inner.span,
+                        });
+                        let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty);
+                        debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty);
+                        let err = self.demand_eqtype_pat_diag(pat.span, expected, ref_ty, ti);
+
+                        // Look for a case like `fn foo(&foo: u32)` and suggest
+                        // `fn foo(foo: &u32)`
+                        if let Some(mut err) = err {
+                            self.borrow_pat_suggestion(&mut err, pat);
+                            err.emit();
+                        }
+                        (ref_ty, inner_ty)
                     }
-                    (ref_ty, inner_ty)
                 }
             }
-        } else {
-            let err = tcx.ty_error();
-            (err, err)
+            Err(guar) => {
+                let err = tcx.ty_error(guar);
+                (err, err)
+            }
         };
         self.check_pat(inner, inner_ty, def_bm, ti);
         ref_ty
@@ -2027,10 +2045,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ty::Slice(element_ty) => (element_ty, Some(expected), expected),
             // The expected type must be an array or slice, but was neither, so error.
             _ => {
-                if !expected.references_error() {
-                    self.error_expected_array_or_slice(span, expected, ti);
-                }
-                let err = self.tcx.ty_error();
+                let guar = expected
+                    .error_reported()
+                    .err()
+                    .unwrap_or_else(|| self.error_expected_array_or_slice(span, expected, ti));
+                let err = self.tcx.ty_error(guar);
                 (err, Some(err), err)
             }
         };
@@ -2063,7 +2082,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         len: ty::Const<'tcx>,
         min_len: u64,
     ) -> (Option<Ty<'tcx>>, Ty<'tcx>) {
-        if let Some(len) = len.try_eval_target_usize(self.tcx, self.param_env) {
+        let guar = if let Some(len) = len.try_eval_target_usize(self.tcx, self.param_env) {
             // Now we know the length...
             if slice.is_none() {
                 // ...and since there is no variable-length pattern,
@@ -2073,7 +2092,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     return (None, arr_ty);
                 }
 
-                self.error_scrutinee_inconsistent_length(span, min_len, len);
+                self.error_scrutinee_inconsistent_length(span, min_len, len)
             } else if let Some(pat_len) = len.checked_sub(min_len) {
                 // The variable-length pattern was there,
                 // so it has an array type with the remaining elements left as its size...
@@ -2081,7 +2100,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             } else {
                 // ...however, in this case, there were no remaining elements.
                 // That is, the slice pattern requires more than the array type offers.
-                self.error_scrutinee_with_rest_inconsistent_length(span, min_len, len);
+                self.error_scrutinee_with_rest_inconsistent_length(span, min_len, len)
             }
         } else if slice.is_none() {
             // We have a pattern with a fixed length,
@@ -2093,14 +2112,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // We have a variable-length pattern and don't know the array length.
             // This happens if we have e.g.,
             // `let [a, b, ..] = arr` where `arr: [T; N]` where `const N: usize`.
-            self.error_scrutinee_unfixed_length(span);
-        }
+            self.error_scrutinee_unfixed_length(span)
+        };
 
         // If we get here, we must have emitted an error.
-        (Some(self.tcx.ty_error()), arr_ty)
+        (Some(self.tcx.ty_error(guar)), arr_ty)
     }
 
-    fn error_scrutinee_inconsistent_length(&self, span: Span, min_len: u64, size: u64) {
+    fn error_scrutinee_inconsistent_length(
+        &self,
+        span: Span,
+        min_len: u64,
+        size: u64,
+    ) -> ErrorGuaranteed {
         struct_span_err!(
             self.tcx.sess,
             span,
@@ -2111,10 +2135,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             size,
         )
         .span_label(span, format!("expected {} element{}", size, pluralize!(size)))
-        .emit();
+        .emit()
     }
 
-    fn error_scrutinee_with_rest_inconsistent_length(&self, span: Span, min_len: u64, size: u64) {
+    fn error_scrutinee_with_rest_inconsistent_length(
+        &self,
+        span: Span,
+        min_len: u64,
+        size: u64,
+    ) -> ErrorGuaranteed {
         struct_span_err!(
             self.tcx.sess,
             span,
@@ -2128,20 +2157,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             span,
             format!("pattern cannot match array of {} element{}", size, pluralize!(size),),
         )
-        .emit();
+        .emit()
     }
 
-    fn error_scrutinee_unfixed_length(&self, span: Span) {
+    fn error_scrutinee_unfixed_length(&self, span: Span) -> ErrorGuaranteed {
         struct_span_err!(
             self.tcx.sess,
             span,
             E0730,
             "cannot pattern-match on an array without a fixed length",
         )
-        .emit();
+        .emit()
     }
 
-    fn error_expected_array_or_slice(&self, span: Span, expected_ty: Ty<'tcx>, ti: TopInfo<'tcx>) {
+    fn error_expected_array_or_slice(
+        &self,
+        span: Span,
+        expected_ty: Ty<'tcx>,
+        ti: TopInfo<'tcx>,
+    ) -> ErrorGuaranteed {
         let mut err = struct_span_err!(
             self.tcx.sess,
             span,
@@ -2185,7 +2219,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
         err.span_label(span, format!("pattern cannot match with input type `{expected_ty}`"));
-        err.emit();
+        err.emit()
     }
 
     fn is_slice_or_array_or_vector(&self, ty: Ty<'tcx>) -> (bool, Ty<'tcx>) {
diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs
index ae0df5aa8f1..8fcec3363c0 100644
--- a/compiler/rustc_hir_typeck/src/place_op.rs
+++ b/compiler/rustc_hir_typeck/src/place_op.rs
@@ -91,10 +91,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             );
         }
         let reported = err.emit();
-        Some((
-            self.tcx.ty_error_with_guaranteed(reported),
-            self.tcx.ty_error_with_guaranteed(reported),
-        ))
+        Some((self.tcx.ty_error(reported), self.tcx.ty_error(reported)))
     }
 
     /// To type-check `base_expr[index_expr]`, we progressively autoderef
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index 7c8abb4186f..e94915c754e 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -301,7 +301,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Build a tuple (U0..Un) of the final upvar types U0..Un
         // and unify the upvar tuple type in the closure with it:
-        let final_tupled_upvars_type = self.tcx.intern_tup(&final_upvar_tys);
+        let final_tupled_upvars_type = self.tcx.mk_tup(&final_upvar_tys);
         self.demand_suptype(span, substs.tupled_upvars_ty(), final_tupled_upvars_type);
 
         let fake_reads = delegate
@@ -315,8 +315,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.typeck_results.borrow_mut().closure_size_eval.insert(
                 closure_def_id,
                 ClosureSizeProfileData {
-                    before_feature_tys: self.tcx.intern_tup(&before_feature_tys),
-                    after_feature_tys: self.tcx.intern_tup(&after_feature_tys),
+                    before_feature_tys: self.tcx.mk_tup(&before_feature_tys),
+                    after_feature_tys: self.tcx.mk_tup(&after_feature_tys),
                 },
             );
         }
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index b6c9a88c82d..00348f3afdc 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -13,8 +13,8 @@ use rustc_infer::infer::InferCtxt;
 use rustc_middle::hir::place::Place as HirPlace;
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
-use rustc_middle::ty::fold::{ir::TypeFolder, TypeFoldable, TypeSuperFoldable};
-use rustc_middle::ty::visit::TypeSuperVisitable;
+use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
+use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
 use rustc_middle::ty::TypeckResults;
 use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt};
 use rustc_span::symbol::sym;
@@ -561,7 +561,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
             struct RecursionChecker {
                 def_id: LocalDefId,
             }
-            impl<'tcx> ty::ir::TypeVisitor<TyCtxt<'tcx>> for RecursionChecker {
+            impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for RecursionChecker {
                 type BreakTy = ();
                 fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
                     if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *t.kind() {
@@ -685,7 +685,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
 
     fn resolve<T>(&mut self, x: T, span: &dyn Locatable) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         let mut resolver = Resolver::new(self.fcx, span, self.body);
         let x = x.fold_with(&mut resolver);
@@ -797,7 +797,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> {
                 debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
                 let e = self.report_error(t);
                 self.replaced_with_error = Some(e);
-                self.interner().ty_error_with_guaranteed(e)
+                self.interner().ty_error(e)
             }
         }
     }
diff --git a/compiler/rustc_incremental/Cargo.toml b/compiler/rustc_incremental/Cargo.toml
index 179e85f32c9..ad89393956e 100644
--- a/compiler/rustc_incremental/Cargo.toml
+++ b/compiler/rustc_incremental/Cargo.toml
@@ -6,16 +6,17 @@ edition = "2021"
 [lib]
 
 [dependencies]
-rustc_graphviz = { path = "../rustc_graphviz" }
-tracing = "0.1"
 rand = "0.8.4"
-rustc_middle = { path = "../rustc_middle" }
+rustc_ast = { path = "../rustc_ast" }
 rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
+rustc_fs_util = { path = "../rustc_fs_util" }
+rustc_graphviz = { path = "../rustc_graphviz" }
 rustc_hir = { path = "../rustc_hir" }
-rustc_serialize = { path = "../rustc_serialize" }
-rustc_ast = { path = "../rustc_ast" }
 rustc_macros = { path = "../rustc_macros" }
-rustc_span = { path = "../rustc_span" }
-rustc_fs_util = { path = "../rustc_fs_util" }
+rustc_middle = { path = "../rustc_middle" }
+rustc_serialize = { path = "../rustc_serialize" }
 rustc_session = { path = "../rustc_session" }
-rustc_errors = { path = "../rustc_errors" }
+rustc_span = { path = "../rustc_span" }
+thin-vec = "0.2.12"
+tracing = "0.1"
diff --git a/compiler/rustc_error_messages/locales/en-US/incremental.ftl b/compiler/rustc_incremental/locales/en-US.ftl
index 4852ee0d959..4852ee0d959 100644
--- a/compiler/rustc_error_messages/locales/en-US/incremental.ftl
+++ b/compiler/rustc_incremental/locales/en-US.ftl
diff --git a/compiler/rustc_incremental/src/assert_module_sources.rs b/compiler/rustc_incremental/src/assert_module_sources.rs
index 2968a0e1203..b4b0ea00c50 100644
--- a/compiler/rustc_incremental/src/assert_module_sources.rs
+++ b/compiler/rustc_incremental/src/assert_module_sources.rs
@@ -30,6 +30,7 @@ use rustc_middle::mir::mono::CodegenUnitNameBuilder;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::cgu_reuse_tracker::*;
 use rustc_span::symbol::{sym, Symbol};
+use thin_vec::ThinVec;
 
 #[allow(missing_docs)]
 pub fn assert_module_sources(tcx: TyCtxt<'_>) {
@@ -138,7 +139,7 @@ impl<'tcx> AssertModuleSource<'tcx> {
     }
 
     fn field(&self, attr: &ast::Attribute, name: Symbol) -> Symbol {
-        for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
+        for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) {
             if item.has_name(name) {
                 if let Some(value) = item.value_str() {
                     return value;
diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs
index 3c58cfa38f2..511e466c2ae 100644
--- a/compiler/rustc_incremental/src/lib.rs
+++ b/compiler/rustc_incremental/src/lib.rs
@@ -31,3 +31,8 @@ pub use persist::save_dep_graph;
 pub use persist::save_work_product_index;
 pub use persist::LoadResult;
 pub use persist::{build_dep_graph, load_dep_graph, DepGraphFuture};
+
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_macros::fluent_messages;
+
+fluent_messages! { "../locales/en-US.ftl" }
diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs
index c6e63998c79..b839416c919 100644
--- a/compiler/rustc_incremental/src/persist/dirty_clean.rs
+++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs
@@ -31,6 +31,8 @@ use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
+use std::iter::FromIterator;
+use thin_vec::ThinVec;
 
 const LOADED_FROM_DISK: Symbol = sym::loaded_from_disk;
 const EXCEPT: Symbol = sym::except;
@@ -205,7 +207,7 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
 
     /// `loaded_from_disk=` attribute value
     fn loaded_from_disk(&self, attr: &Attribute) -> Labels {
-        for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
+        for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) {
             if item.has_name(LOADED_FROM_DISK) {
                 let value = expect_associated_value(self.tcx, &item);
                 return self.resolve_labels(&item, value);
@@ -217,7 +219,7 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
 
     /// `except=` attribute value
     fn except(&self, attr: &Attribute) -> Labels {
-        for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
+        for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) {
             if item.has_name(EXCEPT) {
                 let value = expect_associated_value(self.tcx, &item);
                 return self.resolve_labels(&item, value);
@@ -397,7 +399,7 @@ fn check_config(tcx: TyCtxt<'_>, attr: &Attribute) -> bool {
     let config = &tcx.sess.parse_sess.config;
     debug!("check_config: config={:?}", config);
     let mut cfg = None;
-    for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
+    for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) {
         if item.has_name(CFG) {
             let value = expect_associated_value(tcx, &item);
             debug!("check_config: searching for cfg {:?}", value);
diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_infer/locales/en-US.ftl
index c5b2b6c2d73..c5b2b6c2d73 100644
--- a/compiler/rustc_error_messages/locales/en-US/infer.ftl
+++ b/compiler/rustc_infer/locales/en-US.ftl
diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs
index 0c2713fb1a7..7dccd0bb930 100644
--- a/compiler/rustc_infer/src/errors/mod.rs
+++ b/compiler/rustc_infer/src/errors/mod.rs
@@ -1,6 +1,6 @@
 use hir::GenericParamKind;
 use rustc_errors::{
-    fluent, AddToDiagnostic, Applicability, Diagnostic, DiagnosticMessage, DiagnosticStyledString,
+    AddToDiagnostic, Applicability, Diagnostic, DiagnosticMessage, DiagnosticStyledString,
     IntoDiagnosticArg, MultiSpan, SubdiagnosticMessage,
 };
 use rustc_hir as hir;
@@ -12,9 +12,10 @@ use rustc_span::symbol::kw;
 use rustc_span::Symbol;
 use rustc_span::{symbol::Ident, BytePos, Span};
 
-use crate::infer::error_reporting::nice_region_error::placeholder_error::Highlighted;
+use crate::fluent_generated as fluent;
 use crate::infer::error_reporting::{
     need_type_info::{GeneratorKindAsDiagArg, UnderspecifiedArgKind},
+    nice_region_error::placeholder_error::Highlighted,
     ObligationCauseAsDiagArg,
 };
 
@@ -26,9 +27,9 @@ pub struct OpaqueHiddenTypeDiag {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[note(opaque_type)]
+    #[note(infer_opaque_type)]
     pub opaque_type: Span,
-    #[note(hidden_type)]
+    #[note(infer_hidden_type)]
     pub hidden_type: Span,
 }
 
@@ -768,11 +769,11 @@ impl<'tcx> ActualImplExplNotes<'tcx> {
 pub struct TraitPlaceholderMismatch<'tcx> {
     #[primary_span]
     pub span: Span,
-    #[label(label_satisfy)]
+    #[label(infer_label_satisfy)]
     pub satisfy_span: Option<Span>,
-    #[label(label_where)]
+    #[label(infer_label_where)]
     pub where_span: Option<Span>,
-    #[label(label_dup)]
+    #[label(infer_label_dup)]
     pub dup_span: Option<Span>,
     pub def_id: String,
     pub trait_def_id: String,
@@ -808,11 +809,11 @@ pub struct RelationshipHelp;
 #[diag(infer_trait_impl_diff)]
 pub struct TraitImplDiff {
     #[primary_span]
-    #[label(found)]
+    #[label(infer_found)]
     pub sp: Span,
-    #[label(expected)]
+    #[label(infer_expected)]
     pub trait_sp: Span,
-    #[note(expected_found)]
+    #[note(infer_expected_found)]
     pub note: (),
     #[subdiagnostic]
     pub param_help: ConsiderBorrowingParamHelp,
@@ -852,10 +853,10 @@ impl AddToDiagnostic for DynTraitConstraintSuggestion {
 #[derive(Diagnostic)]
 #[diag(infer_but_calling_introduces, code = "E0772")]
 pub struct ButCallingIntroduces {
-    #[label(label1)]
+    #[label(infer_label1)]
     pub param_ty_span: Span,
     #[primary_span]
-    #[label(label2)]
+    #[label(infer_label2)]
     pub cause_span: Span,
 
     pub has_param_name: bool,
@@ -913,15 +914,15 @@ impl AddToDiagnostic for MoreTargeted {
 pub struct ButNeedsToSatisfy {
     #[primary_span]
     pub sp: Span,
-    #[label(influencer)]
+    #[label(infer_influencer)]
     pub influencer_point: Span,
-    #[label(used_here)]
+    #[label(infer_used_here)]
     pub spans: Vec<Span>,
-    #[label(require)]
+    #[label(infer_require)]
     pub require_span_as_label: Option<Span>,
-    #[note(require)]
+    #[note(infer_require)]
     pub require_span_as_note: Option<Span>,
-    #[note(introduced_by_bound)]
+    #[note(infer_introduced_by_bound)]
     pub bound: Option<Span>,
 
     #[subdiagnostic]
diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs
index cb96aeec5f3..ef543b1fb93 100644
--- a/compiler/rustc_infer/src/errors/note_and_explain.rs
+++ b/compiler/rustc_infer/src/errors/note_and_explain.rs
@@ -1,7 +1,6 @@
+use crate::fluent_generated as fluent;
 use crate::infer::error_reporting::nice_region_error::find_anon_type;
-use rustc_errors::{
-    self, fluent, AddToDiagnostic, Diagnostic, IntoDiagnosticArg, SubdiagnosticMessage,
-};
+use rustc_errors::{self, AddToDiagnostic, Diagnostic, IntoDiagnosticArg, SubdiagnosticMessage};
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::{symbol::kw, Span};
 
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index d816a9ed3d7..c952ddc827a 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -55,7 +55,7 @@ impl<'tcx> InferCtxt<'tcx> {
         cause: &'a ObligationCause<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
     ) -> At<'a, 'tcx> {
-        At { infcx: self, cause, param_env, define_opaque_types: true }
+        At { infcx: self, cause, param_env, define_opaque_types: false }
     }
 
     /// Forks the inference context, creating a new inference context with the same inference
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index b736a416e4a..7ffd39de781 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -10,9 +10,9 @@ use crate::infer::canonical::{
 };
 use crate::infer::InferCtxt;
 use rustc_middle::ty::flags::FlagComputation;
-use rustc_middle::ty::fold::{ir::TypeFolder, TypeFoldable, TypeSuperFoldable};
+use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::subst::GenericArg;
-use rustc_middle::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags};
+use rustc_middle::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags, TypeVisitableExt};
 use std::sync::atomic::Ordering;
 
 use rustc_data_structures::fx::FxHashMap;
@@ -41,7 +41,7 @@ impl<'tcx> InferCtxt<'tcx> {
         query_state: &mut OriginalQueryValues<'tcx>,
     ) -> Canonical<'tcx, V>
     where
-        V: TypeFoldable<'tcx>,
+        V: TypeFoldable<TyCtxt<'tcx>>,
     {
         self.tcx.sess.perf_stats.queries_canonicalized.fetch_add(1, Ordering::Relaxed);
 
@@ -60,7 +60,7 @@ impl<'tcx> InferCtxt<'tcx> {
         query_state: &mut OriginalQueryValues<'tcx>,
     ) -> Canonical<'tcx, V>
     where
-        V: TypeFoldable<'tcx>,
+        V: TypeFoldable<TyCtxt<'tcx>>,
     {
         self.tcx.sess.perf_stats.queries_canonicalized.fetch_add(1, Ordering::Relaxed);
 
@@ -100,7 +100,7 @@ impl<'tcx> InferCtxt<'tcx> {
     /// [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html#canonicalizing-the-query-result
     pub fn canonicalize_response<V>(&self, value: V) -> Canonical<'tcx, V>
     where
-        V: TypeFoldable<'tcx>,
+        V: TypeFoldable<TyCtxt<'tcx>>,
     {
         let mut query_state = OriginalQueryValues::default();
         Canonicalizer::canonicalize(
@@ -114,7 +114,7 @@ impl<'tcx> InferCtxt<'tcx> {
 
     pub fn canonicalize_user_type_annotation<V>(&self, value: V) -> Canonical<'tcx, V>
     where
-        V: TypeFoldable<'tcx>,
+        V: TypeFoldable<TyCtxt<'tcx>>,
     {
         let mut query_state = OriginalQueryValues::default();
         Canonicalizer::canonicalize(
@@ -136,7 +136,7 @@ impl<'tcx> InferCtxt<'tcx> {
         query_state: &mut OriginalQueryValues<'tcx>,
     ) -> Canonical<'tcx, V>
     where
-        V: TypeFoldable<'tcx>,
+        V: TypeFoldable<TyCtxt<'tcx>>,
     {
         self.tcx.sess.perf_stats.queries_canonicalized.fetch_add(1, Ordering::Relaxed);
 
@@ -333,7 +333,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
 
     fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         self.binder_index.shift_in(1);
         let t = t.super_fold_with(self);
@@ -530,7 +530,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
         query_state: &mut OriginalQueryValues<'tcx>,
     ) -> Canonical<'tcx, V>
     where
-        V: TypeFoldable<'tcx>,
+        V: TypeFoldable<TyCtxt<'tcx>>,
     {
         let needs_canonical_flags = if canonicalize_region_mode.any() {
             TypeFlags::NEEDS_INFER |
@@ -572,7 +572,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
         debug_assert!(!out_value.needs_infer() && !out_value.has_placeholders());
 
         let canonical_variables =
-            tcx.intern_canonical_var_infos(&canonicalizer.universe_canonicalized_variables());
+            tcx.mk_canonical_var_infos(&canonicalizer.universe_canonicalized_variables());
 
         let max_universe = canonical_variables
             .iter()
diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs
index 4552256545b..8c782a933a5 100644
--- a/compiler/rustc_infer/src/infer/canonical/mod.rs
+++ b/compiler/rustc_infer/src/infer/canonical/mod.rs
@@ -26,7 +26,7 @@ use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVari
 use rustc_index::vec::IndexVec;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::subst::GenericArg;
-use rustc_middle::ty::{self, List};
+use rustc_middle::ty::{self, List, TyCtxt};
 use rustc_span::source_map::Span;
 
 pub use rustc_middle::infer::canonical::*;
@@ -55,7 +55,7 @@ impl<'tcx> InferCtxt<'tcx> {
         canonical: &Canonical<'tcx, T>,
     ) -> (T, CanonicalVarValues<'tcx>)
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         // For each universe that is referred to in the incoming
         // query, create a universe in our local inference context. In
@@ -88,7 +88,7 @@ impl<'tcx> InferCtxt<'tcx> {
         universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
     ) -> CanonicalVarValues<'tcx> {
         CanonicalVarValues {
-            var_values: self.tcx.mk_substs(
+            var_values: self.tcx.mk_substs_from_iter(
                 variables
                     .iter()
                     .map(|info| self.instantiate_canonical_var(span, info, &universe_map)),
diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index b9cb9732ca3..832af91a431 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -27,7 +27,7 @@ use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::relate::TypeRelation;
 use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
 use rustc_middle::ty::{self, BoundVar, ToPredicate, Ty, TyCtxt};
-use rustc_span::Span;
+use rustc_span::{Span, Symbol};
 use std::fmt::Debug;
 use std::iter;
 
@@ -59,7 +59,7 @@ impl<'tcx> InferCtxt<'tcx> {
         fulfill_cx: &mut dyn TraitEngine<'tcx>,
     ) -> Fallible<CanonicalQueryResponse<'tcx, T>>
     where
-        T: Debug + TypeFoldable<'tcx>,
+        T: Debug + TypeFoldable<TyCtxt<'tcx>>,
         Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>,
     {
         let query_response = self.make_query_response(inference_vars, answer, fulfill_cx)?;
@@ -85,7 +85,7 @@ impl<'tcx> InferCtxt<'tcx> {
         answer: T,
     ) -> Canonical<'tcx, QueryResponse<'tcx, T>>
     where
-        T: Debug + TypeFoldable<'tcx>,
+        T: Debug + TypeFoldable<TyCtxt<'tcx>>,
     {
         self.canonicalize_response(QueryResponse {
             var_values: inference_vars,
@@ -106,7 +106,7 @@ impl<'tcx> InferCtxt<'tcx> {
         fulfill_cx: &mut dyn TraitEngine<'tcx>,
     ) -> Result<QueryResponse<'tcx, T>, NoSolution>
     where
-        T: Debug + TypeFoldable<'tcx>,
+        T: Debug + TypeFoldable<TyCtxt<'tcx>>,
     {
         let tcx = self.tcx;
 
@@ -180,7 +180,7 @@ impl<'tcx> InferCtxt<'tcx> {
         query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
     ) -> InferResult<'tcx, R>
     where
-        R: Debug + TypeFoldable<'tcx>,
+        R: Debug + TypeFoldable<TyCtxt<'tcx>>,
     {
         let InferOk { value: result_subst, mut obligations } =
             self.query_response_substitution(cause, param_env, original_values, query_response)?;
@@ -242,7 +242,7 @@ impl<'tcx> InferCtxt<'tcx> {
         output_query_region_constraints: &mut QueryRegionConstraints<'tcx>,
     ) -> InferResult<'tcx, R>
     where
-        R: Debug + TypeFoldable<'tcx>,
+        R: Debug + TypeFoldable<TyCtxt<'tcx>>,
     {
         let InferOk { value: result_subst, mut obligations } = self
             .query_response_substitution_guess(cause, param_env, original_values, query_response)?;
@@ -356,7 +356,7 @@ impl<'tcx> InferCtxt<'tcx> {
         query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
     ) -> InferResult<'tcx, CanonicalVarValues<'tcx>>
     where
-        R: Debug + TypeFoldable<'tcx>,
+        R: Debug + TypeFoldable<TyCtxt<'tcx>>,
     {
         debug!(
             "query_response_substitution(original_values={:#?}, query_response={:#?})",
@@ -393,6 +393,7 @@ impl<'tcx> InferCtxt<'tcx> {
     /// will instantiate fresh inference variables for each canonical
     /// variable instead. Therefore, the result of this method must be
     /// properly unified
+    #[instrument(level = "debug", skip(self, cause, param_env))]
     fn query_response_substitution_guess<R>(
         &self,
         cause: &ObligationCause<'tcx>,
@@ -401,13 +402,8 @@ impl<'tcx> InferCtxt<'tcx> {
         query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
     ) -> InferResult<'tcx, CanonicalVarValues<'tcx>>
     where
-        R: Debug + TypeFoldable<'tcx>,
+        R: Debug + TypeFoldable<TyCtxt<'tcx>>,
     {
-        debug!(
-            "query_response_substitution_guess(original_values={:#?}, query_response={:#?})",
-            original_values, query_response,
-        );
-
         // For each new universe created in the query result that did
         // not appear in the original query, create a local
         // superuniverse.
@@ -478,8 +474,8 @@ impl<'tcx> InferCtxt<'tcx> {
         // given variable in the loop above, use that. Otherwise, use
         // a fresh inference variable.
         let result_subst = CanonicalVarValues {
-            var_values: self.tcx.mk_substs(query_response.variables.iter().enumerate().map(
-                |(index, info)| {
+            var_values: self.tcx.mk_substs_from_iter(
+                query_response.variables.iter().enumerate().map(|(index, info)| {
                     if info.is_existential() {
                         match opt_values[BoundVar::new(index)] {
                             Some(k) => k,
@@ -492,8 +488,8 @@ impl<'tcx> InferCtxt<'tcx> {
                             universe_map[u.as_usize()]
                         })
                     }
-                },
-            )),
+                }),
+            ),
         };
 
         let mut obligations = vec![];
@@ -502,7 +498,9 @@ impl<'tcx> InferCtxt<'tcx> {
         for &(a, b) in &query_response.value.opaque_types {
             let a = substitute_value(self.tcx, &result_subst, a);
             let b = substitute_value(self.tcx, &result_subst, b);
-            obligations.extend(self.at(cause, param_env).eq(a, b)?.obligations);
+            debug!(?a, ?b, "constrain opaque type");
+            obligations
+                .extend(self.at(cause, param_env).define_opaque_types(true).eq(a, b)?.obligations);
         }
 
         Ok(InferOk { value: result_subst, obligations })
@@ -523,7 +521,7 @@ impl<'tcx> InferCtxt<'tcx> {
         query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
     ) -> InferResult<'tcx, ()>
     where
-        R: Debug + TypeFoldable<'tcx>,
+        R: Debug + TypeFoldable<TyCtxt<'tcx>>,
     {
         // A closure that yields the result value for the given
         // canonical variable; this is taken from
@@ -683,7 +681,11 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
         self.infcx.create_next_universe()
     }
 
-    fn next_existential_region_var(&mut self, from_forall: bool) -> ty::Region<'tcx> {
+    fn next_existential_region_var(
+        &mut self,
+        from_forall: bool,
+        _name: Option<Symbol>,
+    ) -> ty::Region<'tcx> {
         let origin = NllRegionVariableOrigin::Existential { from_forall };
         self.infcx.next_nll_region_var(origin)
     }
diff --git a/compiler/rustc_infer/src/infer/canonical/substitute.rs b/compiler/rustc_infer/src/infer/canonical/substitute.rs
index e77f2d37b7d..c5c6fc41b9e 100644
--- a/compiler/rustc_infer/src/infer/canonical/substitute.rs
+++ b/compiler/rustc_infer/src/infer/canonical/substitute.rs
@@ -16,7 +16,7 @@ pub(super) trait CanonicalExt<'tcx, V> {
     /// with the value given in `var_values`.
     fn substitute(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V
     where
-        V: TypeFoldable<'tcx>;
+        V: TypeFoldable<TyCtxt<'tcx>>;
 
     /// Allows one to apply a substitute to some subset of
     /// `self.value`. Invoke `projection_fn` with `self.value` to get
@@ -31,13 +31,13 @@ pub(super) trait CanonicalExt<'tcx, V> {
         projection_fn: impl FnOnce(&V) -> T,
     ) -> T
     where
-        T: TypeFoldable<'tcx>;
+        T: TypeFoldable<TyCtxt<'tcx>>;
 }
 
 impl<'tcx, V> CanonicalExt<'tcx, V> for Canonical<'tcx, V> {
     fn substitute(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V
     where
-        V: TypeFoldable<'tcx>,
+        V: TypeFoldable<TyCtxt<'tcx>>,
     {
         self.substitute_projected(tcx, var_values, |value| value.clone())
     }
@@ -49,7 +49,7 @@ impl<'tcx, V> CanonicalExt<'tcx, V> for Canonical<'tcx, V> {
         projection_fn: impl FnOnce(&V) -> T,
     ) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         assert_eq!(self.variables.len(), var_values.len());
         let value = projection_fn(&self.value);
@@ -66,7 +66,7 @@ pub(super) fn substitute_value<'tcx, T>(
     value: T,
 ) -> T
 where
-    T: TypeFoldable<'tcx>,
+    T: TypeFoldable<TyCtxt<'tcx>>,
 {
     if var_values.var_values.is_empty() {
         value
diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs
index f5504b05dc4..33292e871b1 100644
--- a/compiler/rustc_infer/src/infer/combine.rs
+++ b/compiler/rustc_infer/src/infer/combine.rs
@@ -40,8 +40,8 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::{
-    self, ir::FallibleTypeFolder, AliasKind, InferConst, ToPredicate, Ty, TyCtxt, TypeFoldable,
-    TypeSuperFoldable,
+    self, AliasKind, FallibleTypeFolder, InferConst, ToPredicate, Ty, TyCtxt, TypeFoldable,
+    TypeSuperFoldable, TypeVisitableExt,
 };
 use rustc_middle::ty::{IntType, UintType};
 use rustc_span::{Span, DUMMY_SP};
@@ -478,10 +478,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
         self.obligations.extend(obligations.into_iter());
     }
 
-    pub fn register_predicates(
-        &mut self,
-        obligations: impl IntoIterator<Item = impl ToPredicate<'tcx>>,
-    ) {
+    pub fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ToPredicate<'tcx>>) {
         self.obligations.extend(obligations.into_iter().map(|to_pred| {
             Obligation::new(self.infcx.tcx, self.trace.cause.clone(), self.param_env, to_pred)
         }))
@@ -814,10 +811,7 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> {
     /// Register predicates that must hold in order for this relation to hold. Uses
     /// a default obligation cause, [`ObligationEmittingRelation::register_obligations`] should
     /// be used if control over the obligaton causes is required.
-    fn register_predicates(
-        &mut self,
-        obligations: impl IntoIterator<Item = impl ToPredicate<'tcx>>,
-    );
+    fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ToPredicate<'tcx>>);
 
     /// Register an obligation that both constants must be equal to each other.
     ///
diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs
index 742c01efff6..54a62326ef7 100644
--- a/compiler/rustc_infer/src/infer/equate.rs
+++ b/compiler/rustc_infer/src/infer/equate.rs
@@ -6,7 +6,7 @@ use super::Subtype;
 use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::TyVar;
-use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 
 use rustc_hir::def_id::DefId;
 
@@ -201,10 +201,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
 }
 
 impl<'tcx> ObligationEmittingRelation<'tcx> for Equate<'_, '_, 'tcx> {
-    fn register_predicates(
-        &mut self,
-        obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>,
-    ) {
+    fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>) {
         self.fields.register_predicates(obligations);
     }
 
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index bb7947e3141..79efc1ce7bf 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -72,7 +72,7 @@ use rustc_middle::ty::print::with_forced_trimmed_paths;
 use rustc_middle::ty::relate::{self, RelateResult, TypeRelation};
 use rustc_middle::ty::{
     self, error::TypeError, List, Region, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
-    TypeVisitable,
+    TypeVisitable, TypeVisitableExt,
 };
 use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span};
 use rustc_target::spec::abi;
@@ -129,21 +129,16 @@ pub(super) fn note_and_explain_region<'tcx>(
     alt_span: Option<Span>,
 ) {
     let (description, span) = match *region {
-        ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic => {
-            msg_span_from_free_region(tcx, region, alt_span)
+        ty::ReEarlyBound(_) | ty::ReFree(_) | ty::RePlaceholder(_) | ty::ReStatic => {
+            msg_span_from_named_region(tcx, region, alt_span)
         }
 
-        ty::RePlaceholder(_) => return,
-
         ty::ReError(_) => return,
 
-        // FIXME(#13998) RePlaceholder should probably print like
-        // ReFree rather than dumping Debug output on the user.
-        //
         // We shouldn't really be having unification failures with ReVar
         // and ReLateBound though.
         ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => {
-            (format!("lifetime {:?}", region), alt_span)
+            (format!("lifetime `{region}`"), alt_span)
         }
     };
 
@@ -157,12 +152,12 @@ fn explain_free_region<'tcx>(
     region: ty::Region<'tcx>,
     suffix: &str,
 ) {
-    let (description, span) = msg_span_from_free_region(tcx, region, None);
+    let (description, span) = msg_span_from_named_region(tcx, region, None);
 
     label_msg_span(err, prefix, description, span, suffix);
 }
 
-fn msg_span_from_free_region<'tcx>(
+fn msg_span_from_named_region<'tcx>(
     tcx: TyCtxt<'tcx>,
     region: ty::Region<'tcx>,
     alt_span: Option<Span>,
@@ -173,6 +168,18 @@ fn msg_span_from_free_region<'tcx>(
             (msg, Some(span))
         }
         ty::ReStatic => ("the static lifetime".to_owned(), alt_span),
+        ty::RePlaceholder(ty::PlaceholderRegion {
+            name: ty::BoundRegionKind::BrNamed(def_id, name),
+            ..
+        }) => (format!("the lifetime `{name}` as defined here"), Some(tcx.def_span(def_id))),
+        ty::RePlaceholder(ty::PlaceholderRegion {
+            name: ty::BoundRegionKind::BrAnon(_, Some(span)),
+            ..
+        }) => (format!("the anonymous lifetime defined here"), Some(span)),
+        ty::RePlaceholder(ty::PlaceholderRegion {
+            name: ty::BoundRegionKind::BrAnon(_, None),
+            ..
+        }) => (format!("an anonymous lifetime"), None),
         _ => bug!("{:?}", region),
     }
 }
@@ -918,7 +925,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
     ) -> Option<()> {
         // FIXME/HACK: Go back to `SubstsRef` to use its inherent methods,
         // ideally that shouldn't be necessary.
-        let sub = self.tcx.intern_substs(sub);
+        let sub = self.tcx.mk_substs(sub);
         for (i, ta) in sub.types().enumerate() {
             if ta == other_ty {
                 self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, other_ty);
@@ -1443,8 +1450,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         impl<'tcx> OpaqueTypesVisitor<'tcx> {
             fn visit_expected_found(
                 tcx: TyCtxt<'tcx>,
-                expected: impl TypeVisitable<'tcx>,
-                found: impl TypeVisitable<'tcx>,
+                expected: impl TypeVisitable<TyCtxt<'tcx>>,
+                found: impl TypeVisitable<TyCtxt<'tcx>>,
                 ignore_span: Span,
             ) -> Self {
                 let mut types_visitor = OpaqueTypesVisitor {
@@ -1494,7 +1501,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             }
         }
 
-        impl<'tcx> ty::visit::ir::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypesVisitor<'tcx> {
+        impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypesVisitor<'tcx> {
             fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
                 if let Some((kind, def_id)) = TyCategory::from_ty(self.tcx, t) {
                     let span = self.tcx.def_span(def_id);
@@ -2199,7 +2206,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
     }
 
     /// Returns a string of the form "expected `{}`, found `{}`".
-    fn expected_found_str<T: fmt::Display + TypeFoldable<'tcx>>(
+    fn expected_found_str<T: fmt::Display + TypeFoldable<TyCtxt<'tcx>>>(
         &self,
         exp_found: ty::error::ExpectedFound<T>,
     ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)>
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index cf2f6ef33be..e242900fd23 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -122,7 +122,7 @@ impl InferenceDiagnosticsParentData {
             tcx.def_key(parent_def_id).disambiguated_data.data.get_opt_name()?.to_string();
 
         Some(InferenceDiagnosticsParentData {
-            prefix: tcx.def_kind(parent_def_id).descr(parent_def_id),
+            prefix: tcx.def_descr(parent_def_id),
             name: parent_name,
         })
     }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
index 641477e907d..b06ff10d86e 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -17,8 +17,7 @@ use rustc_hir::{
     TyKind,
 };
 use rustc_middle::ty::{
-    self, ir::TypeVisitor, AssocItemContainer, StaticLifetimeVisitor, Ty, TyCtxt,
-    TypeSuperVisitable,
+    self, AssocItemContainer, StaticLifetimeVisitor, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor,
 };
 use rustc_span::symbol::Ident;
 use rustc_span::Span;
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
index d295881d5d7..2875448ee15 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
@@ -75,7 +75,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
             }
         }
 
-        impl<'tcx> ty::visit::ir::TypeVisitor<TyCtxt<'tcx>> for HighlightBuilder<'tcx> {
+        impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for HighlightBuilder<'tcx> {
             fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
                 if !r.has_name() && self.counter <= 3 {
                     self.highlight.highlighting_region(r, self.counter);
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
index ac4de2cc842..db4b8af4683 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
@@ -143,7 +143,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
 
     fn includes_region(
         &self,
-        ty: Binder<'tcx, impl TypeVisitable<'tcx>>,
+        ty: Binder<'tcx, impl TypeVisitable<TyCtxt<'tcx>>>,
         region: ty::BoundRegionKind,
     ) -> bool {
         let late_bound_regions = self.tcx().collect_referenced_late_bound_regions(&ty);
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs
index e0e89158a58..7ffe1fd20b4 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs
@@ -2,10 +2,11 @@ use crate::errors::{
     note_and_explain, FullfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent,
     RefLongerThanData, RegionOriginNote, WhereClauseSuggestions,
 };
+use crate::fluent_generated as fluent;
 use crate::infer::error_reporting::{note_and_explain_region, TypeErrCtxt};
 use crate::infer::{self, SubregionOrigin};
 use rustc_errors::{
-    fluent, AddToDiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic,
+    AddToDiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic,
 };
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::traits::ObligationCauseCode;
diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
index 18c5097a262..55dcfd05e0a 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
@@ -8,7 +8,7 @@ use rustc_middle::traits::{
     StatementAsExpression,
 };
 use rustc_middle::ty::print::with_no_trimmed_paths;
-use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TypeVisitable};
+use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TypeVisitableExt};
 use rustc_span::{sym, BytePos, Span};
 
 use crate::errors::{
diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs
index 41bffdc684d..f09f93abf45 100644
--- a/compiler/rustc_infer/src/infer/freshen.rs
+++ b/compiler/rustc_infer/src/infer/freshen.rs
@@ -33,8 +33,8 @@
 use super::InferCtxt;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_middle::infer::unify_key::ToType;
-use rustc_middle::ty::fold::ir::TypeFolder;
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable};
+use rustc_middle::ty::fold::TypeFolder;
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitableExt};
 use std::collections::hash_map::Entry;
 
 pub struct TypeFreshener<'a, 'tcx> {
diff --git a/compiler/rustc_infer/src/infer/fudge.rs b/compiler/rustc_infer/src/infer/fudge.rs
index cc2f19a5704..86c2c2be4a8 100644
--- a/compiler/rustc_infer/src/infer/fudge.rs
+++ b/compiler/rustc_infer/src/infer/fudge.rs
@@ -1,4 +1,4 @@
-use rustc_middle::ty::fold::{ir::TypeFolder, TypeFoldable, TypeSuperFoldable};
+use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::{self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid};
 
 use super::type_variable::TypeVariableOrigin;
@@ -98,7 +98,7 @@ impl<'tcx> InferCtxt<'tcx> {
     pub fn fudge_inference_if_ok<T, E, F>(&self, f: F) -> Result<T, E>
     where
         F: FnOnce() -> Result<T, E>,
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         let variable_lengths = self.variable_lengths();
         let (mut fudger, value) = self.probe(|_| {
diff --git a/compiler/rustc_infer/src/infer/glb.rs b/compiler/rustc_infer/src/infer/glb.rs
index 74abca7bbea..49df393d83b 100644
--- a/compiler/rustc_infer/src/infer/glb.rs
+++ b/compiler/rustc_infer/src/infer/glb.rs
@@ -7,7 +7,7 @@ use super::Subtype;
 
 use crate::traits::{ObligationCause, PredicateObligations};
 use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
-use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 
 /// "Greatest lower bound" (common subtype)
 pub struct Glb<'combine, 'infcx, 'tcx> {
@@ -148,10 +148,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx,
 }
 
 impl<'tcx> ObligationEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> {
-    fn register_predicates(
-        &mut self,
-        obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>,
-    ) {
+    fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>) {
         self.fields.register_predicates(obligations);
     }
 
diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs
index 82a1bb1fd16..d1897cf24b4 100644
--- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs
+++ b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs
@@ -6,7 +6,7 @@ use super::{HigherRankedType, InferCtxt};
 use crate::infer::CombinedSnapshot;
 use rustc_middle::ty::fold::FnMutDelegate;
 use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
-use rustc_middle::ty::{self, Binder, TypeFoldable};
+use rustc_middle::ty::{self, Binder, TyCtxt, TypeFoldable};
 
 impl<'a, 'tcx> CombineFields<'a, 'tcx> {
     /// Checks whether `for<..> sub <: for<..> sup` holds.
@@ -72,7 +72,7 @@ impl<'tcx> InferCtxt<'tcx> {
     #[instrument(level = "debug", skip(self), ret)]
     pub fn instantiate_binder_with_placeholders<T>(&self, binder: ty::Binder<'tcx, T>) -> T
     where
-        T: TypeFoldable<'tcx> + Copy,
+        T: TypeFoldable<TyCtxt<'tcx>> + Copy,
     {
         if let Some(inner) = binder.no_bound_vars() {
             return inner;
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 ac203c4eb0b..335eb4c5406 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -1024,7 +1024,7 @@ impl<'tcx> fmt::Debug for RegionAndOrigin<'tcx> {
 impl<'tcx> LexicalRegionResolutions<'tcx> {
     fn normalize<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         tcx.fold_regions(value, |r, _db| self.resolve_region(tcx, r))
     }
@@ -1046,7 +1046,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> {
             ty::ReVar(rid) => match self.values[rid] {
                 VarValue::Empty(_) => r,
                 VarValue::Value(r) => r,
-                VarValue::ErrorValue => tcx.mk_re_error_misc(),
+                VarValue::ErrorValue => tcx.lifetimes.re_static,
             },
             _ => r,
         };
diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/lub.rs
index f997171b97f..c871ccb21f8 100644
--- a/compiler/rustc_infer/src/infer/lub.rs
+++ b/compiler/rustc_infer/src/infer/lub.rs
@@ -7,7 +7,7 @@ use super::Subtype;
 
 use crate::traits::{ObligationCause, PredicateObligations};
 use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
-use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 
 /// "Least upper bound" (common supertype)
 pub struct Lub<'combine, 'infcx, 'tcx> {
@@ -148,10 +148,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx,
 }
 
 impl<'tcx> ObligationEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> {
-    fn register_predicates(
-        &mut self,
-        obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>,
-    ) {
+    fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>) {
         self.fields.register_predicates(obligations);
     }
 
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index aa316b2dadb..cf8007c964d 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -26,10 +26,10 @@ use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::traits::select;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::fold::BoundVarReplacerDelegate;
-use rustc_middle::ty::fold::{ir::TypeFolder, TypeFoldable, TypeSuperFoldable};
+use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::relate::RelateResult;
 use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef};
-use rustc_middle::ty::visit::TypeVisitable;
+use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
 pub use rustc_middle::ty::IntVarValue;
 use rustc_middle::ty::{self, GenericParamDefKind, InferConst, InferTy, Ty, TyCtxt};
 use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid};
@@ -264,7 +264,7 @@ pub struct InferCtxt<'tcx> {
     /// short lived InferCtxt within queries. The opaque type obligations are forwarded
     /// to the outside until the end up in an `InferCtxt` for typeck or borrowck.
     ///
-    /// It is default value is `DefiningAnchor::Error`, this way it is easier to catch errors that
+    /// Its default value is `DefiningAnchor::Error`, this way it is easier to catch errors that
     /// might come up during inference or typeck.
     pub defining_use_anchor: DefiningAnchor,
 
@@ -617,7 +617,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
         canonical: &Canonical<'tcx, T>,
     ) -> (InferCtxt<'tcx>, T, CanonicalVarValues<'tcx>)
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         let infcx = self.build();
         let (value, subst) = infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical);
@@ -697,7 +697,7 @@ impl<'tcx> InferCtxt<'tcx> {
         self.in_snapshot.get()
     }
 
-    pub fn freshen<T: TypeFoldable<'tcx>>(&self, t: T) -> T {
+    pub fn freshen<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T {
         t.fold_with(&mut self.freshener())
     }
 
@@ -1111,11 +1111,13 @@ impl<'tcx> InferCtxt<'tcx> {
     }
 
     /// Just a convenient wrapper of `next_region_var` for using during NLL.
+    #[instrument(skip(self), level = "debug")]
     pub fn next_nll_region_var(&self, origin: NllRegionVariableOrigin) -> ty::Region<'tcx> {
         self.next_region_var(RegionVariableOrigin::Nll(origin))
     }
 
     /// Just a convenient wrapper of `next_region_var` for using during NLL.
+    #[instrument(skip(self), level = "debug")]
     pub fn next_nll_region_var_in_universe(
         &self,
         origin: NllRegionVariableOrigin,
@@ -1369,7 +1371,7 @@ impl<'tcx> InferCtxt<'tcx> {
     /// will be resolving them as well, e.g. in a loop).
     pub fn shallow_resolve<T>(&self, value: T) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         value.fold_with(&mut ShallowResolver { infcx: self })
     }
@@ -1386,7 +1388,7 @@ impl<'tcx> InferCtxt<'tcx> {
     /// at will.
     pub fn resolve_vars_if_possible<T>(&self, value: T) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         if !value.has_non_region_infer() {
             return value;
@@ -1397,7 +1399,7 @@ impl<'tcx> InferCtxt<'tcx> {
 
     pub fn resolve_numeric_literals_with_default<T>(&self, value: T) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         if !value.needs_infer() {
             return value; // Avoid duplicated subst-folding.
@@ -1412,7 +1414,7 @@ impl<'tcx> InferCtxt<'tcx> {
         value: &T,
     ) -> Option<(ty::Term<'tcx>, Option<Span>)>
     where
-        T: TypeVisitable<'tcx>,
+        T: TypeVisitable<TyCtxt<'tcx>>,
     {
         value.visit_with(&mut resolve::UnresolvedTypeOrConstFinder::new(self)).break_value()
     }
@@ -1427,7 +1429,7 @@ impl<'tcx> InferCtxt<'tcx> {
         }
     }
 
-    pub fn fully_resolve<T: TypeFoldable<'tcx>>(&self, value: T) -> FixupResult<'tcx, T> {
+    pub fn fully_resolve<T: TypeFoldable<TyCtxt<'tcx>>>(&self, value: T) -> FixupResult<'tcx, T> {
         /*!
          * Attempts to resolve all type/region/const variables in
          * `value`. Region inference must have been run already (e.g.,
@@ -1460,7 +1462,7 @@ impl<'tcx> InferCtxt<'tcx> {
         value: ty::Binder<'tcx, T>,
     ) -> T
     where
-        T: TypeFoldable<'tcx> + Copy,
+        T: TypeFoldable<TyCtxt<'tcx>> + Copy,
     {
         if let Some(inner) = value.no_bound_vars() {
             return inner;
diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
index 644774c93c2..6e413a7f412 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
@@ -29,9 +29,9 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
-use rustc_middle::ty::visit::{ir::TypeVisitor, TypeSuperVisitable, TypeVisitable};
+use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
 use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
-use rustc_span::Span;
+use rustc_span::{Span, Symbol};
 use std::fmt::Debug;
 use std::ops::ControlFlow;
 
@@ -100,7 +100,11 @@ pub trait TypeRelatingDelegate<'tcx> {
     /// we will invoke this method to instantiate `'a` with an
     /// inference variable (though `'b` would be instantiated first,
     /// as a placeholder).
-    fn next_existential_region_var(&mut self, was_placeholder: bool) -> ty::Region<'tcx>;
+    fn next_existential_region_var(
+        &mut self,
+        was_placeholder: bool,
+        name: Option<Symbol>,
+    ) -> ty::Region<'tcx>;
 
     /// Creates a new region variable representing a
     /// higher-ranked region that is instantiated universally.
@@ -188,7 +192,7 @@ where
                     let placeholder = ty::PlaceholderRegion { universe, name: br.kind };
                     delegate.next_placeholder_region(placeholder)
                 } else {
-                    delegate.next_existential_region_var(true)
+                    delegate.next_existential_region_var(true, br.kind.get_name())
                 }
             }
         };
@@ -759,10 +763,7 @@ impl<'tcx, D> ObligationEmittingRelation<'tcx> for TypeRelating<'_, 'tcx, D>
 where
     D: TypeRelatingDelegate<'tcx>,
 {
-    fn register_predicates(
-        &mut self,
-        obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>,
-    ) {
+    fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>) {
         self.delegate.register_obligations(
             obligations
                 .into_iter()
@@ -793,7 +794,7 @@ struct ScopeInstantiator<'me, 'tcx> {
 }
 
 impl<'me, 'tcx> TypeVisitor<TyCtxt<'tcx>> for ScopeInstantiator<'me, 'tcx> {
-    fn visit_binder<T: TypeVisitable<'tcx>>(
+    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
         &mut self,
         t: &ty::Binder<'tcx, T>,
     ) -> ControlFlow<Self::BreakTy> {
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index e783443502b..d5c824d4c41 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -12,8 +12,8 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::GenericArgKind;
 use rustc_middle::ty::{
-    self, ir::TypeVisitor, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable,
-    TypeSuperVisitable, TypeVisitable,
+    self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
+    TypeVisitable, TypeVisitableExt, TypeVisitor,
 };
 use rustc_span::Span;
 
@@ -45,7 +45,7 @@ pub struct OpaqueTypeDecl<'tcx> {
 impl<'tcx> InferCtxt<'tcx> {
     /// This is a backwards compatibility hack to prevent breaking changes from
     /// lazy TAIT around RPIT handling.
-    pub fn replace_opaque_types_with_inference_vars<T: TypeFoldable<'tcx>>(
+    pub fn replace_opaque_types_with_inference_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
         &self,
         value: T,
         body_id: LocalDefId,
@@ -427,7 +427,7 @@ impl<'tcx, OP> TypeVisitor<TyCtxt<'tcx>> for ConstrainOpaqueTypeRegionVisitor<'t
 where
     OP: FnMut(ty::Region<'tcx>),
 {
-    fn visit_binder<T: TypeVisitable<'tcx>>(
+    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
         &mut self,
         t: &ty::Binder<'tcx, T>,
     ) -> ControlFlow<Self::BreakTy> {
@@ -545,8 +545,11 @@ impl<'tcx> InferCtxt<'tcx> {
             origin,
         );
         if let Some(prev) = prev {
-            obligations =
-                self.at(&cause, param_env).eq_exp(a_is_expected, prev, hidden_ty)?.obligations;
+            obligations = self
+                .at(&cause, param_env)
+                .define_opaque_types(true)
+                .eq_exp(a_is_expected, prev, hidden_ty)?
+                .obligations;
         }
 
         let item_bounds = tcx.bound_explicit_item_bounds(def_id.to_def_id());
diff --git a/compiler/rustc_infer/src/infer/outlives/components.rs b/compiler/rustc_infer/src/infer/outlives/components.rs
index e3d95669171..ff23087fe8d 100644
--- a/compiler/rustc_infer/src/infer/outlives/components.rs
+++ b/compiler/rustc_infer/src/infer/outlives/components.rs
@@ -4,7 +4,7 @@
 
 use rustc_data_structures::sso::SsoHashSet;
 use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 use smallvec::{smallvec, SmallVec};
 
 #[derive(Debug)]
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index 0194549a886..bbe7d4c63f7 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -69,7 +69,7 @@ use crate::traits::{ObligationCause, ObligationCauseCode};
 use rustc_data_structures::undo_log::UndoLogs;
 use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::ty::subst::GenericArgKind;
-use rustc_middle::ty::{self, Region, SubstsRef, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, Region, SubstsRef, Ty, TyCtxt, TypeVisitableExt};
 use smallvec::smallvec;
 
 impl<'tcx> InferCtxt<'tcx> {
diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
index 10b474efd5a..3c6cc2b9001 100644
--- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
+++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
@@ -1,7 +1,7 @@
 use std::collections::hash_map::Entry;
 
 use rustc_data_structures::fx::FxHashMap;
-use rustc_middle::ty::TypeVisitable;
+use rustc_middle::ty::TypeVisitableExt;
 use rustc_middle::ty::{
     self,
     error::TypeError,
@@ -186,7 +186,8 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
 
     #[instrument(skip(self), level = "debug")]
     fn tys(&mut self, pattern: Ty<'tcx>, value: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
-        if let ty::Error(_) = pattern.kind() {
+        // FIXME(non_lifetime_binders): What to do here?
+        if matches!(pattern.kind(), ty::Error(_) | ty::Bound(..)) {
             // Unlike normal `TypeRelation` rules, `ty::Error` does not equal any type.
             self.no_match()
         } else if pattern == value {
diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs
index 2c246a5787c..5bb35832930 100644
--- a/compiler/rustc_infer/src/infer/resolve.rs
+++ b/compiler/rustc_infer/src/infer/resolve.rs
@@ -1,11 +1,8 @@
 use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use super::{FixupError, FixupResult, InferCtxt, Span};
 use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
-use rustc_middle::ty::fold::{
-    ir::{FallibleTypeFolder, TypeFolder},
-    TypeSuperFoldable,
-};
-use rustc_middle::ty::visit::{ir::TypeVisitor, TypeSuperVisitable};
+use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable};
+use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitableExt, TypeVisitor};
 use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable};
 
 use std::ops::ControlFlow;
@@ -200,7 +197,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for UnresolvedTypeOrConstFinder<'a, 'tc
 /// then an `Err` result is returned.
 pub fn fully_resolve<'tcx, T>(infcx: &InferCtxt<'tcx>, value: T) -> FixupResult<'tcx, T>
 where
-    T: TypeFoldable<'tcx>,
+    T: TypeFoldable<TyCtxt<'tcx>>,
 {
     value.try_fold_with(&mut FullTypeResolver { infcx })
 }
diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs
index bf1b3441547..3e8c2052de8 100644
--- a/compiler/rustc_infer/src/infer/sub.rs
+++ b/compiler/rustc_infer/src/infer/sub.rs
@@ -3,7 +3,7 @@ use super::{ObligationEmittingRelation, SubregionOrigin};
 
 use crate::traits::{Obligation, PredicateObligations};
 use rustc_middle::ty::relate::{Cause, Relate, RelateResult, TypeRelation};
-use rustc_middle::ty::visit::TypeVisitable;
+use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::TyVar;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use std::mem;
@@ -126,7 +126,7 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
 
             (&ty::Error(e), _) | (_, &ty::Error(e)) => {
                 infcx.set_tainted_by_errors(e);
-                Ok(self.tcx().ty_error_with_guaranteed(e))
+                Ok(self.tcx().ty_error(e))
             }
 
             (
@@ -228,10 +228,7 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
 }
 
 impl<'tcx> ObligationEmittingRelation<'tcx> for Sub<'_, '_, 'tcx> {
-    fn register_predicates(
-        &mut self,
-        obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>,
-    ) {
+    fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>) {
         self.fields.register_predicates(obligations);
     }
 
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index 4c119a44355..bdc313c2141 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -13,6 +13,7 @@
 //! This API is completely unstable and subject to change.
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
+#![feature(associated_type_bounds)]
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
 #![feature(extend_one)]
@@ -33,6 +34,11 @@ extern crate tracing;
 #[macro_use]
 extern crate rustc_middle;
 
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_macros::fluent_messages;
+
 mod errors;
 pub mod infer;
 pub mod traits;
+
+fluent_messages! { "../locales/en-US.ftl" }
diff --git a/compiler/rustc_infer/src/traits/structural_impls.rs b/compiler/rustc_infer/src/traits/structural_impls.rs
index 95df6cd62b9..3a5273b0359 100644
--- a/compiler/rustc_infer/src/traits/structural_impls.rs
+++ b/compiler/rustc_infer/src/traits/structural_impls.rs
@@ -2,7 +2,7 @@ use crate::traits;
 use crate::traits::project::Normalized;
 use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable};
 use rustc_middle::ty::visit::{TypeVisitable, TypeVisitor};
-use rustc_middle::ty::{self, ir, TyCtxt};
+use rustc_middle::ty::{self, TyCtxt};
 
 use std::fmt;
 use std::ops::ControlFlow;
@@ -61,8 +61,13 @@ impl<'tcx> fmt::Debug for traits::MismatchedProjectionTypes<'tcx> {
 ///////////////////////////////////////////////////////////////////////////
 // TypeFoldable implementations.
 
-impl<'tcx, O: TypeFoldable<'tcx>> ir::TypeFoldable<TyCtxt<'tcx>> for traits::Obligation<'tcx, O> {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
+impl<'tcx, O: TypeFoldable<TyCtxt<'tcx>>> TypeFoldable<TyCtxt<'tcx>>
+    for traits::Obligation<'tcx, O>
+{
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        folder: &mut F,
+    ) -> Result<Self, F::Error> {
         Ok(traits::Obligation {
             cause: self.cause,
             recursion_depth: self.recursion_depth,
@@ -72,8 +77,10 @@ impl<'tcx, O: TypeFoldable<'tcx>> ir::TypeFoldable<TyCtxt<'tcx>> for traits::Obl
     }
 }
 
-impl<'tcx, O: TypeVisitable<'tcx>> ir::TypeVisitable<TyCtxt<'tcx>> for traits::Obligation<'tcx, O> {
-    fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+impl<'tcx, O: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>>
+    for traits::Obligation<'tcx, O>
+{
+    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
         self.predicate.visit_with(visitor)?;
         self.param_env.visit_with(visitor)
     }
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index c1f0a6e9834..c07ff516579 100644
--- a/compiler/rustc_infer/src/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
@@ -116,11 +116,11 @@ pub fn elaborate_predicates_with_span<'tcx>(
 
 pub fn elaborate_obligations<'tcx>(
     tcx: TyCtxt<'tcx>,
-    mut obligations: Vec<PredicateObligation<'tcx>>,
+    obligations: Vec<PredicateObligation<'tcx>>,
 ) -> Elaborator<'tcx> {
-    let mut visited = PredicateSet::new(tcx);
-    obligations.retain(|obligation| visited.insert(obligation.predicate));
-    Elaborator { stack: obligations, visited }
+    let mut elaborator = Elaborator { stack: Vec::new(), visited: PredicateSet::new(tcx) };
+    elaborator.extend_deduped(obligations);
+    elaborator
 }
 
 fn predicate_obligation<'tcx>(
@@ -132,6 +132,15 @@ fn predicate_obligation<'tcx>(
 }
 
 impl<'tcx> Elaborator<'tcx> {
+    fn extend_deduped(&mut self, obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>) {
+        // Only keep those bounds that we haven't already seen.
+        // This is necessary to prevent infinite recursion in some
+        // cases. One common case is when people define
+        // `trait Sized: Sized { }` rather than `trait Sized { }`.
+        // let visited = &mut self.visited;
+        self.stack.extend(obligations.into_iter().filter(|o| self.visited.insert(o.predicate)));
+    }
+
     pub fn filter_to_traits(self) -> FilterToTraits<Self> {
         FilterToTraits::new(self)
     }
@@ -172,15 +181,7 @@ impl<'tcx> Elaborator<'tcx> {
                         )
                     });
                 debug!(?data, ?obligations, "super_predicates");
-
-                // Only keep those bounds that we haven't already seen.
-                // This is necessary to prevent infinite recursion in some
-                // cases. One common case is when people define
-                // `trait Sized: Sized { }` rather than `trait Sized { }`.
-                let visited = &mut self.visited;
-                let obligations = obligations.filter(|o| visited.insert(o.predicate));
-
-                self.stack.extend(obligations);
+                self.extend_deduped(obligations);
             }
             ty::PredicateKind::WellFormed(..) => {
                 // Currently, we do not elaborate WF predicates,
@@ -237,10 +238,9 @@ impl<'tcx> Elaborator<'tcx> {
                     return;
                 }
 
-                let visited = &mut self.visited;
                 let mut components = smallvec![];
                 push_outlives_components(tcx, ty_max, &mut components);
-                self.stack.extend(
+                self.extend_deduped(
                     components
                         .into_iter()
                         .filter_map(|component| match component {
@@ -280,7 +280,6 @@ impl<'tcx> Elaborator<'tcx> {
                         .map(|predicate_kind| {
                             bound_predicate.rebind(predicate_kind).to_predicate(tcx)
                         })
-                        .filter(|&predicate| visited.insert(predicate))
                         .map(|predicate| {
                             predicate_obligation(
                                 predicate,
diff --git a/compiler/rustc_error_messages/locales/en-US/interface.ftl b/compiler/rustc_interface/locales/en-US.ftl
index a7bc0e7af1f..da58492ccf2 100644
--- a/compiler/rustc_error_messages/locales/en-US/interface.ftl
+++ b/compiler/rustc_interface/locales/en-US.ftl
@@ -11,10 +11,6 @@ interface_mixed_bin_crate =
 interface_mixed_proc_macro_crate =
     cannot mix `proc-macro` crate type with others
 
-interface_proc_macro_doc_without_arg =
-    Trying to document proc macro crate without passing '--crate-type proc-macro to rustdoc
-    .warn = The generated documentation may be incorrect
-
 interface_error_writing_dependencies =
     error writing dependencies to `{$path}`: {$error}
 
diff --git a/compiler/rustc_interface/src/errors.rs b/compiler/rustc_interface/src/errors.rs
index 29543fe2f93..0eedee25026 100644
--- a/compiler/rustc_interface/src/errors.rs
+++ b/compiler/rustc_interface/src/errors.rs
@@ -32,10 +32,6 @@ pub struct MixedBinCrate;
 pub struct MixedProcMacroCrate;
 
 #[derive(Diagnostic)]
-#[diag(interface_proc_macro_doc_without_arg)]
-pub struct ProcMacroDocWithoutArg;
-
-#[derive(Diagnostic)]
 #[diag(interface_error_writing_dependencies)]
 pub struct ErrorWritingDependencies<'a> {
     pub path: &'a Path,
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index d504aea77d0..5e38ca034ac 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -222,6 +222,7 @@ pub struct Config {
     pub output_dir: Option<PathBuf>,
     pub output_file: Option<PathBuf>,
     pub file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
+    pub locale_resources: &'static [&'static str],
 
     pub lint_caps: FxHashMap<lint::LintId, lint::Level>,
 
@@ -267,6 +268,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
                 config.opts,
                 config.crate_cfg,
                 config.crate_check_cfg,
+                config.locale_resources,
                 config.file_loader,
                 CompilerIO {
                     input: config.input,
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index 82bc4770b6b..1abbe8d4fab 100644
--- a/compiler/rustc_interface/src/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -12,6 +12,9 @@
 #[macro_use]
 extern crate tracing;
 
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_macros::fluent_messages;
+
 mod callbacks;
 mod errors;
 pub mod interface;
@@ -27,3 +30,5 @@ pub use queries::Queries;
 
 #[cfg(test)]
 mod tests;
+
+fluent_messages! { "../locales/en-US.ftl" }
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index aa59654099a..81c1d665ef0 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -287,28 +287,18 @@ fn configure_and_expand(mut krate: ast::Crate, resolver: &mut Resolver<'_, '_>)
         sess.emit_warning(errors::ProcMacroCratePanicAbort);
     }
 
-    // For backwards compatibility, we don't try to run proc macro injection
-    // if rustdoc is run on a proc macro crate without '--crate-type proc-macro' being
-    // specified. This should only affect users who manually invoke 'rustdoc', as
-    // 'cargo doc' will automatically pass the proper '--crate-type' flags.
-    // However, we do emit a warning, to let such users know that they should
-    // start passing '--crate-type proc-macro'
-    if has_proc_macro_decls && sess.opts.actually_rustdoc && !is_proc_macro_crate {
-        sess.emit_warning(errors::ProcMacroDocWithoutArg);
-    } else {
-        krate = sess.time("maybe_create_a_macro_crate", || {
-            let is_test_crate = sess.opts.test;
-            rustc_builtin_macros::proc_macro_harness::inject(
-                sess,
-                resolver,
-                krate,
-                is_proc_macro_crate,
-                has_proc_macro_decls,
-                is_test_crate,
-                sess.diagnostic(),
-            )
-        });
-    }
+    krate = sess.time("maybe_create_a_macro_crate", || {
+        let is_test_crate = sess.opts.test;
+        rustc_builtin_macros::proc_macro_harness::inject(
+            sess,
+            resolver,
+            krate,
+            is_proc_macro_crate,
+            has_proc_macro_decls,
+            is_test_crate,
+            sess.diagnostic(),
+        )
+    });
 
     // Done with macro expansion!
 
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index c957578b59e..a96cc95a384 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -7,11 +7,10 @@ use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_codegen_ssa::CodegenResults;
 use rustc_data_structures::steal::Steal;
 use rustc_data_structures::svh::Svh;
-use rustc_data_structures::sync::{Lrc, OnceCell, RwLock, WorkerLocal};
+use rustc_data_structures::sync::{AppendOnlyVec, Lrc, OnceCell, RwLock, WorkerLocal};
 use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::definitions::Definitions;
 use rustc_incremental::DepGraphFuture;
-use rustc_index::vec::IndexVec;
 use rustc_lint::LintStore;
 use rustc_metadata::creader::CStore;
 use rustc_middle::arena::Arena;
@@ -195,10 +194,9 @@ impl<'tcx> Queries<'tcx> {
 
             let cstore = RwLock::new(Box::new(CStore::new(sess)) as _);
             let definitions = RwLock::new(Definitions::new(sess.local_stable_crate_id()));
-            let mut source_span = IndexVec::default();
+            let source_span = AppendOnlyVec::new();
             let _id = source_span.push(krate.spans.inner_span);
             debug_assert_eq!(_id, CRATE_DEF_ID);
-            let source_span = RwLock::new(source_span);
             let untracked = Untracked { cstore, source_span, definitions };
 
             let qcx = passes::create_global_ctxt(
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index ac32988d3ac..18d84a7023a 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -50,7 +50,7 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
         output_file: None,
         temps_dir,
     };
-    let sess = build_session(sessopts, io, None, registry, Default::default(), None, None);
+    let sess = build_session(sessopts, io, None, registry, vec![], Default::default(), None, None);
     (sess, cfg)
 }
 
@@ -756,6 +756,7 @@ fn test_unstable_options_tracking_hash() {
     tracked!(instrument_coverage, Some(InstrumentCoverage::All));
     tracked!(instrument_mcount, true);
     tracked!(instrument_xray, Some(InstrumentXRay::default()));
+    tracked!(link_directives, false);
     tracked!(link_only, true);
     tracked!(llvm_plugins, vec![String::from("plugin_name")]);
     tracked!(location_detail, LocationDetail { file: true, line: false, column: false });
@@ -776,7 +777,6 @@ fn test_unstable_options_tracking_hash() {
     tracked!(packed_bundled_libs, true);
     tracked!(panic_abort_tests, true);
     tracked!(panic_in_drop, PanicStrategy::Abort);
-    tracked!(pick_stable_methods_before_any_unstable, false);
     tracked!(plt, Some(true));
     tracked!(polonius, true);
     tracked!(precise_enum_drop_elaboration, false);
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 475d3601b52..e5d2fb2ea28 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -59,6 +59,7 @@ pub fn create_session(
     sopts: config::Options,
     cfg: FxHashSet<(String, Option<String>)>,
     check_cfg: CheckCfg,
+    locale_resources: &'static [&'static str],
     file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
     io: CompilerIO,
     lint_caps: FxHashMap<lint::LintId, lint::Level>,
@@ -89,11 +90,15 @@ pub fn create_session(
         }
     };
 
+    let mut locale_resources = Vec::from(locale_resources);
+    locale_resources.push(codegen_backend.locale_resource());
+
     let mut sess = session::build_session(
         sopts,
         io,
         bundle,
         descriptions,
+        locale_resources,
         lint_caps,
         file_loader,
         target_override,
diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_lint/locales/en-US.ftl
index b1e7cc69a80..68e62c9789a 100644
--- a/compiler/rustc_error_messages/locales/en-US/lint.ftl
+++ b/compiler/rustc_lint/locales/en-US.ftl
@@ -24,6 +24,13 @@ lint_for_loops_over_fallibles =
     .use_while_let = to check pattern in a loop use `while let`
     .use_question_mark = consider unwrapping the `Result` with `?` to iterate over its contents
 
+lint_map_unit_fn = `Iterator::map` call that discard the iterator's values
+    .note = `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated
+    .function_label = this function returns `()`, which is likely not what you wanted
+    .argument_label = called `Iterator::map` with callable that returns `()`
+    .map_label = after this call to map, the resulting iterator is `impl Iterator<Item = ()>`, which means the only information carried by the iterator is the number of items
+    .suggestion = you might have meant to use `Iterator::for_each`
+
 lint_non_binding_let_on_sync_lock =
     non-binding let on a synchronization lock
 
diff --git a/compiler/rustc_lint/src/array_into_iter.rs b/compiler/rustc_lint/src/array_into_iter.rs
index 3593f141df6..bccb0a94e98 100644
--- a/compiler/rustc_lint/src/array_into_iter.rs
+++ b/compiler/rustc_lint/src/array_into_iter.rs
@@ -1,5 +1,7 @@
-use crate::lints::{ArrayIntoIterDiag, ArrayIntoIterDiagSub};
-use crate::{LateContext, LateLintPass, LintContext};
+use crate::{
+    lints::{ArrayIntoIterDiag, ArrayIntoIterDiagSub},
+    LateContext, LateLintPass, LintContext,
+};
 use rustc_hir as hir;
 use rustc_middle::ty;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment};
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 11fb1f80a11..59540aaf18f 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -20,6 +20,7 @@
 //! If you define a new `LateLintPass`, you will also need to add it to the
 //! `late_lint_methods!` invocation in `lib.rs`.
 
+use crate::fluent_generated as fluent;
 use crate::{
     errors::BuiltinEllpisisInclusiveRangePatterns,
     lints::{
@@ -50,7 +51,7 @@ use rustc_ast::{self as ast, *};
 use rustc_ast_pretty::pprust::{self, expr_to_string};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::stack::ensure_sufficient_stack;
-use rustc_errors::{fluent, Applicability, DecorateLint, MultiSpan};
+use rustc_errors::{Applicability, DecorateLint, MultiSpan};
 use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, GateIssue, Stability};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -676,21 +677,21 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
                     return;
                 }
                 let def = cx.tcx.adt_def(item.owner_id);
-                (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
+                (def, cx.tcx.mk_adt(def, ty::List::empty()))
             }
             hir::ItemKind::Union(_, ref ast_generics) => {
                 if !ast_generics.params.is_empty() {
                     return;
                 }
                 let def = cx.tcx.adt_def(item.owner_id);
-                (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
+                (def, cx.tcx.mk_adt(def, ty::List::empty()))
             }
             hir::ItemKind::Enum(_, ref ast_generics) => {
                 if !ast_generics.params.is_empty() {
                     return;
                 }
                 let def = cx.tcx.adt_def(item.owner_id);
-                (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
+                (def, cx.tcx.mk_adt(def, ty::List::empty()))
             }
             _ => return,
         };
@@ -1583,7 +1584,7 @@ declare_lint_pass!(
 
 impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
-        use rustc_middle::ty::visit::TypeVisitable;
+        use rustc_middle::ty::visit::TypeVisitableExt;
         use rustc_middle::ty::Clause;
         use rustc_middle::ty::PredicateKind::*;
 
@@ -2635,7 +2636,13 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
                 cx.emit_spanned_lint(
                     INVALID_VALUE,
                     expr.span,
-                    BuiltinUnpermittedTypeInit { msg, ty: conjured_ty, label: expr.span, sub },
+                    BuiltinUnpermittedTypeInit {
+                        msg,
+                        ty: conjured_ty,
+                        label: expr.span,
+                        sub,
+                        tcx: cx.tcx,
+                    },
                 );
             }
         }
diff --git a/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs
index 73bd4173270..f1ba192f2bc 100644
--- a/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs
+++ b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs
@@ -4,7 +4,7 @@ use crate::{
     LateContext, LateLintPass,
 };
 use rustc_hir as hir;
-use rustc_middle::ty::{visit::TypeVisitable, Ty};
+use rustc_middle::ty::{visit::TypeVisitableExt, Ty};
 use rustc_span::{symbol::sym, Span};
 
 declare_lint! {
diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs
index f3ae2609186..9af5284df1e 100644
--- a/compiler/rustc_lint/src/errors.rs
+++ b/compiler/rustc_lint/src/errors.rs
@@ -1,6 +1,6 @@
+use crate::fluent_generated as fluent;
 use rustc_errors::{
-    fluent, AddToDiagnostic, Diagnostic, ErrorGuaranteed, Handler, IntoDiagnostic,
-    SubdiagnosticMessage,
+    AddToDiagnostic, Diagnostic, ErrorGuaranteed, Handler, IntoDiagnostic, SubdiagnosticMessage,
 };
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_session::lint::Level;
@@ -116,7 +116,7 @@ impl IntoDiagnostic<'_> for CheckNameUnknown {
         let mut diag = handler.struct_err(fluent::lint_check_name_unknown);
         diag.code(rustc_errors::error_code!(E0602));
         if let Some(suggestion) = self.suggestion {
-            diag.help(fluent::help);
+            diag.help(fluent::lint_help);
             diag.set_arg("suggestion", suggestion);
         }
         diag.set_arg("lint_name", self.lint_name);
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index cca36913dea..bc7488fab4a 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -1,13 +1,16 @@
-use crate::context::{CheckLintNameResult, LintStore};
-use crate::late::unerased_lint_store;
-use crate::lints::{
-    DeprecatedLintName, IgnoredUnlessCrateSpecified, OverruledAtributeLint, RenamedOrRemovedLint,
-    RenamedOrRemovedLintSuggestion, UnknownLint, UnknownLintSuggestion,
+use crate::{
+    context::{CheckLintNameResult, LintStore},
+    fluent_generated as fluent,
+    late::unerased_lint_store,
+    lints::{
+        DeprecatedLintName, IgnoredUnlessCrateSpecified, OverruledAtributeLint,
+        RenamedOrRemovedLint, RenamedOrRemovedLintSuggestion, UnknownLint, UnknownLintSuggestion,
+    },
 };
 use rustc_ast as ast;
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{fluent, DecorateLint, DiagnosticBuilder, DiagnosticMessage, MultiSpan};
+use rustc_errors::{DecorateLint, DiagnosticBuilder, DiagnosticMessage, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::HirId;
@@ -983,7 +986,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                     fluent::lint_unknown_gated_lint,
                     |lint| {
                         lint.set_arg("name", lint_id.lint.name_lower());
-                        lint.note(fluent::note);
+                        lint.note(fluent::lint_note);
                         add_feature_diagnostics(lint, &self.sess.parse_sess, feature);
                         lint
                     },
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 4ca37ef6850..35dc533e56c 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -63,6 +63,7 @@ mod late;
 mod let_underscore;
 mod levels;
 mod lints;
+mod map_unit_fn;
 mod methods;
 mod multiple_supertrait_upcastable;
 mod non_ascii_idents;
@@ -80,8 +81,10 @@ mod unused;
 pub use array_into_iter::ARRAY_INTO_ITER;
 
 use rustc_ast as ast;
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
+use rustc_macros::fluent_messages;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::lint::builtin::{
@@ -98,6 +101,7 @@ use for_loops_over_fallibles::*;
 use hidden_unicode_codepoints::*;
 use internal::*;
 use let_underscore::*;
+use map_unit_fn::*;
 use methods::*;
 use multiple_supertrait_upcastable::*;
 use non_ascii_idents::*;
@@ -122,6 +126,8 @@ pub use rustc_session::lint::Level::{self, *};
 pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Lint, LintId};
 pub use rustc_session::lint::{LintArray, LintPass};
 
+fluent_messages! { "../locales/en-US.ftl" }
+
 pub fn provide(providers: &mut Providers) {
     levels::provide(providers);
     expect::provide(providers);
@@ -235,6 +241,7 @@ late_lint_methods!(
             NamedAsmLabels: NamedAsmLabels,
             OpaqueHiddenInferredBound: OpaqueHiddenInferredBound,
             MultipleSupertraitUpcastable: MultipleSupertraitUpcastable,
+            MapUnitFn: MapUnitFn,
         ]
     ]
 );
@@ -294,7 +301,8 @@ fn register_builtins(store: &mut LintStore) {
         UNUSED_LABELS,
         UNUSED_PARENS,
         UNUSED_BRACES,
-        REDUNDANT_SEMICOLONS
+        REDUNDANT_SEMICOLONS,
+        MAP_UNIT_FN
     );
 
     add_lint_group!("let_underscore", LET_UNDERSCORE_DROP, LET_UNDERSCORE_LOCK);
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 94a43ab0c46..20ab0af5856 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -2,13 +2,16 @@
 #![allow(rustc::diagnostic_outside_of_impl)]
 use std::num::NonZeroU32;
 
+use crate::fluent_generated as fluent;
 use rustc_errors::{
-    fluent, AddToDiagnostic, Applicability, DecorateLint, DiagnosticMessage,
-    DiagnosticStyledString, SuggestionStyle,
+    AddToDiagnostic, Applicability, DecorateLint, DiagnosticMessage, DiagnosticStyledString,
+    SuggestionStyle,
 };
 use rustc_hir::def_id::DefId;
 use rustc_macros::{LintDiagnostic, Subdiagnostic};
-use rustc_middle::ty::{PolyExistentialTraitRef, Predicate, Ty, TyCtxt};
+use rustc_middle::ty::{
+    inhabitedness::InhabitedPredicate, PolyExistentialTraitRef, Predicate, Ty, TyCtxt,
+};
 use rustc_session::parse::ParseSess;
 use rustc_span::{edition::Edition, sym, symbol::Ident, Span, Symbol};
 
@@ -21,7 +24,7 @@ use crate::{
 #[diag(lint_array_into_iter)]
 pub struct ArrayIntoIterDiag<'a> {
     pub target: &'a str,
-    #[suggestion(use_iter_suggestion, code = "iter", applicability = "machine-applicable")]
+    #[suggestion(lint_use_iter_suggestion, code = "iter", applicability = "machine-applicable")]
     pub suggestion: Span,
     #[subdiagnostic]
     pub sub: Option<ArrayIntoIterDiagSub>,
@@ -29,12 +32,15 @@ pub struct ArrayIntoIterDiag<'a> {
 
 #[derive(Subdiagnostic)]
 pub enum ArrayIntoIterDiagSub {
-    #[suggestion(remove_into_iter_suggestion, code = "", applicability = "maybe-incorrect")]
+    #[suggestion(lint_remove_into_iter_suggestion, code = "", applicability = "maybe-incorrect")]
     RemoveIntoIter {
         #[primary_span]
         span: Span,
     },
-    #[multipart_suggestion(use_explicit_into_iter_suggestion, applicability = "maybe-incorrect")]
+    #[multipart_suggestion(
+        lint_use_explicit_into_iter_suggestion,
+        applicability = "maybe-incorrect"
+    )]
     UseExplicitIntoIter {
         #[suggestion_part(code = "IntoIterator::into_iter(")]
         start_span: Span,
@@ -161,13 +167,13 @@ pub struct BuiltinDeprecatedAttrLink<'a> {
 
 #[derive(Subdiagnostic)]
 pub enum BuiltinDeprecatedAttrLinkSuggestion<'a> {
-    #[suggestion(msg_suggestion, code = "", applicability = "machine-applicable")]
+    #[suggestion(lint_msg_suggestion, code = "", applicability = "machine-applicable")]
     Msg {
         #[primary_span]
         suggestion: Span,
         msg: &'a str,
     },
-    #[suggestion(default_suggestion, code = "", applicability = "machine-applicable")]
+    #[suggestion(lint_default_suggestion, code = "", applicability = "machine-applicable")]
     Default {
         #[primary_span]
         suggestion: Span,
@@ -199,9 +205,9 @@ pub struct BuiltinUnusedDocComment<'a> {
 
 #[derive(Subdiagnostic)]
 pub enum BuiltinUnusedDocCommentSub {
-    #[help(plain_help)]
+    #[help(lint_plain_help)]
     PlainHelp,
-    #[help(block_help)]
+    #[help(lint_block_help)]
     BlockHelp,
 }
 
@@ -240,7 +246,7 @@ impl<'a> DecorateLint<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
         self,
         diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
-        diag.span_label(self.label, fluent::label);
+        diag.span_label(self.label, fluent::lint_label);
         rustc_session::parse::add_feature_diagnostics(
             diag,
             &self.parse_sess,
@@ -335,7 +341,7 @@ impl AddToDiagnostic for BuiltinTypeAliasGenericBoundsSuggestion {
         ) -> rustc_errors::SubdiagnosticMessage,
     {
         diag.multipart_suggestion(
-            fluent::suggestion,
+            fluent::lint_suggestion,
             self.suggestions,
             Applicability::MachineApplicable,
         );
@@ -386,7 +392,7 @@ pub struct BuiltinExplicitOutlives {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(suggestion)]
+#[multipart_suggestion(lint_suggestion)]
 pub struct BuiltinExplicitOutlivesSuggestion {
     #[suggestion_part(code = "")]
     pub spans: Vec<Span>,
@@ -405,11 +411,11 @@ pub struct BuiltinIncompleteFeatures {
 }
 
 #[derive(Subdiagnostic)]
-#[help(help)]
+#[help(lint_help)]
 pub struct BuiltinIncompleteFeaturesHelp;
 
 #[derive(Subdiagnostic)]
-#[note(note)]
+#[note(lint_note)]
 pub struct BuiltinIncompleteFeaturesNote {
     pub n: NonZeroU32,
 }
@@ -419,6 +425,7 @@ pub struct BuiltinUnpermittedTypeInit<'a> {
     pub ty: Ty<'a>,
     pub label: Span,
     pub sub: BuiltinUnpermittedTypeInitSub,
+    pub tcx: TyCtxt<'a>,
 }
 
 impl<'a> DecorateLint<'a, ()> for BuiltinUnpermittedTypeInit<'_> {
@@ -428,7 +435,13 @@ impl<'a> DecorateLint<'a, ()> for BuiltinUnpermittedTypeInit<'_> {
     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
         diag.set_arg("ty", self.ty);
         diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label);
-        diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label_suggestion);
+        if let InhabitedPredicate::True = self.ty.inhabited_predicate(self.tcx) {
+            // Only suggest late `MaybeUninit::assume_init` initialization if the type is inhabited.
+            diag.span_label(
+                self.label,
+                fluent::lint_builtin_unpermitted_type_init_label_suggestion,
+            );
+        }
         self.sub.add_to_diagnostic(diag);
         diag
     }
@@ -473,9 +486,9 @@ pub enum BuiltinClashingExtern<'a> {
     SameName {
         this: Symbol,
         orig: Symbol,
-        #[label(previous_decl_label)]
+        #[label(lint_previous_decl_label)]
         previous_decl_label: Span,
-        #[label(mismatch_label)]
+        #[label(lint_mismatch_label)]
         mismatch_label: Span,
         #[subdiagnostic]
         sub: BuiltinClashingExternSub<'a>,
@@ -484,9 +497,9 @@ pub enum BuiltinClashingExtern<'a> {
     DiffName {
         this: Symbol,
         orig: Symbol,
-        #[label(previous_decl_label)]
+        #[label(lint_previous_decl_label)]
         previous_decl_label: Span,
-        #[label(mismatch_label)]
+        #[label(lint_mismatch_label)]
         mismatch_label: Span,
         #[subdiagnostic]
         sub: BuiltinClashingExternSub<'a>,
@@ -562,7 +575,7 @@ pub struct SupertraitAsDerefTarget<'a> {
 }
 
 #[derive(Subdiagnostic)]
-#[label(label)]
+#[label(lint_label)]
 pub struct SupertraitAsDerefTargetLabel {
     #[primary_span]
     pub label: Span,
@@ -595,7 +608,7 @@ pub struct Expectation {
 }
 
 #[derive(Subdiagnostic)]
-#[note(rationale)]
+#[note(lint_rationale)]
 pub struct ExpectationNote {
     pub rationale: Symbol,
 }
@@ -616,13 +629,13 @@ pub struct ForLoopsOverFalliblesDiag<'a> {
 
 #[derive(Subdiagnostic)]
 pub enum ForLoopsOverFalliblesLoopSub<'a> {
-    #[suggestion(remove_next, code = ".by_ref()", applicability = "maybe-incorrect")]
+    #[suggestion(lint_remove_next, code = ".by_ref()", applicability = "maybe-incorrect")]
     RemoveNext {
         #[primary_span]
         suggestion: Span,
         recv_snip: String,
     },
-    #[multipart_suggestion(use_while_let, applicability = "maybe-incorrect")]
+    #[multipart_suggestion(lint_use_while_let, applicability = "maybe-incorrect")]
     UseWhileLet {
         #[suggestion_part(code = "while let {var}(")]
         start_span: Span,
@@ -633,14 +646,14 @@ pub enum ForLoopsOverFalliblesLoopSub<'a> {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(use_question_mark, code = "?", applicability = "maybe-incorrect")]
+#[suggestion(lint_use_question_mark, code = "?", applicability = "maybe-incorrect")]
 pub struct ForLoopsOverFalliblesQuestionMark {
     #[primary_span]
     pub suggestion: Span,
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(suggestion, applicability = "maybe-incorrect")]
+#[multipart_suggestion(lint_suggestion, applicability = "maybe-incorrect")]
 pub struct ForLoopsOverFalliblesSuggestion<'a> {
     pub var: &'a str,
     #[suggestion_part(code = "if let {var}(")]
@@ -699,13 +712,13 @@ impl AddToDiagnostic for HiddenUnicodeCodepointsDiagSub {
         match self {
             HiddenUnicodeCodepointsDiagSub::Escape { spans } => {
                 diag.multipart_suggestion_with_style(
-                    fluent::suggestion_remove,
+                    fluent::lint_suggestion_remove,
                     spans.iter().map(|(_, span)| (*span, "".to_string())).collect(),
                     Applicability::MachineApplicable,
                     SuggestionStyle::HideCodeAlways,
                 );
                 diag.multipart_suggestion(
-                    fluent::suggestion_escape,
+                    fluent::lint_suggestion_escape,
                     spans
                         .into_iter()
                         .map(|(c, span)| {
@@ -728,13 +741,29 @@ impl AddToDiagnostic for HiddenUnicodeCodepointsDiagSub {
                         .collect::<Vec<String>>()
                         .join(", "),
                 );
-                diag.note(fluent::suggestion_remove);
-                diag.note(fluent::no_suggestion_note_escape);
+                diag.note(fluent::lint_suggestion_remove);
+                diag.note(fluent::lint_no_suggestion_note_escape);
             }
         }
     }
 }
 
+// map_unit_fn.rs
+#[derive(LintDiagnostic)]
+#[diag(lint_map_unit_fn)]
+#[note]
+pub struct MappingToUnit {
+    #[label(lint_function_label)]
+    pub function_label: Span,
+    #[label(lint_argument_label)]
+    pub argument_label: Span,
+    #[label(lint_map_label)]
+    pub map_label: Span,
+    #[suggestion(style = "verbose", code = "{replace}", applicability = "maybe-incorrect")]
+    pub suggestion: Span,
+    pub replace: String,
+}
+
 // internal.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_default_hash_types)]
@@ -874,7 +903,7 @@ pub struct RenamedOrRemovedLint<'a> {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(suggestion, code = "{replace}", applicability = "machine-applicable")]
+#[suggestion(lint_suggestion, code = "{replace}", applicability = "machine-applicable")]
 pub struct RenamedOrRemovedLintSuggestion<'a> {
     #[primary_span]
     pub suggestion: Span,
@@ -890,7 +919,7 @@ pub struct UnknownLint {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
+#[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")]
 pub struct UnknownLintSuggestion {
     #[primary_span]
     pub suggestion: Span,
@@ -910,9 +939,9 @@ pub struct IgnoredUnlessCrateSpecified<'a> {
 #[note]
 #[help]
 pub struct CStringPtr {
-    #[label(as_ptr_label)]
+    #[label(lint_as_ptr_label)]
     pub as_ptr: Span,
-    #[label(unwrap_label)]
+    #[label(lint_unwrap_label)]
     pub unwrap: Span,
 }
 
@@ -943,7 +972,7 @@ pub struct ConfusableIdentifierPair {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_mixed_script_confusables)]
-#[note(includes_note)]
+#[note(lint_includes_note)]
 #[note]
 pub struct MixedScriptConfusables {
     pub set: String,
@@ -963,17 +992,17 @@ impl<'a> DecorateLint<'a, ()> for NonFmtPanicUnused {
         diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
         diag.set_arg("count", self.count);
-        diag.note(fluent::note);
+        diag.note(fluent::lint_note);
         if let Some(span) = self.suggestion {
             diag.span_suggestion(
                 span.shrink_to_hi(),
-                fluent::add_args_suggestion,
+                fluent::lint_add_args_suggestion,
                 ", ...",
                 Applicability::HasPlaceholders,
             );
             diag.span_suggestion(
                 span.shrink_to_lo(),
-                fluent::add_fmt_suggestion,
+                fluent::lint_add_fmt_suggestion,
                 "\"{}\", ",
                 Applicability::MachineApplicable,
             );
@@ -1007,12 +1036,12 @@ pub struct NonCamelCaseType<'a> {
 
 #[derive(Subdiagnostic)]
 pub enum NonCamelCaseTypeSub {
-    #[label(label)]
+    #[label(lint_label)]
     Label {
         #[primary_span]
         span: Span,
     },
-    #[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
+    #[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")]
     Suggestion {
         #[primary_span]
         span: Span,
@@ -1048,15 +1077,15 @@ impl AddToDiagnostic for NonSnakeCaseDiagSub {
     {
         match self {
             NonSnakeCaseDiagSub::Label { span } => {
-                diag.span_label(span, fluent::label);
+                diag.span_label(span, fluent::lint_label);
             }
             NonSnakeCaseDiagSub::Help => {
-                diag.help(fluent::help);
+                diag.help(fluent::lint_help);
             }
             NonSnakeCaseDiagSub::ConvertSuggestion { span, suggestion } => {
                 diag.span_suggestion(
                     span,
-                    fluent::convert_suggestion,
+                    fluent::lint_convert_suggestion,
                     suggestion,
                     Applicability::MaybeIncorrect,
                 );
@@ -1064,16 +1093,16 @@ impl AddToDiagnostic for NonSnakeCaseDiagSub {
             NonSnakeCaseDiagSub::RenameOrConvertSuggestion { span, suggestion } => {
                 diag.span_suggestion(
                     span,
-                    fluent::rename_or_convert_suggestion,
+                    fluent::lint_rename_or_convert_suggestion,
                     suggestion,
                     Applicability::MaybeIncorrect,
                 );
             }
             NonSnakeCaseDiagSub::SuggestionAndNote { span } => {
-                diag.note(fluent::cannot_convert_note);
+                diag.note(fluent::lint_cannot_convert_note);
                 diag.span_suggestion(
                     span,
-                    fluent::rename_suggestion,
+                    fluent::lint_rename_suggestion,
                     "",
                     Applicability::MaybeIncorrect,
                 );
@@ -1093,12 +1122,12 @@ pub struct NonUpperCaseGlobal<'a> {
 
 #[derive(Subdiagnostic)]
 pub enum NonUpperCaseGlobalSub {
-    #[label(label)]
+    #[label(lint_label)]
     Label {
         #[primary_span]
         span: Span,
     },
-    #[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
+    #[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")]
     Suggestion {
         #[primary_span]
         span: Span,
@@ -1216,11 +1245,11 @@ impl AddToDiagnostic for OverflowingBinHexSign {
     {
         match self {
             OverflowingBinHexSign::Positive => {
-                diag.note(fluent::positive_note);
+                diag.note(fluent::lint_positive_note);
             }
             OverflowingBinHexSign::Negative => {
-                diag.note(fluent::negative_note);
-                diag.note(fluent::negative_becomes_note);
+                diag.note(fluent::lint_negative_note);
+                diag.note(fluent::lint_negative_becomes_note);
             }
         }
     }
@@ -1229,7 +1258,7 @@ impl AddToDiagnostic for OverflowingBinHexSign {
 #[derive(Subdiagnostic)]
 pub enum OverflowingBinHexSub<'a> {
     #[suggestion(
-        suggestion,
+        lint_suggestion,
         code = "{sans_suffix}{suggestion_ty}",
         applicability = "machine-applicable"
     )]
@@ -1239,7 +1268,7 @@ pub enum OverflowingBinHexSub<'a> {
         suggestion_ty: &'a str,
         sans_suffix: &'a str,
     },
-    #[help(help)]
+    #[help(lint_help)]
     Help { suggestion_ty: &'a str },
 }
 
@@ -1256,7 +1285,7 @@ pub struct OverflowingInt<'a> {
 }
 
 #[derive(Subdiagnostic)]
-#[help(help)]
+#[help(lint_help)]
 pub struct OverflowingIntHelp<'a> {
     pub suggestion_ty: &'a str,
 }
@@ -1308,13 +1337,13 @@ impl<'a> DecorateLint<'a, ()> for ImproperCTypes<'_> {
     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
         diag.set_arg("ty", self.ty);
         diag.set_arg("desc", self.desc);
-        diag.span_label(self.label, fluent::label);
+        diag.span_label(self.label, fluent::lint_label);
         if let Some(help) = self.help {
             diag.help(help);
         }
         diag.note(self.note);
         if let Some(note) = self.span_note {
-            diag.span_note(note, fluent::note);
+            diag.span_note(note, fluent::lint_note);
         }
         diag
     }
@@ -1407,7 +1436,7 @@ pub struct UnusedDef<'a, 'b> {
 #[derive(Subdiagnostic)]
 pub enum UnusedDefSuggestion {
     #[suggestion(
-        suggestion,
+        lint_suggestion,
         style = "verbose",
         code = "let _ = ",
         applicability = "machine-applicable"
@@ -1451,13 +1480,13 @@ pub struct PathStatementDrop {
 
 #[derive(Subdiagnostic)]
 pub enum PathStatementDropSub {
-    #[suggestion(suggestion, code = "drop({snippet});", applicability = "machine-applicable")]
+    #[suggestion(lint_suggestion, code = "drop({snippet});", applicability = "machine-applicable")]
     Suggestion {
         #[primary_span]
         span: Span,
         snippet: String,
     },
-    #[help(help)]
+    #[help(lint_help)]
     Help {
         #[primary_span]
         span: Span,
@@ -1478,7 +1507,7 @@ pub struct UnusedDelim<'a> {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
+#[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")]
 pub struct UnusedDelimSuggestion {
     #[suggestion_part(code = "{start_replace}")]
     pub start_span: Span,
diff --git a/compiler/rustc_lint/src/map_unit_fn.rs b/compiler/rustc_lint/src/map_unit_fn.rs
new file mode 100644
index 00000000000..62e8b4fe9e4
--- /dev/null
+++ b/compiler/rustc_lint/src/map_unit_fn.rs
@@ -0,0 +1,120 @@
+use crate::lints::MappingToUnit;
+use crate::{LateContext, LateLintPass, LintContext};
+
+use rustc_hir::{Expr, ExprKind, HirId, Stmt, StmtKind};
+use rustc_middle::{
+    query::Key,
+    ty::{self, Ty},
+};
+
+declare_lint! {
+    /// The `map_unit_fn` lint checks for `Iterator::map` receive
+    /// a callable that returns `()`.
+    ///
+    /// ### Example
+    ///
+    /// ```rust
+    /// fn foo(items: &mut Vec<u8>) {
+    ///     items.sort();
+    /// }
+    ///
+    /// fn main() {
+    ///     let mut x: Vec<Vec<u8>> = vec![
+    ///         vec![0, 2, 1],
+    ///         vec![5, 4, 3],
+    ///     ];
+    ///     x.iter_mut().map(foo);
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Mapping to `()` is almost always a mistake.
+    pub MAP_UNIT_FN,
+    Warn,
+    "`Iterator::map` call that discard the iterator's values"
+}
+
+declare_lint_pass!(MapUnitFn => [MAP_UNIT_FN]);
+
+impl<'tcx> LateLintPass<'tcx> for MapUnitFn {
+    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &Stmt<'_>) {
+        if stmt.span.from_expansion() {
+            return;
+        }
+
+        if let StmtKind::Semi(expr) = stmt.kind {
+            if let ExprKind::MethodCall(path, receiver, args, span) = expr.kind {
+                if path.ident.name.as_str() == "map" {
+                    if receiver.span.from_expansion()
+                        || args.iter().any(|e| e.span.from_expansion())
+                        || !is_impl_slice(cx, receiver)
+                        || !is_diagnostic_name(cx, expr.hir_id, "IteratorMap")
+                    {
+                        return;
+                    }
+                    let arg_ty = cx.typeck_results().expr_ty(&args[0]);
+                    if let ty::FnDef(id, _) = arg_ty.kind() {
+                        let fn_ty = cx.tcx.fn_sig(id).skip_binder();
+                        let ret_ty = fn_ty.output().skip_binder();
+                        if is_unit_type(ret_ty) {
+                            cx.emit_spanned_lint(
+                                MAP_UNIT_FN,
+                                span,
+                                MappingToUnit {
+                                    function_label: cx.tcx.span_of_impl(*id).unwrap(),
+                                    argument_label: args[0].span,
+                                    map_label: arg_ty.default_span(cx.tcx),
+                                    suggestion: path.ident.span,
+                                    replace: "for_each".to_string(),
+                                },
+                            )
+                        }
+                    } else if let ty::Closure(id, subs) = arg_ty.kind() {
+                        let cl_ty = subs.as_closure().sig();
+                        let ret_ty = cl_ty.output().skip_binder();
+                        if is_unit_type(ret_ty) {
+                            cx.emit_spanned_lint(
+                                MAP_UNIT_FN,
+                                span,
+                                MappingToUnit {
+                                    function_label: cx.tcx.span_of_impl(*id).unwrap(),
+                                    argument_label: args[0].span,
+                                    map_label: arg_ty.default_span(cx.tcx),
+                                    suggestion: path.ident.span,
+                                    replace: "for_each".to_string(),
+                                },
+                            )
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+fn is_impl_slice(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {
+        if let Some(impl_id) = cx.tcx.impl_of_method(method_id) {
+            return cx.tcx.type_of(impl_id).skip_binder().is_slice();
+        }
+    }
+    false
+}
+
+fn is_unit_type(ty: Ty<'_>) -> bool {
+    ty.is_unit() || ty.is_never()
+}
+
+fn is_diagnostic_name(cx: &LateContext<'_>, id: HirId, name: &str) -> bool {
+    if let Some(def_id) = cx.typeck_results().type_dependent_def_id(id) {
+        if let Some(item) = cx.tcx.get_diagnostic_name(def_id) {
+            if item.as_str() == name {
+                return true;
+            }
+        }
+    }
+    false
+}
diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs
index 548f30ec972..5bb1abfd2ec 100644
--- a/compiler/rustc_lint/src/non_fmt_panic.rs
+++ b/compiler/rustc_lint/src/non_fmt_panic.rs
@@ -1,7 +1,7 @@
 use crate::lints::{NonFmtPanicBraces, NonFmtPanicUnused};
-use crate::{LateContext, LateLintPass, LintContext};
+use crate::{fluent_generated as fluent, LateContext, LateLintPass, LintContext};
 use rustc_ast as ast;
-use rustc_errors::{fluent, Applicability};
+use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::lint::in_external_macro;
@@ -122,18 +122,18 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
     #[allow(rustc::diagnostic_outside_of_impl)]
     cx.struct_span_lint(NON_FMT_PANICS, arg_span, fluent::lint_non_fmt_panic, |lint| {
         lint.set_arg("name", symbol);
-        lint.note(fluent::note);
-        lint.note(fluent::more_info_note);
+        lint.note(fluent::lint_note);
+        lint.note(fluent::lint_more_info_note);
         if !is_arg_inside_call(arg_span, span) {
             // No clue where this argument is coming from.
             return lint;
         }
         if arg_macro.map_or(false, |id| cx.tcx.is_diagnostic_item(sym::format_macro, id)) {
             // A case of `panic!(format!(..))`.
-            lint.note(fluent::supports_fmt_note);
+            lint.note(fluent::lint_supports_fmt_note);
             if let Some((open, close, _)) = find_delimiters(cx, arg_span) {
                 lint.multipart_suggestion(
-                    fluent::supports_fmt_suggestion,
+                    fluent::lint_supports_fmt_suggestion,
                     vec![
                         (arg_span.until(open.shrink_to_hi()), "".into()),
                         (close.until(arg_span.shrink_to_hi()), "".into()),
@@ -179,7 +179,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
             if suggest_display {
                 lint.span_suggestion_verbose(
                     arg_span.shrink_to_lo(),
-                    fluent::display_suggestion,
+                    fluent::lint_display_suggestion,
                     "\"{}\", ",
                     fmt_applicability,
                 );
@@ -187,7 +187,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
                 lint.set_arg("ty", ty);
                 lint.span_suggestion_verbose(
                     arg_span.shrink_to_lo(),
-                    fluent::debug_suggestion,
+                    fluent::lint_debug_suggestion,
                     "\"{:?}\", ",
                     fmt_applicability,
                 );
@@ -197,7 +197,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
                 if let Some((open, close, del)) = find_delimiters(cx, span) {
                     lint.set_arg("already_suggested", suggest_display || suggest_debug);
                     lint.multipart_suggestion(
-                        fluent::panic_suggestion,
+                        fluent::lint_panic_suggestion,
                         if del == '(' {
                             vec![(span.until(open), "std::panic::panic_any".into())]
                         } else {
diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
index 42442cfb190..883a56cb3ce 100644
--- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
+++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
@@ -149,7 +149,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
 struct OpaqueHiddenInferredBoundLint<'tcx> {
     ty: Ty<'tcx>,
     proj_ty: Ty<'tcx>,
-    #[label(specifically)]
+    #[label(lint_specifically)]
     assoc_pred_span: Span,
     #[subdiagnostic]
     add_bound: Option<AddBound<'tcx>>,
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index b7fd6a254d8..85958c41705 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -1,19 +1,24 @@
-use crate::lints::{
-    AtomicOrderingFence, AtomicOrderingLoad, AtomicOrderingStore, ImproperCTypes,
-    InvalidAtomicOrderingDiag, OnlyCastu8ToChar, OverflowingBinHex, OverflowingBinHexSign,
-    OverflowingBinHexSub, OverflowingInt, OverflowingIntHelp, OverflowingLiteral, OverflowingUInt,
-    RangeEndpointOutOfRange, UnusedComparisons, VariantSizeDifferencesDiag,
+use crate::{
+    fluent_generated as fluent,
+    lints::{
+        AtomicOrderingFence, AtomicOrderingLoad, AtomicOrderingStore, ImproperCTypes,
+        InvalidAtomicOrderingDiag, OnlyCastu8ToChar, OverflowingBinHex, OverflowingBinHexSign,
+        OverflowingBinHexSub, OverflowingInt, OverflowingIntHelp, OverflowingLiteral,
+        OverflowingUInt, RangeEndpointOutOfRange, UnusedComparisons, VariantSizeDifferencesDiag,
+    },
 };
 use crate::{LateContext, LateLintPass, LintContext};
 use rustc_ast as ast;
 use rustc_attr as attr;
 use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::{fluent, DiagnosticMessage};
+use rustc_errors::DiagnosticMessage;
 use rustc_hir as hir;
 use rustc_hir::{is_range_literal, Expr, ExprKind, Node};
 use rustc_middle::ty::layout::{IntegerExt, LayoutOf, SizeSkeleton};
 use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::{self, AdtKind, DefIdTree, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable};
+use rustc_middle::ty::{
+    self, AdtKind, DefIdTree, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
+};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::source_map;
 use rustc_span::symbol::sym;
@@ -1144,7 +1149,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
 
     fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
         struct ProhibitOpaqueTypes;
-        impl<'tcx> ty::visit::ir::TypeVisitor<TyCtxt<'tcx>> for ProhibitOpaqueTypes {
+        impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for ProhibitOpaqueTypes {
             type BreakTy = Ty<'tcx>;
 
             fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 9d8ad9d9ed9..46ec1a2dca1 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -4103,3 +4103,33 @@ declare_lint! {
     };
     report_in_external_macro
 }
+
+declare_lint! {
+    /// The `invalid_macro_export_arguments` lint detects cases where `#[macro_export]` is being used with invalid arguments.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// #![deny(invalid_macro_export_arguments)]
+    ///
+    /// #[macro_export(invalid_parameter)]
+    /// macro_rules! myMacro {
+    ///    () => {
+    ///         // [...]
+    ///    }
+    /// }
+    ///
+    /// #[macro_export(too, many, items)]
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// The only valid argument is `#[macro_export(local_inner_macros)]` or no argument (`#[macro_export]`).
+    /// You can't have multiple arguments in a `#[macro_export(..)]`, or mention arguments other than `local_inner_macros`.
+    ///
+    pub INVALID_MACRO_EXPORT_ARGUMENTS,
+    Warn,
+    "\"invalid_parameter\" isn't a valid argument for `#[macro_export]`",
+}
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs
index 9ff94486404..12a954258d1 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs
@@ -57,7 +57,7 @@ impl<'a> DiagnosticDerive<'a> {
                 }
                 Some(slug) => {
                     quote! {
-                        let mut #diag = #handler.struct_diagnostic(rustc_errors::fluent::#slug);
+                        let mut #diag = #handler.struct_diagnostic(crate::fluent_generated::#slug);
                     }
                 }
             };
@@ -149,7 +149,7 @@ impl<'a> LintDiagnosticDerive<'a> {
                 }
                 Some(slug) => {
                     quote! {
-                        rustc_errors::fluent::#slug.into()
+                        crate::fluent_generated::#slug.into()
                     }
                 }
             }
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
index 12bcd939bd6..46068f8c868 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
@@ -452,7 +452,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
                 Ok(quote! {
                     #diag.span_suggestions_with_style(
                         #span_field,
-                        rustc_errors::fluent::#slug,
+                        crate::fluent_generated::#slug,
                         #code_field,
                         #applicability,
                         #style
@@ -476,7 +476,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
         quote! {
             #diag.#fn_name(
                 #field_binding,
-                rustc_errors::fluent::#fluent_attr_identifier
+                crate::fluent_generated::#fluent_attr_identifier
             );
         }
     }
@@ -486,7 +486,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
     fn add_subdiagnostic(&self, kind: &Ident, fluent_attr_identifier: Path) -> TokenStream {
         let diag = &self.parent.diag;
         quote! {
-            #diag.#kind(rustc_errors::fluent::#fluent_attr_identifier);
+            #diag.#kind(crate::fluent_generated::#fluent_attr_identifier);
         }
     }
 
diff --git a/compiler/rustc_macros/src/diagnostics/fluent.rs b/compiler/rustc_macros/src/diagnostics/fluent.rs
index 08098c9bb2a..38c0f4895db 100644
--- a/compiler/rustc_macros/src/diagnostics/fluent.rs
+++ b/compiler/rustc_macros/src/diagnostics/fluent.rs
@@ -19,52 +19,9 @@ use std::{
     io::Read,
     path::{Path, PathBuf},
 };
-use syn::{
-    parse::{Parse, ParseStream},
-    parse_macro_input,
-    punctuated::Punctuated,
-    token, Ident, LitStr, Result,
-};
+use syn::{parse_macro_input, Ident, LitStr};
 use unic_langid::langid;
 
-struct Resource {
-    krate: Ident,
-    #[allow(dead_code)]
-    fat_arrow_token: token::FatArrow,
-    resource_path: LitStr,
-}
-
-impl Parse for Resource {
-    fn parse(input: ParseStream<'_>) -> Result<Self> {
-        Ok(Resource {
-            krate: input.parse()?,
-            fat_arrow_token: input.parse()?,
-            resource_path: input.parse()?,
-        })
-    }
-}
-
-struct Resources(Punctuated<Resource, token::Comma>);
-
-impl Parse for Resources {
-    fn parse(input: ParseStream<'_>) -> Result<Self> {
-        let mut resources = Punctuated::new();
-        loop {
-            if input.is_empty() || input.peek(token::Brace) {
-                break;
-            }
-            let value = input.parse()?;
-            resources.push_value(value);
-            if !input.peek(token::Comma) {
-                break;
-            }
-            let punct = input.parse()?;
-            resources.push_punct(punct);
-        }
-        Ok(Resources(resources))
-    }
-}
-
 /// Helper function for returning an absolute path for macro-invocation relative file paths.
 ///
 /// If the input is already absolute, then the input is returned. If the input is not absolute,
@@ -84,251 +41,285 @@ fn invocation_relative_path_to_absolute(span: Span, path: &str) -> PathBuf {
     }
 }
 
+/// Tokens to be returned when the macro cannot proceed.
+fn failed(crate_name: &Ident) -> proc_macro::TokenStream {
+    quote! {
+        pub static DEFAULT_LOCALE_RESOURCE: &'static str = "";
+
+        #[allow(non_upper_case_globals)]
+        #[doc(hidden)]
+        pub(crate) mod fluent_generated {
+            pub mod #crate_name {
+            }
+
+            pub mod _subdiag {
+                pub const help: crate::SubdiagnosticMessage =
+                    crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("help"));
+                pub const note: crate::SubdiagnosticMessage =
+                    crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("note"));
+                pub const warn: crate::SubdiagnosticMessage =
+                    crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("warn"));
+                pub const label: crate::SubdiagnosticMessage =
+                    crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("label"));
+                pub const suggestion: crate::SubdiagnosticMessage =
+                    crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("suggestion"));
+            }
+        }
+    }
+    .into()
+}
+
 /// See [rustc_macros::fluent_messages].
 pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
-    let resources = parse_macro_input!(input as Resources);
+    let crate_name = std::env::var("CARGO_PKG_NAME")
+        // If `CARGO_PKG_NAME` is missing, then we're probably running in a test, so use
+        // `no_crate`.
+        .unwrap_or_else(|_| "no_crate".to_string())
+        .replace("rustc_", "");
 
     // Cannot iterate over individual messages in a bundle, so do that using the
     // `FluentResource` instead. Construct a bundle anyway to find out if there are conflicting
     // messages in the resources.
     let mut bundle = FluentBundle::new(vec![langid!("en-US")]);
 
-    // Map of Fluent identifiers to the `Span` of the resource that defined them, used for better
-    // diagnostics.
-    let mut previous_defns = HashMap::new();
-
     // Set of Fluent attribute names already output, to avoid duplicate type errors - any given
     // constant created for a given attribute is the same.
     let mut previous_attrs = HashSet::new();
 
-    let mut includes = TokenStream::new();
-    let mut generated = TokenStream::new();
+    let resource_str = parse_macro_input!(input as LitStr);
+    let resource_span = resource_str.span().unwrap();
+    let relative_ftl_path = resource_str.value();
+    let absolute_ftl_path = invocation_relative_path_to_absolute(resource_span, &relative_ftl_path);
 
-    for res in resources.0 {
-        let krate_span = res.krate.span().unwrap();
-        let path_span = res.resource_path.span().unwrap();
+    let crate_name = Ident::new(&crate_name, resource_str.span());
 
-        let relative_ftl_path = res.resource_path.value();
-        let absolute_ftl_path =
-            invocation_relative_path_to_absolute(krate_span, &relative_ftl_path);
-        // As this macro also outputs an `include_str!` for this file, the macro will always be
-        // re-executed when the file changes.
-        let mut resource_file = match File::open(absolute_ftl_path) {
-            Ok(resource_file) => resource_file,
-            Err(e) => {
-                Diagnostic::spanned(path_span, Level::Error, "could not open Fluent resource")
-                    .note(e.to_string())
-                    .emit();
-                continue;
-            }
-        };
-        let mut resource_contents = String::new();
-        if let Err(e) = resource_file.read_to_string(&mut resource_contents) {
-            Diagnostic::spanned(path_span, Level::Error, "could not read Fluent resource")
+    // As this macro also outputs an `include_str!` for this file, the macro will always be
+    // re-executed when the file changes.
+    let mut resource_file = match File::open(absolute_ftl_path) {
+        Ok(resource_file) => resource_file,
+        Err(e) => {
+            Diagnostic::spanned(resource_span, Level::Error, "could not open Fluent resource")
                 .note(e.to_string())
                 .emit();
-            continue;
+            return failed(&crate_name);
         }
-        let resource = match FluentResource::try_new(resource_contents) {
-            Ok(resource) => resource,
-            Err((this, errs)) => {
-                Diagnostic::spanned(path_span, Level::Error, "could not parse Fluent resource")
-                    .help("see additional errors emitted")
-                    .emit();
-                for ParserError { pos, slice: _, kind } in errs {
-                    let mut err = kind.to_string();
-                    // Entirely unnecessary string modification so that the error message starts
-                    // with a lowercase as rustc errors do.
-                    err.replace_range(
-                        0..1,
-                        &err.chars().next().unwrap().to_lowercase().to_string(),
-                    );
+    };
+    let mut resource_contents = String::new();
+    if let Err(e) = resource_file.read_to_string(&mut resource_contents) {
+        Diagnostic::spanned(resource_span, Level::Error, "could not read Fluent resource")
+            .note(e.to_string())
+            .emit();
+        return failed(&crate_name);
+    }
+
+    let resource = match FluentResource::try_new(resource_contents) {
+        Ok(resource) => resource,
+        Err((this, errs)) => {
+            Diagnostic::spanned(resource_span, Level::Error, "could not parse Fluent resource")
+                .help("see additional errors emitted")
+                .emit();
+            for ParserError { pos, slice: _, kind } in errs {
+                let mut err = kind.to_string();
+                // Entirely unnecessary string modification so that the error message starts
+                // with a lowercase as rustc errors do.
+                err.replace_range(0..1, &err.chars().next().unwrap().to_lowercase().to_string());
 
-                    let line_starts: Vec<usize> = std::iter::once(0)
-                        .chain(
-                            this.source()
-                                .char_indices()
-                                .filter_map(|(i, c)| Some(i + 1).filter(|_| c == '\n')),
-                        )
-                        .collect();
-                    let line_start = line_starts
-                        .iter()
-                        .enumerate()
-                        .map(|(line, idx)| (line + 1, idx))
-                        .filter(|(_, idx)| **idx <= pos.start)
-                        .last()
-                        .unwrap()
-                        .0;
+                let line_starts: Vec<usize> = std::iter::once(0)
+                    .chain(
+                        this.source()
+                            .char_indices()
+                            .filter_map(|(i, c)| Some(i + 1).filter(|_| c == '\n')),
+                    )
+                    .collect();
+                let line_start = line_starts
+                    .iter()
+                    .enumerate()
+                    .map(|(line, idx)| (line + 1, idx))
+                    .filter(|(_, idx)| **idx <= pos.start)
+                    .last()
+                    .unwrap()
+                    .0;
 
-                    let snippet = Snippet {
-                        title: Some(Annotation {
-                            label: Some(&err),
-                            id: None,
+                let snippet = Snippet {
+                    title: Some(Annotation {
+                        label: Some(&err),
+                        id: None,
+                        annotation_type: AnnotationType::Error,
+                    }),
+                    footer: vec![],
+                    slices: vec![Slice {
+                        source: this.source(),
+                        line_start,
+                        origin: Some(&relative_ftl_path),
+                        fold: true,
+                        annotations: vec![SourceAnnotation {
+                            label: "",
                             annotation_type: AnnotationType::Error,
-                        }),
-                        footer: vec![],
-                        slices: vec![Slice {
-                            source: this.source(),
-                            line_start,
-                            origin: Some(&relative_ftl_path),
-                            fold: true,
-                            annotations: vec![SourceAnnotation {
-                                label: "",
-                                annotation_type: AnnotationType::Error,
-                                range: (pos.start, pos.end - 1),
-                            }],
+                            range: (pos.start, pos.end - 1),
                         }],
-                        opt: Default::default(),
-                    };
-                    let dl = DisplayList::from(snippet);
-                    eprintln!("{dl}\n");
-                }
-                continue;
+                    }],
+                    opt: Default::default(),
+                };
+                let dl = DisplayList::from(snippet);
+                eprintln!("{dl}\n");
             }
-        };
 
-        let mut constants = TokenStream::new();
-        let mut messagerefs = Vec::new();
-        for entry in resource.entries() {
-            let span = res.krate.span();
-            if let Entry::Message(Message { id: Identifier { name }, attributes, value, .. }) =
-                entry
-            {
-                let _ = previous_defns.entry(name.to_string()).or_insert(path_span);
+            return failed(&crate_name);
+        }
+    };
 
-                if name.contains('-') {
-                    Diagnostic::spanned(
-                        path_span,
-                        Level::Error,
-                        format!("name `{name}` contains a '-' character"),
-                    )
-                    .help("replace any '-'s with '_'s")
-                    .emit();
-                }
+    let mut constants = TokenStream::new();
+    let mut previous_defns = HashMap::new();
+    let mut message_refs = Vec::new();
+    for entry in resource.entries() {
+        if let Entry::Message(Message { id: Identifier { name }, attributes, value, .. }) = entry {
+            let _ = previous_defns.entry(name.to_string()).or_insert(resource_span);
+            if name.contains('-') {
+                Diagnostic::spanned(
+                    resource_span,
+                    Level::Error,
+                    format!("name `{name}` contains a '-' character"),
+                )
+                .help("replace any '-'s with '_'s")
+                .emit();
+            }
 
-                if let Some(Pattern { elements }) = value {
-                    for elt in elements {
-                        if let PatternElement::Placeable {
-                            expression:
-                                Expression::Inline(InlineExpression::MessageReference { id, .. }),
-                        } = elt
-                        {
-                            messagerefs.push((id.name, *name));
-                        }
+            if let Some(Pattern { elements }) = value {
+                for elt in elements {
+                    if let PatternElement::Placeable {
+                        expression:
+                            Expression::Inline(InlineExpression::MessageReference { id, .. }),
+                    } = elt
+                    {
+                        message_refs.push((id.name, *name));
                     }
                 }
+            }
 
-                // Require that the message name starts with the crate name
-                // `hir_typeck_foo_bar` (in `hir_typeck.ftl`)
-                // `const_eval_baz` (in `const_eval.ftl`)
-                // `const-eval-hyphen-having` => `hyphen_having` (in `const_eval.ftl`)
-                // The last case we error about above, but we want to fall back gracefully
-                // so that only the error is being emitted and not also one about the macro
-                // failing.
-                let crate_prefix = format!("{}_", res.krate);
+            // `typeck_foo_bar` => `foo_bar` (in `typeck.ftl`)
+            // `const_eval_baz` => `baz` (in `const_eval.ftl`)
+            // `const-eval-hyphen-having` => `hyphen_having` (in `const_eval.ftl`)
+            // The last case we error about above, but we want to fall back gracefully
+            // so that only the error is being emitted and not also one about the macro
+            // failing.
+            let crate_prefix = format!("{crate_name}_");
 
-                let snake_name = name.replace('-', "_");
-                if !snake_name.starts_with(&crate_prefix) {
+            let snake_name = name.replace('-', "_");
+            if !snake_name.starts_with(&crate_prefix) {
+                Diagnostic::spanned(
+                    resource_span,
+                    Level::Error,
+                    format!("name `{name}` does not start with the crate name"),
+                )
+                .help(format!(
+                    "prepend `{crate_prefix}` to the slug name: `{crate_prefix}{snake_name}`"
+                ))
+                .emit();
+            };
+            let snake_name = Ident::new(&snake_name, resource_str.span());
+
+            if !previous_attrs.insert(snake_name.clone()) {
+                continue;
+            }
+
+            let msg = format!("Constant referring to Fluent message `{name}` from `{crate_name}`");
+            constants.extend(quote! {
+                #[doc = #msg]
+                pub const #snake_name: crate::DiagnosticMessage =
+                    crate::DiagnosticMessage::FluentIdentifier(
+                        std::borrow::Cow::Borrowed(#name),
+                        None
+                    );
+            });
+
+            for Attribute { id: Identifier { name: attr_name }, .. } in attributes {
+                let snake_name = Ident::new(
+                    &format!("{}{}", &crate_prefix, &attr_name.replace('-', "_")),
+                    resource_str.span(),
+                );
+                if !previous_attrs.insert(snake_name.clone()) {
+                    continue;
+                }
+
+                if attr_name.contains('-') {
                     Diagnostic::spanned(
-                        path_span,
+                        resource_span,
                         Level::Error,
-                        format!("name `{name}` does not start with the crate name"),
+                        format!("attribute `{attr_name}` contains a '-' character"),
                     )
-                    .help(format!(
-                        "prepend `{crate_prefix}` to the slug name: `{crate_prefix}{snake_name}`"
-                    ))
+                    .help("replace any '-'s with '_'s")
                     .emit();
-                };
-
-                let snake_name = Ident::new(&snake_name, span);
+                }
 
+                let msg = format!(
+                    "Constant referring to Fluent message `{name}.{attr_name}` from `{crate_name}`"
+                );
                 constants.extend(quote! {
-                    pub const #snake_name: crate::DiagnosticMessage =
-                        crate::DiagnosticMessage::FluentIdentifier(
-                            std::borrow::Cow::Borrowed(#name),
-                            None
+                    #[doc = #msg]
+                    pub const #snake_name: crate::SubdiagnosticMessage =
+                        crate::SubdiagnosticMessage::FluentAttr(
+                            std::borrow::Cow::Borrowed(#attr_name)
                         );
                 });
-
-                for Attribute { id: Identifier { name: attr_name }, .. } in attributes {
-                    let snake_name = Ident::new(&attr_name.replace('-', "_"), span);
-                    if !previous_attrs.insert(snake_name.clone()) {
-                        continue;
-                    }
-
-                    if attr_name.contains('-') {
-                        Diagnostic::spanned(
-                            path_span,
-                            Level::Error,
-                            format!("attribute `{attr_name}` contains a '-' character"),
-                        )
-                        .help("replace any '-'s with '_'s")
-                        .emit();
-                    }
-
-                    constants.extend(quote! {
-                        pub const #snake_name: crate::SubdiagnosticMessage =
-                            crate::SubdiagnosticMessage::FluentAttr(
-                                std::borrow::Cow::Borrowed(#attr_name)
-                            );
-                    });
-                }
             }
         }
+    }
 
-        for (mref, name) in messagerefs.into_iter() {
-            if !previous_defns.contains_key(mref) {
-                Diagnostic::spanned(
-                    path_span,
-                    Level::Error,
-                    format!("referenced message `{mref}` does not exist (in message `{name}`)"),
-                )
-                .help(&format!("you may have meant to use a variable reference (`{{${mref}}}`)"))
-                .emit();
-            }
+    for (mref, name) in message_refs.into_iter() {
+        if !previous_defns.contains_key(mref) {
+            Diagnostic::spanned(
+                resource_span,
+                Level::Error,
+                format!("referenced message `{mref}` does not exist (in message `{name}`)"),
+            )
+            .help(&format!("you may have meant to use a variable reference (`{{${mref}}}`)"))
+            .emit();
         }
+    }
 
-        if let Err(errs) = bundle.add_resource(resource) {
-            for e in errs {
-                match e {
-                    FluentError::Overriding { kind, id } => {
-                        Diagnostic::spanned(
-                            path_span,
-                            Level::Error,
-                            format!("overrides existing {kind}: `{id}`"),
-                        )
-                        .span_help(previous_defns[&id], "previously defined in this resource")
-                        .emit();
-                    }
-                    FluentError::ResolverError(_) | FluentError::ParserError(_) => unreachable!(),
+    if let Err(errs) = bundle.add_resource(resource) {
+        for e in errs {
+            match e {
+                FluentError::Overriding { kind, id } => {
+                    Diagnostic::spanned(
+                        resource_span,
+                        Level::Error,
+                        format!("overrides existing {kind}: `{id}`"),
+                    )
+                    .emit();
                 }
+                FluentError::ResolverError(_) | FluentError::ParserError(_) => unreachable!(),
             }
         }
-
-        includes.extend(quote! { include_str!(#relative_ftl_path), });
-
-        generated.extend(constants);
     }
 
     quote! {
+        /// Raw content of Fluent resource for this crate, generated by `fluent_messages` macro,
+        /// imported by `rustc_driver` to include all crates' resources in one bundle.
+        pub static DEFAULT_LOCALE_RESOURCE: &'static str = include_str!(#relative_ftl_path);
+
         #[allow(non_upper_case_globals)]
         #[doc(hidden)]
-        pub mod fluent_generated {
-            pub static DEFAULT_LOCALE_RESOURCES: &'static [&'static str] = &[
-                #includes
-            ];
-
-            #generated
+        /// Auto-generated constants for type-checked references to Fluent messages.
+        pub(crate) mod fluent_generated {
+            #constants
 
+            /// Constants expected to exist by the diagnostic derive macros to use as default Fluent
+            /// identifiers for different subdiagnostic kinds.
             pub mod _subdiag {
+                /// Default for `#[help]`
                 pub const help: crate::SubdiagnosticMessage =
                     crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("help"));
+                /// Default for `#[note]`
                 pub const note: crate::SubdiagnosticMessage =
                     crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("note"));
+                /// Default for `#[warn]`
                 pub const warn: crate::SubdiagnosticMessage =
                     crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("warn"));
+                /// Default for `#[label]`
                 pub const label: crate::SubdiagnosticMessage =
                     crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("label"));
+                /// Default for `#[suggestion]`
                 pub const suggestion: crate::SubdiagnosticMessage =
                     crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("suggestion"));
             }
diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
index 906e4c0b0e1..90660fc1f93 100644
--- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
+++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
@@ -512,7 +512,9 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
         let mut calls = TokenStream::new();
         for (kind, slug) in kind_slugs {
             let message = format_ident!("__message");
-            calls.extend(quote! { let #message = #f(#diag, rustc_errors::fluent::#slug.into()); });
+            calls.extend(
+                quote! { let #message = #f(#diag, crate::fluent_generated::#slug.into()); },
+            );
 
             let name = format_ident!("{}{}", if span_field.is_some() { "span_" } else { "" }, kind);
             let call = match kind {
diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs
index d2cb6ee9f71..737500cc257 100644
--- a/compiler/rustc_macros/src/lib.rs
+++ b/compiler/rustc_macros/src/lib.rs
@@ -61,9 +61,7 @@ pub fn newtype_index(input: TokenStream) -> TokenStream {
 /// For example, given the following invocation of the macro..
 ///
 /// ```ignore (rust)
-/// fluent_messages! {
-///     typeck => "./typeck.ftl",
-/// }
+/// fluent_messages! { "./typeck.ftl" }
 /// ```
 /// ..where `typeck.ftl` has the following contents..
 ///
@@ -77,9 +75,7 @@ pub fn newtype_index(input: TokenStream) -> TokenStream {
 /// will generate the following code:
 ///
 /// ```ignore (rust)
-/// pub static DEFAULT_LOCALE_RESOURCES: &'static [&'static str] = &[
-///     include_str!("./typeck.ftl"),
-/// ];
+/// pub static DEFAULT_LOCALE_RESOURCE: &'static [&'static str] = include_str!("./typeck.ftl");
 ///
 /// mod fluent_generated {
 ///     mod typeck {
diff --git a/compiler/rustc_macros/src/type_foldable.rs b/compiler/rustc_macros/src/type_foldable.rs
index 51729a377d9..388e254cd64 100644
--- a/compiler/rustc_macros/src/type_foldable.rs
+++ b/compiler/rustc_macros/src/type_foldable.rs
@@ -37,16 +37,16 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::
                 bind.to_token_stream()
             } else {
                 quote! {
-                    ::rustc_middle::ty::fold::ir::TypeFoldable::try_fold_with(#bind, __folder)?
+                    ::rustc_middle::ty::fold::TypeFoldable::try_fold_with(#bind, __folder)?
                 }
             }
         })
     });
 
     s.bound_impl(
-        quote!(::rustc_middle::ty::fold::ir::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>),
+        quote!(::rustc_middle::ty::fold::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>),
         quote! {
-            fn try_fold_with<__F: ::rustc_middle::ty::fold::FallibleTypeFolder<'tcx>>(
+            fn try_fold_with<__F: ::rustc_middle::ty::fold::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(
                 self,
                 __folder: &mut __F
             ) -> Result<Self, __F::Error> {
diff --git a/compiler/rustc_macros/src/type_visitable.rs b/compiler/rustc_macros/src/type_visitable.rs
index 0a16a371fdc..f6f4c4779c3 100644
--- a/compiler/rustc_macros/src/type_visitable.rs
+++ b/compiler/rustc_macros/src/type_visitable.rs
@@ -30,15 +30,15 @@ pub fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:
     s.add_bounds(synstructure::AddBounds::Generics);
     let body_visit = s.each(|bind| {
         quote! {
-            ::rustc_middle::ty::visit::ir::TypeVisitable::visit_with(#bind, __visitor)?;
+            ::rustc_middle::ty::visit::TypeVisitable::visit_with(#bind, __visitor)?;
         }
     });
     s.bind_with(|_| synstructure::BindStyle::Move);
 
     s.bound_impl(
-        quote!(::rustc_middle::ty::visit::ir::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>),
+        quote!(::rustc_middle::ty::visit::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>),
         quote! {
-            fn visit_with<__V: ::rustc_middle::ty::visit::TypeVisitor<'tcx>>(
+            fn visit_with<__V: ::rustc_middle::ty::visit::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(
                 &self,
                 __visitor: &mut __V
             ) -> ::std::ops::ControlFlow<__V::BreakTy> {
diff --git a/compiler/rustc_error_messages/locales/en-US/metadata.ftl b/compiler/rustc_metadata/locales/en-US.ftl
index 79b8b417257..79b8b417257 100644
--- a/compiler/rustc_error_messages/locales/en-US/metadata.ftl
+++ b/compiler/rustc_metadata/locales/en-US.ftl
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
index c32686779fa..51b41b5f6a2 100644
--- a/compiler/rustc_metadata/src/errors.rs
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -9,6 +9,7 @@ use rustc_session::config;
 use rustc_span::{sym, Span, Symbol};
 use rustc_target::spec::{PanicStrategy, TargetTriple};
 
+use crate::fluent_generated as fluent;
 use crate::locator::CrateFlavor;
 
 #[derive(Diagnostic)]
@@ -491,7 +492,7 @@ impl IntoDiagnostic<'_> for MultipleCandidates {
         self,
         handler: &'_ rustc_errors::Handler,
     ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
-        let mut diag = handler.struct_err(rustc_errors::fluent::metadata_multiple_candidates);
+        let mut diag = handler.struct_err(fluent::metadata_multiple_candidates);
         diag.set_arg("crate_name", self.crate_name);
         diag.set_arg("flavor", self.flavor);
         diag.code(error_code!(E0464));
@@ -590,7 +591,7 @@ impl IntoDiagnostic<'_> for InvalidMetadataFiles {
         self,
         handler: &'_ rustc_errors::Handler,
     ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
-        let mut diag = handler.struct_err(rustc_errors::fluent::metadata_invalid_meta_files);
+        let mut diag = handler.struct_err(fluent::metadata_invalid_meta_files);
         diag.set_arg("crate_name", self.crate_name);
         diag.set_arg("add_info", self.add_info);
         diag.code(error_code!(E0786));
@@ -619,7 +620,7 @@ impl IntoDiagnostic<'_> for CannotFindCrate {
         self,
         handler: &'_ rustc_errors::Handler,
     ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
-        let mut diag = handler.struct_err(rustc_errors::fluent::metadata_cannot_find_crate);
+        let mut diag = handler.struct_err(fluent::metadata_cannot_find_crate);
         diag.set_arg("crate_name", self.crate_name);
         diag.set_arg("current_crate", self.current_crate);
         diag.set_arg("add_info", self.add_info);
@@ -630,32 +631,32 @@ impl IntoDiagnostic<'_> for CannotFindCrate {
             && self.locator_triple != TargetTriple::from_triple(config::host_triple())
         {
             if self.missing_core {
-                diag.note(rustc_errors::fluent::metadata_target_not_installed);
+                diag.note(fluent::metadata_target_not_installed);
             } else {
-                diag.note(rustc_errors::fluent::metadata_target_no_std_support);
+                diag.note(fluent::metadata_target_no_std_support);
             }
             // NOTE: this suggests using rustup, even though the user may not have it installed.
             // That's because they could choose to install it; or this may give them a hint which
             // target they need to install from their distro.
             if self.missing_core {
-                diag.help(rustc_errors::fluent::metadata_consider_downloading_target);
+                diag.help(fluent::metadata_consider_downloading_target);
             }
             // Suggest using #![no_std]. #[no_core] is unstable and not really supported anyway.
             // NOTE: this is a dummy span if `extern crate std` was injected by the compiler.
             // If it's not a dummy, that means someone added `extern crate std` explicitly and
             // `#![no_std]` won't help.
             if !self.missing_core && self.span.is_dummy() {
-                diag.note(rustc_errors::fluent::metadata_std_required);
+                diag.note(fluent::metadata_std_required);
             }
             if self.is_nightly_build {
-                diag.help(rustc_errors::fluent::metadata_consider_building_std);
+                diag.help(fluent::metadata_consider_building_std);
             }
         } else if self.crate_name == self.profiler_runtime {
-            diag.note(rustc_errors::fluent::metadata_compiler_missing_profiler);
+            diag.note(fluent::metadata_compiler_missing_profiler);
         } else if self.crate_name.as_str().starts_with("rustc_") {
-            diag.help(rustc_errors::fluent::metadata_install_missing_components);
+            diag.help(fluent::metadata_install_missing_components);
         }
-        diag.span_label(self.span, rustc_errors::fluent::metadata_cant_find_crate);
+        diag.span_label(self.span, fluent::metadata_cant_find_crate);
         diag
     }
 }
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 1987f88e6b8..6f6d3731cea 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -30,6 +30,8 @@ extern crate rustc_data_structures;
 extern crate tracing;
 
 pub use rmeta::{provide, provide_extern};
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_macros::fluent_messages;
 
 mod dependency_format;
 mod foreign_modules;
@@ -44,3 +46,5 @@ pub mod locator;
 pub use fs::{emit_wrapper_file, METADATA_FILENAME};
 pub use native_libs::find_native_static_library;
 pub use rmeta::{encode_metadata, EncodedMetadata, METADATA_HEADER};
+
+fluent_messages! { "../locales/en-US.ftl" }
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index d823989bb02..d6f68b2e140 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -103,8 +103,13 @@ impl<'tcx> Collector<'tcx> {
         }
 
         // Process all of the #[link(..)]-style arguments
-        let sess = &self.tcx.sess;
+        let sess = self.tcx.sess;
         let features = self.tcx.features();
+
+        if !sess.opts.unstable_opts.link_directives {
+            return;
+        }
+
         for m in self.tcx.hir().attrs(it.hir_id()).iter().filter(|a| a.has_name(sym::link)) {
             let Some(items) = m.meta_item_list() else {
                 continue;
@@ -502,7 +507,7 @@ impl<'tcx> Collector<'tcx> {
                 .subst_identity()
                 .fn_sig(self.tcx)
                 .inputs()
-                .map_bound(|slice| self.tcx.intern_type_list(slice)),
+                .map_bound(|slice| self.tcx.mk_type_list(slice)),
         );
 
         argument_types
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 3457e51f8e6..b1e59b0a470 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -910,7 +910,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             std::iter::once(self.get_variant(&kind, item_id, did)).collect()
         };
 
-        tcx.alloc_adt_def(did, adt_kind, variants, repr)
+        tcx.mk_adt_def(did, adt_kind, variants, repr)
     }
 
     fn get_generics(self, item_id: DefIndex, sess: &Session) -> ty::Generics {
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 60ea08a1647..83a0e833edc 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -254,6 +254,8 @@ provide! { tcx, def_id, other, cdata,
             .process_decoded(tcx, || panic!("{def_id:?} does not have trait_impl_trait_tys")))
      }
 
+    associated_items_for_impl_trait_in_trait => { table_defaulted_array }
+
     visibility => { cdata.get_visibility(def_id.index) }
     adt_def => { cdata.get_adt_def(def_id.index, tcx) }
     adt_destructor => {
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index e941dd45688..f0dafe73c00 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1129,6 +1129,11 @@ fn should_encode_trait_impl_trait_tys(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     })
 }
 
+// Return `false` to avoid encoding impl trait in trait, while we don't use the query.
+fn should_encode_fn_impl_trait_in_trait<'tcx>(_tcx: TyCtxt<'tcx>, _def_id: DefId) -> bool {
+    false
+}
+
 impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     fn encode_attrs(&mut self, def_id: LocalDefId) {
         let tcx = self.tcx;
@@ -1137,8 +1142,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             is_doc_hidden: false,
         };
         let attr_iter = tcx
-            .hir()
-            .attrs(tcx.hir().local_def_id_to_hir_id(def_id))
+            .opt_local_def_id_to_hir_id(def_id)
+            .map_or(Default::default(), |hir_id| tcx.hir().attrs(hir_id))
             .iter()
             .filter(|attr| analyze_attr(attr, &mut state));
 
@@ -1211,6 +1216,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             {
                 record!(self.tables.trait_impl_trait_tys[def_id] <- table);
             }
+            if should_encode_fn_impl_trait_in_trait(tcx, def_id) {
+                let table = tcx.associated_items_for_impl_trait_in_trait(def_id);
+                record_defaulted_array!(self.tables.associated_items_for_impl_trait_in_trait[def_id] <- table);
+            }
         }
 
         let inherent_impls = tcx.with_stable_hashing_context(|hcx| {
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 01691398ad0..a7ec2d790b7 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -354,6 +354,7 @@ define_tables! {
     explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Predicate<'static>, Span)>>,
     inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
     inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
+    associated_items_for_impl_trait_in_trait: Table<DefIndex, LazyArray<DefId>>,
 
 - optional:
     attributes: Table<DefIndex, LazyArray<ast::Attribute>>,
diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml
index 543bd56a20c..a2b78cc2985 100644
--- a/compiler/rustc_middle/Cargo.toml
+++ b/compiler/rustc_middle/Cargo.toml
@@ -34,7 +34,7 @@ rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 rustc_type_ir = { path = "../rustc_type_ir" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-thin-vec = "0.2.9"
+thin-vec = "0.2.12"
 tracing = "0.1"
 
 [features]
diff --git a/compiler/rustc_error_messages/locales/en-US/middle.ftl b/compiler/rustc_middle/locales/en-US.ftl
index 4f4e5c6a2c9..4f4e5c6a2c9 100644
--- a/compiler/rustc_error_messages/locales/en-US/middle.ftl
+++ b/compiler/rustc_middle/locales/en-US.ftl
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 2eafc356dc3..2df851a7857 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -849,6 +849,13 @@ impl<'hir> Map<'hir> {
         }
     }
 
+    pub fn get_fn_output(self, def_id: LocalDefId) -> Option<&'hir FnRetTy<'hir>> {
+        match self.tcx.hir_owner(OwnerId { def_id }) {
+            Some(Owner { node, .. }) => node.fn_decl().map(|fn_decl| &fn_decl.output),
+            _ => None,
+        }
+    }
+
     pub fn expect_variant(self, id: HirId) -> &'hir Variant<'hir> {
         match self.find(id) {
             Some(Node::Variant(variant)) => variant,
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index dc89f762b76..2e2ca6a2788 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -121,13 +121,13 @@ pub fn provide(providers: &mut Providers) {
         let node = owner.node();
         Some(Owner { node, hash_without_bodies: owner.nodes.hash_without_bodies })
     };
-    providers.local_def_id_to_hir_id = |tcx, id| {
+    providers.opt_local_def_id_to_hir_id = |tcx, id| {
         let owner = tcx.hir_crate(()).owners[id].map(|_| ());
-        match owner {
+        Some(match owner {
             MaybeOwner::Owner(_) => HirId::make_owner(id),
             MaybeOwner::Phantom => bug!("No HirId for {:?}", id),
             MaybeOwner::NonOwner(hir_id) => hir_id,
-        }
+        })
     };
     providers.hir_owner_nodes = |tcx, id| tcx.hir_crate(()).owners[id.def_id].map(|i| &i.nodes);
     providers.hir_owner_parent = |tcx, id| {
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index bb617e692cc..8712514a384 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -42,12 +42,12 @@ pub struct Canonical<'tcx, V> {
 
 pub type CanonicalVarInfos<'tcx> = &'tcx List<CanonicalVarInfo<'tcx>>;
 
-impl<'tcx> ty::ir::TypeFoldable<TyCtxt<'tcx>> for CanonicalVarInfos<'tcx> {
-    fn try_fold_with<F: ty::FallibleTypeFolder<'tcx>>(
+impl<'tcx> ty::TypeFoldable<TyCtxt<'tcx>> for CanonicalVarInfos<'tcx> {
+    fn try_fold_with<F: ty::FallibleTypeFolder<TyCtxt<'tcx>>>(
         self,
         folder: &mut F,
     ) -> Result<Self, F::Error> {
-        ty::util::fold_list(self, folder, |tcx, v| tcx.intern_canonical_var_infos(v))
+        ty::util::fold_list(self, folder, |tcx, v| tcx.mk_canonical_var_infos(v))
     }
 }
 
@@ -342,7 +342,7 @@ impl<'tcx> CanonicalVarValues<'tcx> {
         infos: CanonicalVarInfos<'tcx>,
     ) -> CanonicalVarValues<'tcx> {
         CanonicalVarValues {
-            var_values: tcx.mk_substs(infos.iter().enumerate().map(
+            var_values: tcx.mk_substs_from_iter(infos.iter().enumerate().map(
                 |(i, info)| -> ty::GenericArg<'tcx> {
                     match info.kind {
                         CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) => {
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index e6cd38c0f15..c33b9d84eb0 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -73,6 +73,9 @@ extern crate tracing;
 #[macro_use]
 extern crate smallvec;
 
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_macros::fluent_messages;
+
 #[cfg(test)]
 mod tests;
 
@@ -105,3 +108,5 @@ pub mod util {
 
 // Allows macros to refer to this crate as `::rustc_middle`
 extern crate self as rustc_middle;
+
+fluent_messages! { "../locales/en-US.ftl" }
diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs
index 57d66ac6a03..a8d71ce030c 100644
--- a/compiler/rustc_middle/src/macros.rs
+++ b/compiler/rustc_middle/src/macros.rs
@@ -69,8 +69,8 @@ macro_rules! CloneLiftImpls {
 macro_rules! TrivialTypeTraversalImpls {
     (for <$tcx:lifetime> { $($ty:ty,)+ }) => {
         $(
-            impl<$tcx> $crate::ty::fold::ir::TypeFoldable<$crate::ty::TyCtxt<$tcx>> for $ty {
-                fn try_fold_with<F: $crate::ty::fold::FallibleTypeFolder<$tcx>>(
+            impl<$tcx> $crate::ty::fold::TypeFoldable<$crate::ty::TyCtxt<$tcx>> for $ty {
+                fn try_fold_with<F: $crate::ty::fold::FallibleTypeFolder<$crate::ty::TyCtxt<$tcx>>>(
                     self,
                     _: &mut F,
                 ) -> ::std::result::Result<Self, F::Error> {
@@ -78,7 +78,7 @@ macro_rules! TrivialTypeTraversalImpls {
                 }
 
                 #[inline]
-                fn fold_with<F: $crate::ty::fold::TypeFolder<$tcx>>(
+                fn fold_with<F: $crate::ty::fold::TypeFolder<$crate::ty::TyCtxt<$tcx>>>(
                     self,
                     _: &mut F,
                 ) -> Self {
@@ -86,9 +86,9 @@ macro_rules! TrivialTypeTraversalImpls {
                 }
             }
 
-            impl<$tcx> $crate::ty::visit::ir::TypeVisitable<$crate::ty::TyCtxt<$tcx>> for $ty {
+            impl<$tcx> $crate::ty::visit::TypeVisitable<$crate::ty::TyCtxt<$tcx>> for $ty {
                 #[inline]
-                fn visit_with<F: $crate::ty::visit::TypeVisitor<$tcx>>(
+                fn visit_with<F: $crate::ty::visit::TypeVisitor<$crate::ty::TyCtxt<$tcx>>>(
                     &self,
                     _: &mut F)
                     -> ::std::ops::ControlFlow<F::BreakTy>
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index 0836f236e24..354c84e2209 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -255,7 +255,7 @@ fn late_report_deprecation(
     let method_span = method_span.unwrap_or(span);
     tcx.struct_span_lint_hir(lint, hir_id, method_span, message, |diag| {
         if let hir::Node::Expr(_) = tcx.hir().get(hir_id) {
-            let kind = tcx.def_kind(def_id).descr(def_id);
+            let kind = tcx.def_descr(def_id);
             deprecation_suggestion(diag, kind, suggestion, method_span);
         }
         diag
@@ -392,7 +392,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     let lint = deprecation_lint(is_in_effect);
                     if self.lint_level_at_node(lint, id).0 != Level::Allow {
                         let def_path = with_no_trimmed_paths!(self.def_path_str(def_id));
-                        let def_kind = self.def_kind(def_id).descr(def_id);
+                        let def_kind = self.def_descr(def_id);
 
                         late_report_deprecation(
                             self,
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index b6c6e9d559c..856d821a5cf 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -2,7 +2,7 @@ use super::{ErrorHandled, EvalToConstValueResult, EvalToValTreeResult, GlobalId}
 
 use crate::mir;
 use crate::ty::subst::InternalSubsts;
-use crate::ty::visit::TypeVisitable;
+use crate::ty::visit::TypeVisitableExt;
 use crate::ty::{self, query::TyCtxtAt, query::TyCtxtEnsure, TyCtxt};
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 46184cddd51..0d78c6135b3 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -7,10 +7,10 @@ use crate::mir::interpret::{
 };
 use crate::mir::visit::MirVisitable;
 use crate::ty::codec::{TyDecoder, TyEncoder};
-use crate::ty::fold::{ir::TypeFoldable, FallibleTypeFolder};
+use crate::ty::fold::{FallibleTypeFolder, TypeFoldable};
 use crate::ty::print::{FmtPrinter, Printer};
-use crate::ty::visit::{TypeVisitable, TypeVisitor};
-use crate::ty::{self, ir, DefIdTree, List, Ty, TyCtxt};
+use crate::ty::visit::{TypeVisitable, TypeVisitableExt, TypeVisitor};
+use crate::ty::{self, DefIdTree, List, Ty, TyCtxt};
 use crate::ty::{AdtDef, InstanceDef, ScalarInt, UserTypeAnnotationIndex};
 use crate::ty::{GenericArg, InternalSubsts, SubstsRef};
 
@@ -1620,7 +1620,7 @@ impl<'tcx> Place<'tcx> {
             &v
         };
 
-        Place { local: self.local, projection: tcx.intern_place_elems(new_projections) }
+        Place { local: self.local, projection: tcx.mk_place_elems(new_projections) }
     }
 }
 
@@ -2530,13 +2530,14 @@ impl<'tcx> ConstantKind<'tcx> {
         {
             InternalSubsts::identity_for_item(tcx, parent_did.to_def_id())
         } else {
-            tcx.intern_substs(&[])
+            List::empty()
         };
         debug!(?parent_substs);
 
         let did = def.did.to_def_id();
         let child_substs = InternalSubsts::identity_for_item(tcx, did);
-        let substs = tcx.mk_substs(parent_substs.into_iter().chain(child_substs.into_iter()));
+        let substs =
+            tcx.mk_substs_from_iter(parent_substs.into_iter().chain(child_substs.into_iter()));
         debug!(?substs);
 
         let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
@@ -2755,7 +2756,10 @@ impl UserTypeProjection {
 }
 
 impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for UserTypeProjection {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        folder: &mut F,
+    ) -> Result<Self, F::Error> {
         Ok(UserTypeProjection {
             base: self.base.try_fold_with(folder)?,
             projs: self.projs.try_fold_with(folder)?,
@@ -2763,8 +2767,11 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for UserTypeProjection {
     }
 }
 
-impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for UserTypeProjection {
-    fn visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> ControlFlow<Vs::BreakTy> {
+impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for UserTypeProjection {
+    fn visit_with<Vs: TypeVisitor<TyCtxt<'tcx>>>(
+        &self,
+        visitor: &mut Vs,
+    ) -> ControlFlow<Vs::BreakTy> {
         self.base.visit_with(visitor)
         // Note: there's nothing in `self.proj` to visit.
     }
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index aa9f170477b..0aa2c500f51 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -194,14 +194,16 @@ impl<'tcx> Rvalue<'tcx> {
                 let lhs_ty = lhs.ty(local_decls, tcx);
                 let rhs_ty = rhs.ty(local_decls, tcx);
                 let ty = op.ty(tcx, lhs_ty, rhs_ty);
-                tcx.intern_tup(&[ty, tcx.types.bool])
+                tcx.mk_tup(&[ty, tcx.types.bool])
             }
             Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, ref operand) => operand.ty(local_decls, tcx),
             Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx),
             Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => tcx.types.usize,
             Rvalue::Aggregate(ref ak, ref ops) => match **ak {
                 AggregateKind::Array(ty) => tcx.mk_array(ty, ops.len() as u64),
-                AggregateKind::Tuple => tcx.mk_tup(ops.iter().map(|op| op.ty(local_decls, tcx))),
+                AggregateKind::Tuple => {
+                    tcx.mk_tup_from_iter(ops.iter().map(|op| op.ty(local_decls, tcx)))
+                }
                 AggregateKind::Adt(did, _, substs, _, _) => tcx.type_of(did).subst(tcx, substs),
                 AggregateKind::Closure(did, substs) => tcx.mk_closure(did, substs),
                 AggregateKind::Generator(did, substs, movability) => {
diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs
index ce06a0ef060..9881583214e 100644
--- a/compiler/rustc_middle/src/mir/type_foldable.rs
+++ b/compiler/rustc_middle/src/mir/type_foldable.rs
@@ -31,19 +31,28 @@ TrivialTypeTraversalImpls! {
 }
 
 impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx [InlineAsmTemplatePiece] {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        _folder: &mut F,
+    ) -> Result<Self, F::Error> {
         Ok(self)
     }
 }
 
 impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx [Span] {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        _folder: &mut F,
+    ) -> Result<Self, F::Error> {
         Ok(self)
     }
 }
 
 impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<PlaceElem<'tcx>> {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
-        ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v))
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        folder: &mut F,
+    ) -> Result<Self, F::Error> {
+        ty::util::fold_list(self, folder, |tcx, v| tcx.mk_place_elems(v))
     }
 }
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 443c1b2d261..5c056b29975 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -1045,7 +1045,7 @@ macro_rules! visit_place_fns {
             self.visit_local(&mut place.local, context, location);
 
             if let Some(new_projection) = self.process_projection(&place.projection, location) {
-                place.projection = self.tcx().intern_place_elems(&new_projection);
+                place.projection = self.tcx().mk_place_elems(&new_projection);
             }
         }
 
@@ -1214,7 +1214,7 @@ impl<'tcx> MirVisitable<'tcx> for Option<Terminator<'tcx>> {
 
 /// Extra information passed to `visit_ty` and friends to give context
 /// about where the type etc appears.
-#[derive(Debug)]
+#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
 pub enum TyContext {
     LocalDecl {
         /// The index of the local variable we are visiting.
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 3b559c7f8ad..6a34e5ede19 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -85,11 +85,10 @@ rustc_queries! {
         desc { |tcx| "getting HIR owner of `{}`", tcx.def_path_str(key.to_def_id()) }
     }
 
-    /// Gives access to the HIR ID for the given `LocalDefId` owner `key`.
+    /// Gives access to the HIR ID for the given `LocalDefId` owner `key` if any.
     ///
-    /// This can be conveniently accessed by methods on `tcx.hir()`.
-    /// Avoid calling this query directly.
-    query local_def_id_to_hir_id(key: LocalDefId) -> hir::HirId {
+    /// Definitions that were generated with no HIR, would be feeded to return `None`.
+    query opt_local_def_id_to_hir_id(key: LocalDefId) -> Option<hir::HirId>{
         desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key.to_def_id()) }
     }
 
@@ -767,6 +766,26 @@ rustc_queries! {
         desc { |tcx| "comparing impl items against trait for `{}`", tcx.def_path_str(impl_id) }
     }
 
+    /// Given `fn_def_id` of a trait or of an impl that implements a given trait:
+    /// if `fn_def_id` is the def id of a function defined inside a trait, then it creates and returns
+    /// the associated items that correspond to each impl trait in return position for that trait.
+    /// if `fn_def_id` is the def id of a function defined inside an impl that implements a trait, then it
+    /// creates and returns the associated items that correspond to each impl trait in return position
+    /// of the implemented trait.
+    query associated_items_for_impl_trait_in_trait(fn_def_id: DefId) -> &'tcx [DefId] {
+        desc { |tcx| "creating associated items for impl trait in trait returned by `{}`", tcx.def_path_str(fn_def_id) }
+        cache_on_disk_if { fn_def_id.is_local() }
+        separate_provide_extern
+    }
+
+    /// Given an impl trait in trait `opaque_ty_def_id`, create and return the corresponding
+    /// associated item.
+    query associated_item_for_impl_trait_in_trait(opaque_ty_def_id: LocalDefId) -> LocalDefId {
+        desc { |tcx| "creates the associated item corresponding to the opaque type `{}`", tcx.def_path_str(opaque_ty_def_id.to_def_id()) }
+        cache_on_disk_if { true }
+        separate_provide_extern
+    }
+
     /// Given an `impl_id`, return the trait it implements.
     /// Return `None` if this is an inherent impl.
     query impl_trait_ref(impl_id: DefId) -> Option<ty::EarlyBinder<ty::TraitRef<'tcx>>> {
diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs
index 615154a55e5..c4f8718754f 100644
--- a/compiler/rustc_middle/src/traits/query.rs
+++ b/compiler/rustc_middle/src/traits/query.rs
@@ -14,7 +14,7 @@ use rustc_span::source_map::Span;
 
 pub mod type_op {
     use crate::ty::fold::TypeFoldable;
-    use crate::ty::{Predicate, Ty, UserType};
+    use crate::ty::{Predicate, Ty, TyCtxt, UserType};
     use std::fmt;
 
     #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
@@ -64,7 +64,7 @@ pub mod type_op {
 
     impl<'tcx, T> Normalize<T>
     where
-        T: fmt::Debug + TypeFoldable<'tcx>,
+        T: fmt::Debug + TypeFoldable<TyCtxt<'tcx>>,
     {
         pub fn new(value: T) -> Self {
             Self { value }
diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs
index bddf84880d2..c5bf9717f03 100644
--- a/compiler/rustc_middle/src/traits/solve.rs
+++ b/compiler/rustc_middle/src/traits/solve.rs
@@ -3,8 +3,7 @@ use std::ops::ControlFlow;
 use rustc_data_structures::intern::Interned;
 
 use crate::ty::{
-    ir::{self, TypeFoldable, TypeVisitable},
-    FallibleTypeFolder, Ty, TyCtxt, TypeFolder, TypeVisitor,
+    FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor,
 };
 
 #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
@@ -27,21 +26,22 @@ pub struct ExternalConstraintsData<'tcx> {
 }
 
 impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
-        Ok(ir::FallibleTypeFolder::interner(folder).intern_external_constraints(
-            ExternalConstraintsData {
-                regions: (),
-                opaque_types: self
-                    .opaque_types
-                    .iter()
-                    .map(|opaque| opaque.try_fold_with(folder))
-                    .collect::<Result<_, F::Error>>()?,
-            },
-        ))
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        folder: &mut F,
+    ) -> Result<Self, F::Error> {
+        Ok(FallibleTypeFolder::interner(folder).mk_external_constraints(ExternalConstraintsData {
+            regions: (),
+            opaque_types: self
+                .opaque_types
+                .iter()
+                .map(|opaque| opaque.try_fold_with(folder))
+                .collect::<Result<_, F::Error>>()?,
+        }))
     }
 
-    fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
-        ir::TypeFolder::interner(folder).intern_external_constraints(ExternalConstraintsData {
+    fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
+        TypeFolder::interner(folder).mk_external_constraints(ExternalConstraintsData {
             regions: (),
             opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(),
         })
@@ -49,7 +49,7 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
 }
 
 impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
-    fn visit_with<V: TypeVisitor<'tcx>>(
+    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
         &self,
         visitor: &mut V,
     ) -> std::ops::ControlFlow<V::BreakTy> {
diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs
index 4019cf8ceee..c016f722750 100644
--- a/compiler/rustc_middle/src/traits/specialization_graph.rs
+++ b/compiler/rustc_middle/src/traits/specialization_graph.rs
@@ -1,6 +1,6 @@
 use crate::error::StrictCoherenceNeedsNegativeCoherence;
 use crate::ty::fast_reject::SimplifiedType;
-use crate::ty::visit::TypeVisitable;
+use crate::ty::visit::TypeVisitableExt;
 use crate::ty::{self, TyCtxt};
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::ErrorGuaranteed;
diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs
index b9c5a4e0d0d..df9aa765dc1 100644
--- a/compiler/rustc_middle/src/ty/_match.rs
+++ b/compiler/rustc_middle/src/ty/_match.rs
@@ -89,9 +89,7 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
                 Err(TypeError::Sorts(relate::expected_found(self, a, b)))
             }
 
-            (&ty::Error(guar), _) | (_, &ty::Error(guar)) => {
-                Ok(self.tcx().ty_error_with_guaranteed(guar))
-            }
+            (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(self.tcx().ty_error(guar)),
 
             _ => relate::super_relate_tys(self, a, b),
         }
diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs
index b7f0a0be75e..f889ce82706 100644
--- a/compiler/rustc_middle/src/ty/abstract_const.rs
+++ b/compiler/rustc_middle/src/ty/abstract_const.rs
@@ -1,6 +1,7 @@
 //! A subset of a mir body used for const evaluatability checking.
 use crate::ty::{
-    self, ir::TypeFolder, Const, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable,
+    self, Const, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
+    TypeVisitableExt,
 };
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def_id::DefId;
@@ -47,7 +48,7 @@ impl<'tcx> TyCtxt<'tcx> {
         Ok(ac?.map(|ac| EarlyBinder(ac)))
     }
 
-    pub fn expand_abstract_consts<T: TypeFoldable<'tcx>>(self, ac: T) -> T {
+    pub fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, ac: T) -> T {
         struct Expander<'tcx> {
             tcx: TyCtxt<'tcx>,
         }
diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs
index f127b6275a2..ec21030b302 100644
--- a/compiler/rustc_middle/src/ty/adt.rs
+++ b/compiler/rustc_middle/src/ty/adt.rs
@@ -54,7 +54,7 @@ bitflags! {
 
 /// The definition of a user-defined type, e.g., a `struct`, `enum`, or `union`.
 ///
-/// These are all interned (by `alloc_adt_def`) into the global arena.
+/// These are all interned (by `mk_adt_def`) into the global arena.
 ///
 /// The initialism *ADT* stands for an [*algebraic data type (ADT)*][adt].
 /// This is slightly wrong because `union`s are not ADTs.
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index b9a1e23879c..3ce80e06ad9 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -207,7 +207,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for Ty<'tcx> {
             })
         } else {
             let tcx = decoder.interner();
-            tcx.mk_ty(rustc_type_ir::TyKind::decode(decoder))
+            tcx.mk_ty_from_kind(rustc_type_ir::TyKind::decode(decoder))
         }
     }
 }
@@ -244,7 +244,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for SubstsRef<'tcx> {
     fn decode(decoder: &mut D) -> Self {
         let len = decoder.read_usize();
         let tcx = decoder.interner();
-        tcx.mk_substs(
+        tcx.mk_substs_from_iter(
             (0..len).map::<ty::subst::GenericArg<'tcx>, _>(|_| Decodable::decode(decoder)),
         )
     }
@@ -254,7 +254,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for mir::Place<'tcx> {
     fn decode(decoder: &mut D) -> Self {
         let local: mir::Local = Decodable::decode(decoder);
         let len = decoder.read_usize();
-        let projection = decoder.interner().mk_place_elems(
+        let projection = decoder.interner().mk_place_elems_from_iter(
             (0..len).map::<mir::PlaceElem<'tcx>, _>(|_| Decodable::decode(decoder)),
         );
         mir::Place { local, projection }
@@ -263,16 +263,16 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for mir::Place<'tcx> {
 
 impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Region<'tcx> {
     fn decode(decoder: &mut D) -> Self {
-        decoder.interner().mk_region(Decodable::decode(decoder))
+        decoder.interner().mk_region_from_kind(Decodable::decode(decoder))
     }
 }
 
 impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for CanonicalVarInfos<'tcx> {
     fn decode(decoder: &mut D) -> Self {
         let len = decoder.read_usize();
-        let interned: Vec<CanonicalVarInfo<'tcx>> =
-            (0..len).map(|_| Decodable::decode(decoder)).collect();
-        decoder.interner().intern_canonical_var_infos(interned.as_slice())
+        decoder.interner().mk_canonical_var_infos_from_iter(
+            (0..len).map::<CanonicalVarInfo<'tcx>, _>(|_| Decodable::decode(decoder)),
+        )
     }
 }
 
@@ -310,7 +310,9 @@ macro_rules! impl_decodable_via_ref {
 impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<Ty<'tcx>> {
     fn decode(decoder: &mut D) -> &'tcx Self {
         let len = decoder.read_usize();
-        decoder.interner().mk_type_list((0..len).map::<Ty<'tcx>, _>(|_| Decodable::decode(decoder)))
+        decoder
+            .interner()
+            .mk_type_list_from_iter((0..len).map::<Ty<'tcx>, _>(|_| Decodable::decode(decoder)))
     }
 }
 
@@ -319,7 +321,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
 {
     fn decode(decoder: &mut D) -> &'tcx Self {
         let len = decoder.read_usize();
-        decoder.interner().mk_poly_existential_predicates(
+        decoder.interner().mk_poly_existential_predicates_from_iter(
             (0..len).map::<ty::Binder<'tcx, _>, _>(|_| Decodable::decode(decoder)),
         )
     }
@@ -342,13 +344,13 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for [ty::ValTre
 
 impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ConstAllocation<'tcx> {
     fn decode(decoder: &mut D) -> Self {
-        decoder.interner().intern_const_alloc(Decodable::decode(decoder))
+        decoder.interner().mk_const_alloc(Decodable::decode(decoder))
     }
 }
 
 impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for AdtDef<'tcx> {
     fn decode(decoder: &mut D) -> Self {
-        decoder.interner().intern_adt_def(Decodable::decode(decoder))
+        decoder.interner().mk_adt_def_from_data(Decodable::decode(decoder))
     }
 }
 
@@ -375,7 +377,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
 {
     fn decode(decoder: &mut D) -> &'tcx Self {
         let len = decoder.read_usize();
-        decoder.interner().mk_bound_variable_kinds(
+        decoder.interner().mk_bound_variable_kinds_from_iter(
             (0..len).map::<ty::BoundVariableKind, _>(|_| Decodable::decode(decoder)),
         )
     }
@@ -384,18 +386,18 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
 impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<ty::Const<'tcx>> {
     fn decode(decoder: &mut D) -> &'tcx Self {
         let len = decoder.read_usize();
-        decoder
-            .interner()
-            .mk_const_list((0..len).map::<ty::Const<'tcx>, _>(|_| Decodable::decode(decoder)))
+        decoder.interner().mk_const_list_from_iter(
+            (0..len).map::<ty::Const<'tcx>, _>(|_| Decodable::decode(decoder)),
+        )
     }
 }
 
 impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<ty::Predicate<'tcx>> {
     fn decode(decoder: &mut D) -> &'tcx Self {
         let len = decoder.read_usize();
-        let predicates: Vec<_> =
-            (0..len).map::<ty::Predicate<'tcx>, _>(|_| Decodable::decode(decoder)).collect();
-        decoder.interner().intern_predicates(&predicates)
+        decoder.interner().mk_predicates_from_iter(
+            (0..len).map::<ty::Predicate<'tcx>, _>(|_| Decodable::decode(decoder)),
+        )
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index 52f4414e37b..560caa041a7 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -4,7 +4,7 @@ use crate::mir::interpret::{AllocId, ConstValue, Scalar};
 use crate::ty::abstract_const::CastKind;
 use crate::ty::subst::{InternalSubsts, SubstsRef};
 use crate::ty::ParamEnv;
-use crate::ty::{self, List, Ty, TyCtxt, TypeVisitable};
+use crate::ty::{self, List, Ty, TyCtxt, TypeVisitableExt};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def_id::DefId;
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index cf4836ded47..433c9ab9aa2 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -6,7 +6,7 @@ pub mod tls;
 
 use crate::arena::Arena;
 use crate::dep_graph::{DepGraph, DepKindStruct};
-use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos};
+use crate::infer::canonical::CanonicalVarInfo;
 use crate::lint::struct_lint_level;
 use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
 use crate::middle::resolve_bound_vars;
@@ -177,7 +177,7 @@ impl<'tcx> CtxtInterners<'tcx> {
         }
     }
 
-    /// Interns a type.
+    /// Interns a type. (Use `mk_*` functions instead, where possible.)
     #[allow(rustc::usage_of_ty_tykind)]
     #[inline(never)]
     fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> {
@@ -217,6 +217,7 @@ impl<'tcx> CtxtInterners<'tcx> {
         }
     }
 
+    /// Interns a predicate. (Use `mk_predicate` instead, where possible.)
     #[inline(never)]
     fn intern_predicate(
         &self,
@@ -615,21 +616,21 @@ impl<'tcx> TyCtxt<'tcx> {
         self.arena.alloc(Steal::new(promoted))
     }
 
-    pub fn alloc_adt_def(
+    pub fn mk_adt_def(
         self,
         did: DefId,
         kind: AdtKind,
         variants: IndexVec<VariantIdx, ty::VariantDef>,
         repr: ReprOptions,
     ) -> ty::AdtDef<'tcx> {
-        self.intern_adt_def(ty::AdtDefData::new(self, did, kind, variants, repr))
+        self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
     }
 
     /// Allocates a read-only byte or string literal for `mir::interpret`.
     pub fn allocate_bytes(self, bytes: &[u8]) -> interpret::AllocId {
         // Create an allocation that just contains these bytes.
         let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes);
-        let alloc = self.intern_const_alloc(alloc);
+        let alloc = self.mk_const_alloc(alloc);
         self.create_memory_alloc(alloc)
     }
 
@@ -718,13 +719,13 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Constructs a `TyKind::Error` type with current `ErrorGuaranteed`
     #[track_caller]
-    pub fn ty_error_with_guaranteed(self, reported: ErrorGuaranteed) -> Ty<'tcx> {
-        self.mk_ty(Error(reported))
+    pub fn ty_error(self, reported: ErrorGuaranteed) -> Ty<'tcx> {
+        self.mk_ty_from_kind(Error(reported))
     }
 
     /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used.
     #[track_caller]
-    pub fn ty_error(self) -> Ty<'tcx> {
+    pub fn ty_error_misc(self) -> Ty<'tcx> {
         self.ty_error_with_message(DUMMY_SP, "TyKind::Error constructed but no error reported")
     }
 
@@ -733,7 +734,7 @@ impl<'tcx> TyCtxt<'tcx> {
     #[track_caller]
     pub fn ty_error_with_message<S: Into<MultiSpan>>(self, span: S, msg: &str) -> Ty<'tcx> {
         let reported = self.sess.delay_span_bug(span, msg);
-        self.mk_ty(Error(reported))
+        self.mk_ty_from_kind(Error(reported))
     }
 
     /// Constructs a `RegionKind::ReError` lifetime.
@@ -1011,6 +1012,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Note that this is *untracked* and should only be used within the query
     /// system if the result is otherwise tracked through queries
+    #[inline]
     pub fn cstore_untracked(self) -> MappedReadGuard<'tcx, CrateStoreDyn> {
         ReadGuard::map(self.untracked.cstore.read(), |c| &**c)
     }
@@ -1030,7 +1032,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// system if the result is otherwise tracked through queries
     #[inline]
     pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
-        self.untracked.source_span.read().get(def_id).copied().unwrap_or(DUMMY_SP)
+        self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
     }
 
     #[inline(always)]
@@ -1194,19 +1196,14 @@ impl<'tcx> TyCtxt<'tcx> {
         self.mk_imm_ref(
             self.lifetimes.re_static,
             self.type_of(self.require_lang_item(LangItem::PanicLocation, None))
-                .subst(self, self.intern_substs(&[self.lifetimes.re_static.into()])),
+                .subst(self, self.mk_substs(&[self.lifetimes.re_static.into()])),
         )
     }
 
     /// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`).
     pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
-        match self.def_kind(def_id) {
-            DefKind::Generator => match self.generator_kind(def_id).unwrap() {
-                rustc_hir::GeneratorKind::Async(..) => ("an", "async closure"),
-                rustc_hir::GeneratorKind::Gen => ("a", "generator"),
-            },
-            def_kind => (def_kind.article(), def_kind.descr(def_id)),
-        }
+        let kind = self.def_kind(def_id);
+        (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
     }
 
     pub fn type_length_limit(self) -> Limit {
@@ -1281,7 +1278,7 @@ macro_rules! nop_lift {
 
 // Can't use the macros as we have reuse the `substs` here.
 //
-// See `intern_type_list` for more info.
+// See `mk_type_list` for more info.
 impl<'a, 'tcx> Lift<'tcx> for &'a List<Ty<'a>> {
     type Lifted = &'tcx List<Ty<'tcx>>;
     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
@@ -1522,7 +1519,7 @@ impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
 }
 
 macro_rules! direct_interners {
-    ($($name:ident: $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
+    ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
         $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
             fn borrow<'a>(&'a self) -> &'a $ty {
                 &self.0
@@ -1548,7 +1545,7 @@ macro_rules! direct_interners {
         }
 
         impl<'tcx> TyCtxt<'tcx> {
-            pub fn $method(self, v: $ty) -> $ret_ty {
+            $vis fn $method(self, v: $ty) -> $ret_ty {
                 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
                     InternedInSet(self.interners.arena.alloc(v))
                 }).0))
@@ -1557,37 +1554,47 @@ macro_rules! direct_interners {
     }
 }
 
+// Functions with a `mk_` prefix are intended for use outside this file and
+// crate. Functions with an `intern_` prefix are intended for use within this
+// file only, and have a corresponding `mk_` function.
 direct_interners! {
     region: intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
-    const_: mk_const_internal(ConstData<'tcx>): Const -> Const<'tcx>,
-    const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
-    layout: intern_layout(LayoutS): Layout -> Layout<'tcx>,
-    adt_def: intern_adt_def(AdtDefData): AdtDef -> AdtDef<'tcx>,
-    external_constraints: intern_external_constraints(ExternalConstraintsData<'tcx>): ExternalConstraints -> ExternalConstraints<'tcx>,
+    const_: intern_const(ConstData<'tcx>): Const -> Const<'tcx>,
+    const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
+    layout: pub mk_layout(LayoutS): Layout -> Layout<'tcx>,
+    adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
+    external_constraints: pub mk_external_constraints(ExternalConstraintsData<'tcx>):
+        ExternalConstraints -> ExternalConstraints<'tcx>,
 }
 
 macro_rules! slice_interners {
-    ($($field:ident: $method:ident($ty:ty)),+ $(,)?) => (
+    ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
         impl<'tcx> TyCtxt<'tcx> {
-            $(pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
-                self.interners.$field.intern_ref(v, || {
-                    InternedInSet(List::from_arena(&*self.arena, v))
-                }).0
+            $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
+                if v.is_empty() {
+                    List::empty()
+                } else {
+                    self.interners.$field.intern_ref(v, || {
+                        InternedInSet(List::from_arena(&*self.arena, v))
+                    }).0
+                }
             })+
         }
     );
 }
 
+// These functions intern slices. They all have a corresponding
+// `mk_foo_from_iter` function that interns an iterator. The slice version
+// should be used when possible, because it's faster.
 slice_interners!(
-    const_lists: _intern_const_list(Const<'tcx>),
-    substs: _intern_substs(GenericArg<'tcx>),
-    canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo<'tcx>),
-    poly_existential_predicates:
-        _intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
-    predicates: _intern_predicates(Predicate<'tcx>),
-    projs: _intern_projs(ProjectionKind),
-    place_elems: _intern_place_elems(PlaceElem<'tcx>),
-    bound_variable_kinds: _intern_bound_variable_kinds(ty::BoundVariableKind),
+    const_lists: pub mk_const_list(Const<'tcx>),
+    substs: pub mk_substs(GenericArg<'tcx>),
+    canonical_var_infos: pub mk_canonical_var_infos(CanonicalVarInfo<'tcx>),
+    poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
+    predicates: intern_predicates(Predicate<'tcx>),
+    projs: pub mk_projs(ProjectionKind),
+    place_elems: pub mk_place_elems(PlaceElem<'tcx>),
+    bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
 );
 
 impl<'tcx> TyCtxt<'tcx> {
@@ -1675,7 +1682,7 @@ impl<'tcx> TyCtxt<'tcx> {
     // Avoid this in favour of more specific `mk_*` methods, where possible.
     #[allow(rustc::usage_of_ty_tykind)]
     #[inline]
-    pub fn mk_ty(self, st: TyKind<'tcx>) -> Ty<'tcx> {
+    pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
         self.interners.intern_ty(
             st,
             self.sess,
@@ -1740,12 +1747,12 @@ impl<'tcx> TyCtxt<'tcx> {
     #[inline]
     pub fn mk_adt(self, def: AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
         // Take a copy of substs so that we own the vectors inside.
-        self.mk_ty(Adt(def, substs))
+        self.mk_ty_from_kind(Adt(def, substs))
     }
 
     #[inline]
     pub fn mk_foreign(self, def_id: DefId) -> Ty<'tcx> {
-        self.mk_ty(Foreign(def_id))
+        self.mk_ty_from_kind(Foreign(def_id))
     }
 
     fn mk_generic_adt(self, wrapper_def_id: DefId, ty_param: Ty<'tcx>) -> Ty<'tcx> {
@@ -1762,7 +1769,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     }
                 }
             });
-        self.mk_ty(Adt(adt_def, substs))
+        self.mk_ty_from_kind(Adt(adt_def, substs))
     }
 
     #[inline]
@@ -1791,12 +1798,12 @@ impl<'tcx> TyCtxt<'tcx> {
 
     #[inline]
     pub fn mk_ptr(self, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(RawPtr(tm))
+        self.mk_ty_from_kind(RawPtr(tm))
     }
 
     #[inline]
     pub fn mk_ref(self, r: Region<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(Ref(r, tm.ty, tm.mutbl))
+        self.mk_ty_from_kind(Ref(r, tm.ty, tm.mutbl))
     }
 
     #[inline]
@@ -1821,30 +1828,34 @@ impl<'tcx> TyCtxt<'tcx> {
 
     #[inline]
     pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
-        self.mk_ty(Array(ty, ty::Const::from_target_usize(self, n)))
+        self.mk_ty_from_kind(Array(ty, ty::Const::from_target_usize(self, n)))
     }
 
     #[inline]
     pub fn mk_array_with_const_len(self, ty: Ty<'tcx>, ct: Const<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(Array(ty, ct))
+        self.mk_ty_from_kind(Array(ty, ct))
     }
 
     #[inline]
     pub fn mk_slice(self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(Slice(ty))
+        self.mk_ty_from_kind(Slice(ty))
     }
 
     #[inline]
-    pub fn intern_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
-        if ts.is_empty() { self.types.unit } else { self.mk_ty(Tuple(self.intern_type_list(&ts))) }
+    pub fn mk_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
+        if ts.is_empty() {
+            self.types.unit
+        } else {
+            self.mk_ty_from_kind(Tuple(self.mk_type_list(&ts)))
+        }
     }
 
-    pub fn mk_tup<I, T>(self, iter: I) -> T::Output
+    pub fn mk_tup_from_iter<I, T>(self, iter: I) -> T::Output
     where
         I: Iterator<Item = T>,
         T: CollectAndApply<Ty<'tcx>, Ty<'tcx>>,
     {
-        T::collect_and_apply(iter, |ts| self.intern_tup(ts))
+        T::collect_and_apply(iter, |ts| self.mk_tup(ts))
     }
 
     #[inline]
@@ -1861,17 +1872,17 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn mk_fn_def(
         self,
         def_id: DefId,
-        substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
+        substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
     ) -> Ty<'tcx> {
-        let substs = self.check_substs(def_id, substs);
-        self.mk_ty(FnDef(def_id, substs))
+        let substs = self.check_and_mk_substs(def_id, substs);
+        self.mk_ty_from_kind(FnDef(def_id, substs))
     }
 
     #[inline(always)]
-    fn check_substs(
+    fn check_and_mk_substs(
         self,
         _def_id: DefId,
-        substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
+        substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
     ) -> SubstsRef<'tcx> {
         let substs = substs.into_iter().map(Into::into);
         #[cfg(debug_assertions)]
@@ -1884,12 +1895,12 @@ impl<'tcx> TyCtxt<'tcx> {
                 substs.collect::<Vec<_>>(),
             );
         }
-        self.mk_substs(substs)
+        self.mk_substs_from_iter(substs)
     }
 
     #[inline]
     pub fn mk_fn_ptr(self, fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(FnPtr(fty))
+        self.mk_ty_from_kind(FnPtr(fty))
     }
 
     #[inline]
@@ -1899,21 +1910,21 @@ impl<'tcx> TyCtxt<'tcx> {
         reg: ty::Region<'tcx>,
         repr: DynKind,
     ) -> Ty<'tcx> {
-        self.mk_ty(Dynamic(obj, reg, repr))
+        self.mk_ty_from_kind(Dynamic(obj, reg, repr))
     }
 
     #[inline]
     pub fn mk_projection(
         self,
         item_def_id: DefId,
-        substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
+        substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
     ) -> Ty<'tcx> {
         self.mk_alias(ty::Projection, self.mk_alias_ty(item_def_id, substs))
     }
 
     #[inline]
     pub fn mk_closure(self, closure_id: DefId, closure_substs: SubstsRef<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(Closure(closure_id, closure_substs))
+        self.mk_ty_from_kind(Closure(closure_id, closure_substs))
     }
 
     #[inline]
@@ -1923,47 +1934,51 @@ impl<'tcx> TyCtxt<'tcx> {
         generator_substs: SubstsRef<'tcx>,
         movability: hir::Movability,
     ) -> Ty<'tcx> {
-        self.mk_ty(Generator(id, generator_substs, movability))
+        self.mk_ty_from_kind(Generator(id, generator_substs, movability))
     }
 
     #[inline]
     pub fn mk_generator_witness(self, types: ty::Binder<'tcx, &'tcx List<Ty<'tcx>>>) -> Ty<'tcx> {
-        self.mk_ty(GeneratorWitness(types))
+        self.mk_ty_from_kind(GeneratorWitness(types))
     }
 
     /// Creates a `&mut Context<'_>` [`Ty`] with erased lifetimes.
     pub fn mk_task_context(self) -> Ty<'tcx> {
         let context_did = self.require_lang_item(LangItem::Context, None);
         let context_adt_ref = self.adt_def(context_did);
-        let context_substs = self.intern_substs(&[self.lifetimes.re_erased.into()]);
+        let context_substs = self.mk_substs(&[self.lifetimes.re_erased.into()]);
         let context_ty = self.mk_adt(context_adt_ref, context_substs);
         self.mk_mut_ref(self.lifetimes.re_erased, context_ty)
     }
 
     #[inline]
     pub fn mk_generator_witness_mir(self, id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(GeneratorWitnessMIR(id, substs))
+        self.mk_ty_from_kind(GeneratorWitnessMIR(id, substs))
     }
 
     #[inline]
     pub fn mk_const(self, kind: impl Into<ty::ConstKind<'tcx>>, ty: Ty<'tcx>) -> Const<'tcx> {
-        self.mk_const_internal(ty::ConstData { kind: kind.into(), ty })
+        self.intern_const(ty::ConstData { kind: kind.into(), ty })
     }
 
     #[inline]
     pub fn mk_ty_var(self, v: TyVid) -> Ty<'tcx> {
         // Use a pre-interned one when possible.
-        self.types.ty_vars.get(v.as_usize()).copied().unwrap_or_else(|| self.mk_ty(Infer(TyVar(v))))
+        self.types
+            .ty_vars
+            .get(v.as_usize())
+            .copied()
+            .unwrap_or_else(|| self.mk_ty_from_kind(Infer(TyVar(v))))
     }
 
     #[inline]
     pub fn mk_int_var(self, v: IntVid) -> Ty<'tcx> {
-        self.mk_ty(Infer(IntVar(v)))
+        self.mk_ty_from_kind(Infer(IntVar(v)))
     }
 
     #[inline]
     pub fn mk_float_var(self, v: FloatVid) -> Ty<'tcx> {
-        self.mk_ty(Infer(FloatVar(v)))
+        self.mk_ty_from_kind(Infer(FloatVar(v)))
     }
 
     #[inline]
@@ -1973,7 +1988,7 @@ impl<'tcx> TyCtxt<'tcx> {
             .fresh_tys
             .get(n as usize)
             .copied()
-            .unwrap_or_else(|| self.mk_ty(Infer(ty::FreshTy(n))))
+            .unwrap_or_else(|| self.mk_ty_from_kind(Infer(ty::FreshTy(n))))
     }
 
     #[inline]
@@ -1983,7 +1998,7 @@ impl<'tcx> TyCtxt<'tcx> {
             .fresh_int_tys
             .get(n as usize)
             .copied()
-            .unwrap_or_else(|| self.mk_ty(Infer(ty::FreshIntTy(n))))
+            .unwrap_or_else(|| self.mk_ty_from_kind(Infer(ty::FreshIntTy(n))))
     }
 
     #[inline]
@@ -1993,12 +2008,12 @@ impl<'tcx> TyCtxt<'tcx> {
             .fresh_float_tys
             .get(n as usize)
             .copied()
-            .unwrap_or_else(|| self.mk_ty(Infer(ty::FreshFloatTy(n))))
+            .unwrap_or_else(|| self.mk_ty_from_kind(Infer(ty::FreshFloatTy(n))))
     }
 
     #[inline]
     pub fn mk_ty_param(self, index: u32, name: Symbol) -> Ty<'tcx> {
-        self.mk_ty(Param(ParamTy { index, name }))
+        self.mk_ty_from_kind(Param(ParamTy { index, name }))
     }
 
     pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
@@ -2020,17 +2035,17 @@ impl<'tcx> TyCtxt<'tcx> {
 
     #[inline]
     pub fn mk_bound(self, index: ty::DebruijnIndex, bound_ty: ty::BoundTy) -> Ty<'tcx> {
-        self.mk_ty(Bound(index, bound_ty))
+        self.mk_ty_from_kind(Bound(index, bound_ty))
     }
 
     #[inline]
     pub fn mk_placeholder(self, placeholder: ty::PlaceholderType) -> Ty<'tcx> {
-        self.mk_ty(Placeholder(placeholder))
+        self.mk_ty_from_kind(Placeholder(placeholder))
     }
 
     #[inline]
     pub fn mk_alias(self, kind: ty::AliasKind, alias_ty: ty::AliasTy<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(Alias(kind, alias_ty))
+        self.mk_ty_from_kind(Alias(kind, alias_ty))
     }
 
     #[inline]
@@ -2083,7 +2098,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     // Avoid this in favour of more specific `mk_re_*` methods, where possible,
     // to avoid the cost of the `match`.
-    pub fn mk_region(self, kind: ty::RegionKind<'tcx>) -> Region<'tcx> {
+    pub fn mk_region_from_kind(self, kind: ty::RegionKind<'tcx>) -> Region<'tcx> {
         match kind {
             ty::ReEarlyBound(region) => self.mk_re_early_bound(region),
             ty::ReLateBound(debruijn, region) => self.mk_re_late_bound(debruijn, region),
@@ -2137,10 +2152,10 @@ impl<'tcx> TyCtxt<'tcx> {
         let mut projection = place.projection.to_vec();
         projection.push(elem);
 
-        Place { local: place.local, projection: self.intern_place_elems(&projection) }
+        Place { local: place.local, projection: self.mk_place_elems(&projection) }
     }
 
-    pub fn intern_poly_existential_predicates(
+    pub fn mk_poly_existential_predicates(
         self,
         eps: &[PolyExistentialPredicate<'tcx>],
     ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
@@ -2150,80 +2165,40 @@ impl<'tcx> TyCtxt<'tcx> {
                 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
                     != Ordering::Greater)
         );
-        self._intern_poly_existential_predicates(eps)
+        self.intern_poly_existential_predicates(eps)
     }
 
-    pub fn intern_predicates(self, preds: &[Predicate<'tcx>]) -> &'tcx List<Predicate<'tcx>> {
+    pub fn mk_predicates(self, preds: &[Predicate<'tcx>]) -> &'tcx List<Predicate<'tcx>> {
         // FIXME consider asking the input slice to be sorted to avoid
         // re-interning permutations, in which case that would be asserted
         // here.
-        if preds.is_empty() {
-            // The macro-generated method below asserts we don't intern an empty slice.
-            List::empty()
-        } else {
-            self._intern_predicates(preds)
-        }
+        self.intern_predicates(preds)
     }
 
-    pub fn mk_const_list<I, T>(self, iter: I) -> T::Output
+    pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
     where
         I: Iterator<Item = T>,
         T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
     {
-        T::collect_and_apply(iter, |xs| self.intern_const_list(xs))
-    }
-
-    pub fn intern_const_list(self, cs: &[ty::Const<'tcx>]) -> &'tcx List<ty::Const<'tcx>> {
-        if cs.is_empty() { List::empty() } else { self._intern_const_list(cs) }
-    }
-
-    pub fn intern_type_list(self, ts: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> {
-        if ts.is_empty() {
-            List::empty()
-        } else {
-            // Actually intern type lists as lists of `GenericArg`s.
-            //
-            // Transmuting from `Ty<'tcx>` to `GenericArg<'tcx>` is sound
-            // as explained in ty_slice_as_generic_arg`. With this,
-            // we guarantee that even when transmuting between `List<Ty<'tcx>>`
-            // and `List<GenericArg<'tcx>>`, the uniqueness requirement for
-            // lists is upheld.
-            let substs = self._intern_substs(ty::subst::ty_slice_as_generic_args(ts));
-            substs.try_as_type_list().unwrap()
-        }
+        T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
     }
 
-    pub fn intern_substs(self, ts: &[GenericArg<'tcx>]) -> &'tcx List<GenericArg<'tcx>> {
-        if ts.is_empty() { List::empty() } else { self._intern_substs(ts) }
-    }
-
-    pub fn intern_projs(self, ps: &[ProjectionKind]) -> &'tcx List<ProjectionKind> {
-        if ps.is_empty() { List::empty() } else { self._intern_projs(ps) }
-    }
-
-    pub fn intern_place_elems(self, ts: &[PlaceElem<'tcx>]) -> &'tcx List<PlaceElem<'tcx>> {
-        if ts.is_empty() { List::empty() } else { self._intern_place_elems(ts) }
-    }
-
-    pub fn intern_canonical_var_infos(
-        self,
-        ts: &[CanonicalVarInfo<'tcx>],
-    ) -> CanonicalVarInfos<'tcx> {
-        if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) }
-    }
-
-    pub fn intern_bound_variable_kinds(
-        self,
-        ts: &[ty::BoundVariableKind],
-    ) -> &'tcx List<ty::BoundVariableKind> {
-        if ts.is_empty() { List::empty() } else { self._intern_bound_variable_kinds(ts) }
-    }
-
-    // Unlike various other `mk_*` functions, this one uses `I: IntoIterator`
-    // instead of `I: Iterator`. Unlike those other functions, this one doesn't
-    // have a `intern_fn_sig` variant that can be used for cases where `I` is
-    // something like a `Vec`. That's because of the need to combine `inputs`
-    // and `output`.
+    pub fn mk_type_list(self, ts: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> {
+        // Actually intern type lists as lists of `GenericArg`s.
+        //
+        // Transmuting from `Ty<'tcx>` to `GenericArg<'tcx>` is sound
+        // as explained in ty_slice_as_generic_arg`. With this,
+        // we guarantee that even when transmuting between `List<Ty<'tcx>>`
+        // and `List<GenericArg<'tcx>>`, the uniqueness requirement for
+        // lists is upheld.
+        let substs = self.mk_substs(ty::subst::ty_slice_as_generic_args(ts));
+        substs.try_as_type_list().unwrap()
+    }
+
+    // Unlike various other `mk_*_from_iter` functions, this one uses `I:
+    // IntoIterator` instead of `I: Iterator`, and it doesn't have a slice
+    // variant, because of the need to combine `inputs` and `output`. This
+    // explains the lack of `_from_iter` suffix.
     pub fn mk_fn_sig<I, T>(
         self,
         inputs: I,
@@ -2237,14 +2212,14 @@ impl<'tcx> TyCtxt<'tcx> {
         T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
     {
         T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
-            inputs_and_output: self.intern_type_list(xs),
+            inputs_and_output: self.mk_type_list(xs),
             c_variadic,
             unsafety,
             abi,
         })
     }
 
-    pub fn mk_poly_existential_predicates<I, T>(self, iter: I) -> T::Output
+    pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
     where
         I: Iterator<Item = T>,
         T: CollectAndApply<
@@ -2252,39 +2227,47 @@ impl<'tcx> TyCtxt<'tcx> {
                 &'tcx List<PolyExistentialPredicate<'tcx>>,
             >,
     {
-        T::collect_and_apply(iter, |xs| self.intern_poly_existential_predicates(xs))
+        T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
     }
 
-    pub fn mk_predicates<I, T>(self, iter: I) -> T::Output
+    pub fn mk_predicates_from_iter<I, T>(self, iter: I) -> T::Output
     where
         I: Iterator<Item = T>,
         T: CollectAndApply<Predicate<'tcx>, &'tcx List<Predicate<'tcx>>>,
     {
-        T::collect_and_apply(iter, |xs| self.intern_predicates(xs))
+        T::collect_and_apply(iter, |xs| self.mk_predicates(xs))
     }
 
-    pub fn mk_type_list<I, T>(self, iter: I) -> T::Output
+    pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
     where
         I: Iterator<Item = T>,
         T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
     {
-        T::collect_and_apply(iter, |xs| self.intern_type_list(xs))
+        T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
     }
 
-    pub fn mk_substs<I, T>(self, iter: I) -> T::Output
+    pub fn mk_substs_from_iter<I, T>(self, iter: I) -> T::Output
     where
         I: Iterator<Item = T>,
         T: CollectAndApply<GenericArg<'tcx>, &'tcx List<GenericArg<'tcx>>>,
     {
-        T::collect_and_apply(iter, |xs| self.intern_substs(xs))
+        T::collect_and_apply(iter, |xs| self.mk_substs(xs))
     }
 
-    pub fn mk_place_elems<I, T>(self, iter: I) -> T::Output
+    pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
+    where
+        I: Iterator<Item = T>,
+        T: CollectAndApply<CanonicalVarInfo<'tcx>, &'tcx List<CanonicalVarInfo<'tcx>>>,
+    {
+        T::collect_and_apply(iter, |xs| self.mk_canonical_var_infos(xs))
+    }
+
+    pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
     where
         I: Iterator<Item = T>,
         T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
     {
-        T::collect_and_apply(iter, |xs| self.intern_place_elems(xs))
+        T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
     }
 
     pub fn mk_substs_trait(
@@ -2292,33 +2275,33 @@ impl<'tcx> TyCtxt<'tcx> {
         self_ty: Ty<'tcx>,
         rest: impl IntoIterator<Item = GenericArg<'tcx>>,
     ) -> SubstsRef<'tcx> {
-        self.mk_substs(iter::once(self_ty.into()).chain(rest))
+        self.mk_substs_from_iter(iter::once(self_ty.into()).chain(rest))
     }
 
     pub fn mk_trait_ref(
         self,
         trait_def_id: DefId,
-        substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
+        substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
     ) -> ty::TraitRef<'tcx> {
-        let substs = self.check_substs(trait_def_id, substs);
+        let substs = self.check_and_mk_substs(trait_def_id, substs);
         ty::TraitRef { def_id: trait_def_id, substs, _use_mk_trait_ref_instead: () }
     }
 
     pub fn mk_alias_ty(
         self,
         def_id: DefId,
-        substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
+        substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
     ) -> ty::AliasTy<'tcx> {
-        let substs = self.check_substs(def_id, substs);
+        let substs = self.check_and_mk_substs(def_id, substs);
         ty::AliasTy { def_id, substs, _use_mk_alias_ty_instead: () }
     }
 
-    pub fn mk_bound_variable_kinds<I, T>(self, iter: I) -> T::Output
+    pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
     where
         I: Iterator<Item = T>,
         T: CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
     {
-        T::collect_and_apply(iter, |xs| self.intern_bound_variable_kinds(xs))
+        T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
     }
 
     /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`,
@@ -2403,7 +2386,7 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
-        self.intern_bound_variable_kinds(
+        self.mk_bound_variable_kinds(
             &self
                 .late_bound_vars_map(id.owner)
                 .and_then(|map| map.get(&id.local_id).cloned())
@@ -2451,6 +2434,10 @@ impl<'tcx> TyCtxt<'tcx> {
         )
     }
 
+    pub fn local_def_id_to_hir_id(self, local_def_id: LocalDefId) -> HirId {
+        self.opt_local_def_id_to_hir_id(local_def_id).unwrap()
+    }
+
     pub fn trait_solver_next(self) -> bool {
         self.sess.opts.unstable_opts.trait_solver == rustc_session::config::TraitSolver::Next
     }
@@ -2459,7 +2446,7 @@ impl<'tcx> TyCtxt<'tcx> {
 impl<'tcx> TyCtxtAt<'tcx> {
     /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used.
     #[track_caller]
-    pub fn ty_error(self) -> Ty<'tcx> {
+    pub fn ty_error_misc(self) -> Ty<'tcx> {
         self.tcx.ty_error_with_message(self.span, "TyKind::Error constructed but no error reported")
     }
 
@@ -2473,7 +2460,7 @@ impl<'tcx> TyCtxtAt<'tcx> {
     pub fn mk_trait_ref(
         self,
         trait_lang_item: LangItem,
-        substs: impl IntoIterator<Item = impl Into<ty::GenericArg<'tcx>>>,
+        substs: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>,
     ) -> ty::TraitRef<'tcx> {
         let trait_def_id = self.require_lang_item(trait_lang_item, Some(self.span));
         self.tcx.mk_trait_ref(trait_def_id, substs)
@@ -2521,6 +2508,5 @@ pub fn provide(providers: &mut ty::query::Providers) {
         // We want to check if the panic handler was defined in this crate
         tcx.lang_items().panic_impl().map_or(false, |did| did.is_local())
     };
-    providers.source_span =
-        |tcx, def_id| tcx.untracked.source_span.read().get(def_id).copied().unwrap_or(DUMMY_SP);
+    providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
 }
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index a029c1b209d..e894e1aaf36 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -3,10 +3,9 @@
 use std::ops::ControlFlow;
 
 use crate::ty::{
-    ir::{FallibleTypeFolder, TypeVisitor},
-    visit::TypeVisitable,
-    AliasTy, Const, ConstKind, DefIdTree, InferConst, InferTy, Opaque, PolyTraitPredicate,
-    Projection, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable,
+    AliasTy, Const, ConstKind, DefIdTree, FallibleTypeFolder, InferConst, InferTy, Opaque,
+    PolyTraitPredicate, Projection, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable,
+    TypeSuperVisitable, TypeVisitable, TypeVisitor,
 };
 
 use rustc_data_structures::fx::FxHashMap;
@@ -95,7 +94,7 @@ pub trait IsSuggestable<'tcx>: Sized {
 
 impl<'tcx, T> IsSuggestable<'tcx> for T
 where
-    T: TypeVisitable<'tcx> + TypeFoldable<'tcx>,
+    T: TypeVisitable<TyCtxt<'tcx>> + TypeFoldable<TyCtxt<'tcx>>,
 {
     fn is_suggestable(self, tcx: TyCtxt<'tcx>, infer_suggestable: bool) -> bool {
         self.visit_with(&mut IsSuggestableVisitor { tcx, infer_suggestable }).is_continue()
@@ -612,3 +611,11 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for MakeSuggestableFolder<'tcx> {
         c.try_super_fold_with(self)
     }
 }
+
+#[derive(Diagnostic)]
+#[diag(middle_const_not_used_in_type_alias)]
+pub(super) struct ConstNotUsedTraitAlias {
+    pub ct: String,
+    #[primary_span]
+    pub span: Span,
+}
diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs
index d3b031bf875..38377324832 100644
--- a/compiler/rustc_middle/src/ty/erase_regions.rs
+++ b/compiler/rustc_middle/src/ty/erase_regions.rs
@@ -1,5 +1,5 @@
-use crate::ty::fold::{ir::TypeFolder, TypeFoldable, TypeSuperFoldable};
-use crate::ty::{self, Ty, TyCtxt, TypeFlags};
+use crate::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
+use crate::ty::{self, Ty, TyCtxt, TypeFlags, TypeVisitableExt};
 
 pub(super) fn provide(providers: &mut ty::query::Providers) {
     *providers = ty::query::Providers { erase_regions_ty, ..*providers };
@@ -17,7 +17,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// subtyping, but they are anonymized and normalized as well)..
     pub fn erase_regions<T>(self, value: T) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         // If there's nothing to erase avoid performing the query at all
         if !value.has_type_flags(TypeFlags::HAS_LATE_BOUND | TypeFlags::HAS_FREE_REGIONS) {
@@ -45,7 +45,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RegionEraserVisitor<'tcx> {
 
     fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         let u = self.tcx.anonymize_bound_vars(t);
         u.super_fold_with(self)
diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs
index 106ce9990e1..59deade0a07 100644
--- a/compiler/rustc_middle/src/ty/fast_reject.rs
+++ b/compiler/rustc_middle/src/ty/fast_reject.rs
@@ -1,6 +1,6 @@
 use crate::mir::Mutability;
 use crate::ty::subst::GenericArgKind;
-use crate::ty::{self, Ty, TyCtxt, TypeVisitable};
+use crate::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 use rustc_hir::def_id::DefId;
 use std::fmt::Debug;
 use std::hash::Hash;
diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index ee36e60bff1..d66f436f947 100644
--- a/compiler/rustc_middle/src/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
@@ -1,19 +1,10 @@
-use crate::ty::{self, Binder, BoundTy, Ty, TyCtxt, TypeVisitable};
+use crate::ty::{self, Binder, BoundTy, Ty, TyCtxt, TypeVisitableExt};
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_hir::def_id::DefId;
 
 use std::collections::BTreeMap;
 
-pub trait TypeFoldable<'tcx> = ir::TypeFoldable<TyCtxt<'tcx>> + TypeVisitable<'tcx>;
-pub trait TypeSuperFoldable<'tcx> = ir::TypeSuperFoldable<TyCtxt<'tcx>>;
-pub trait TypeFolder<'tcx> = ir::TypeFolder<TyCtxt<'tcx>>;
-pub trait FallibleTypeFolder<'tcx> = ir::FallibleTypeFolder<TyCtxt<'tcx>>;
-
-pub mod ir {
-    pub use rustc_type_ir::fold::{
-        FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable,
-    };
-}
+pub use rustc_type_ir::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
 
 ///////////////////////////////////////////////////////////////////////////
 // Some sample folders
@@ -30,7 +21,7 @@ where
     pub ct_op: H,
 }
 
-impl<'tcx, F, G, H> ir::TypeFolder<TyCtxt<'tcx>> for BottomUpFolder<'tcx, F, G, H>
+impl<'tcx, F, G, H> TypeFolder<TyCtxt<'tcx>> for BottomUpFolder<'tcx, F, G, H>
 where
     F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
     G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>,
@@ -69,7 +60,7 @@ impl<'tcx> TyCtxt<'tcx> {
         mut f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>,
     ) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         value.fold_with(&mut RegionFolder::new(self, &mut f))
     }
@@ -80,7 +71,7 @@ impl<'tcx> TyCtxt<'tcx> {
         mut f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>,
     ) -> T
     where
-        T: TypeSuperFoldable<'tcx>,
+        T: TypeSuperFoldable<TyCtxt<'tcx>>,
     {
         value.super_fold_with(&mut RegionFolder::new(self, &mut f))
     }
@@ -120,12 +111,12 @@ impl<'a, 'tcx> RegionFolder<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> ir::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
+impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
     fn interner(&self) -> TyCtxt<'tcx> {
         self.tcx
     }
 
-    fn fold_binder<T: TypeFoldable<'tcx>>(
+    fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
         &mut self,
         t: ty::Binder<'tcx, T>,
     ) -> ty::Binder<'tcx, T> {
@@ -194,7 +185,7 @@ impl<'tcx, D: BoundVarReplacerDelegate<'tcx>> BoundVarReplacer<'tcx, D> {
     }
 }
 
-impl<'tcx, D> ir::TypeFolder<TyCtxt<'tcx>> for BoundVarReplacer<'tcx, D>
+impl<'tcx, D> TypeFolder<TyCtxt<'tcx>> for BoundVarReplacer<'tcx, D>
 where
     D: BoundVarReplacerDelegate<'tcx>,
 {
@@ -202,7 +193,7 @@ where
         self.tcx
     }
 
-    fn fold_binder<T: TypeFoldable<'tcx>>(
+    fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
         &mut self,
         t: ty::Binder<'tcx, T>,
     ) -> ty::Binder<'tcx, T> {
@@ -280,7 +271,7 @@ impl<'tcx> TyCtxt<'tcx> {
     ) -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
     where
         F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         let mut region_map = BTreeMap::new();
         let real_fld_r = |br: ty::BoundRegion| *region_map.entry(br).or_insert_with(|| fld_r(br));
@@ -295,7 +286,7 @@ impl<'tcx> TyCtxt<'tcx> {
     ) -> T
     where
         F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         let value = value.skip_binder();
         if !value.has_escaping_bound_vars() {
@@ -314,7 +305,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Replaces all escaping bound vars. The `fld_r` closure replaces escaping
     /// bound regions; the `fld_t` closure replaces escaping bound types and the `fld_c`
     /// closure replaces escaping bound consts.
-    pub fn replace_escaping_bound_vars_uncached<T: TypeFoldable<'tcx>>(
+    pub fn replace_escaping_bound_vars_uncached<T: TypeFoldable<TyCtxt<'tcx>>>(
         self,
         value: T,
         delegate: impl BoundVarReplacerDelegate<'tcx>,
@@ -330,7 +321,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Replaces all types or regions bound by the given `Binder`. The `fld_r`
     /// closure replaces bound regions, the `fld_t` closure replaces bound
     /// types, and `fld_c` replaces bound constants.
-    pub fn replace_bound_vars_uncached<T: TypeFoldable<'tcx>>(
+    pub fn replace_bound_vars_uncached<T: TypeFoldable<TyCtxt<'tcx>>>(
         self,
         value: Binder<'tcx, T>,
         delegate: impl BoundVarReplacerDelegate<'tcx>,
@@ -346,7 +337,7 @@ impl<'tcx> TyCtxt<'tcx> {
         value: ty::Binder<'tcx, T>,
     ) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         self.replace_late_bound_regions_uncached(value, |br| {
             self.mk_re_free(all_outlive_scope, br.kind)
@@ -355,7 +346,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     pub fn shift_bound_var_indices<T>(self, bound_vars: usize, value: T) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         let shift_bv = |bv: ty::BoundVar| ty::BoundVar::from_usize(bv.as_usize() + bound_vars);
         self.replace_escaping_bound_vars_uncached(
@@ -381,7 +372,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// method lookup and a few other places where precise region relationships are not required.
     pub fn erase_late_bound_regions<T>(self, value: Binder<'tcx, T>) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         self.replace_late_bound_regions(value, |_| self.lifetimes.re_erased).0
     }
@@ -389,7 +380,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Anonymize all bound variables in `value`, this is mostly used to improve caching.
     pub fn anonymize_bound_vars<T>(self, value: Binder<'tcx, T>) -> Binder<'tcx, T>
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         struct Anonymize<'a, 'tcx> {
             tcx: TyCtxt<'tcx>,
@@ -431,7 +422,7 @@ impl<'tcx> TyCtxt<'tcx> {
         let mut map = Default::default();
         let delegate = Anonymize { tcx: self, map: &mut map };
         let inner = self.replace_escaping_bound_vars_uncached(value.skip_binder(), delegate);
-        let bound_vars = self.mk_bound_variable_kinds(map.into_values());
+        let bound_vars = self.mk_bound_variable_kinds_from_iter(map.into_values());
         Binder::bind_with_vars(inner, bound_vars)
     }
 }
@@ -457,12 +448,12 @@ impl<'tcx> Shifter<'tcx> {
     }
 }
 
-impl<'tcx> ir::TypeFolder<TyCtxt<'tcx>> for Shifter<'tcx> {
+impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Shifter<'tcx> {
     fn interner(&self) -> TyCtxt<'tcx> {
         self.tcx
     }
 
-    fn fold_binder<T: TypeFoldable<'tcx>>(
+    fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
         &mut self,
         t: ty::Binder<'tcx, T>,
     ) -> ty::Binder<'tcx, T> {
@@ -525,7 +516,7 @@ pub fn shift_region<'tcx>(
 
 pub fn shift_vars<'tcx, T>(tcx: TyCtxt<'tcx>, value: T, amount: u32) -> T
 where
-    T: TypeFoldable<'tcx>,
+    T: TypeFoldable<TyCtxt<'tcx>>,
 {
     debug!("shift_vars(value={:?}, amount={})", value, amount);
 
diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index 35c036fef2d..baef4ffeda7 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -101,7 +101,7 @@ impl GenericParamDef {
     ) -> ty::GenericArg<'tcx> {
         match &self.kind {
             ty::GenericParamDefKind::Lifetime => tcx.mk_re_error_misc().into(),
-            ty::GenericParamDefKind::Type { .. } => tcx.ty_error().into(),
+            ty::GenericParamDefKind::Type { .. } => tcx.ty_error_misc().into(),
             ty::GenericParamDefKind::Const { .. } => {
                 tcx.const_error(tcx.type_of(self.def_id).subst(tcx, preceding_substs)).into()
             }
diff --git a/compiler/rustc_middle/src/ty/impls_ty.rs b/compiler/rustc_middle/src/ty/impls_ty.rs
index 3e59c0b967c..4c7822acdf7 100644
--- a/compiler/rustc_middle/src/ty/impls_ty.rs
+++ b/compiler/rustc_middle/src/ty/impls_ty.rs
@@ -79,7 +79,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::GenericArgKin
             // WARNING: We dedup cache the `HashStable` results for `List`
             // while ignoring types and freely transmute
             // between `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>`.
-            // See `fn intern_type_list` for more details.
+            // See `fn mk_type_list` for more details.
             //
             // We therefore hash types without adding a hash for their discriminant.
             //
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index c68a344e92c..f4028a5a9f6 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -1,7 +1,7 @@
 use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use crate::ty::print::{FmtPrinter, Printer};
 use crate::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable};
-use crate::ty::{EarlyBinder, InternalSubsts, SubstsRef};
+use crate::ty::{EarlyBinder, InternalSubsts, SubstsRef, TypeVisitableExt};
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def::Namespace;
 use rustc_hir::def_id::{CrateNum, DefId};
@@ -540,7 +540,7 @@ impl<'tcx> Instance<'tcx> {
 
     pub fn resolve_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> {
         let def_id = tcx.require_lang_item(LangItem::DropInPlace, None);
-        let substs = tcx.intern_substs(&[ty.into()]);
+        let substs = tcx.mk_substs(&[ty.into()]);
         Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, substs)
     }
 
@@ -589,7 +589,7 @@ impl<'tcx> Instance<'tcx> {
 
     pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: &T) -> T
     where
-        T: TypeFoldable<'tcx> + Copy,
+        T: TypeFoldable<TyCtxt<'tcx>> + Copy,
     {
         if let Some(substs) = self.substs_for_mir_body() {
             EarlyBinder(*v).subst(tcx, substs)
@@ -606,7 +606,7 @@ impl<'tcx> Instance<'tcx> {
         v: T,
     ) -> T
     where
-        T: TypeFoldable<'tcx> + Clone,
+        T: TypeFoldable<TyCtxt<'tcx>> + Clone,
     {
         if let Some(substs) = self.substs_for_mir_body() {
             tcx.subst_and_normalize_erasing_regions(substs, param_env, v)
@@ -623,7 +623,7 @@ impl<'tcx> Instance<'tcx> {
         v: T,
     ) -> Result<T, NormalizationError<'tcx>>
     where
-        T: TypeFoldable<'tcx> + Clone,
+        T: TypeFoldable<TyCtxt<'tcx>> + Clone,
     {
         if let Some(substs) = self.substs_for_mir_body() {
             tcx.try_subst_and_normalize_erasing_regions(substs, param_env, v)
@@ -674,7 +674,7 @@ fn polymorphize<'tcx>(
         tcx: TyCtxt<'tcx>,
     }
 
-    impl<'tcx> ty::ir::TypeFolder<TyCtxt<'tcx>> for PolymorphizationFolder<'tcx> {
+    impl<'tcx> ty::TypeFolder<TyCtxt<'tcx>> for PolymorphizationFolder<'tcx> {
         fn interner(&self) -> TyCtxt<'tcx> {
             self.tcx
         }
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 993191ee96a..6c59cde86e3 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -1,6 +1,7 @@
+use crate::fluent_generated as fluent;
 use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use crate::ty::normalize_erasing_regions::NormalizationError;
-use crate::ty::{self, ReprOptions, Ty, TyCtxt, TypeVisitable};
+use crate::ty::{self, ReprOptions, Ty, TyCtxt, TypeVisitableExt};
 use rustc_errors::{DiagnosticBuilder, Handler, IntoDiagnostic};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
@@ -182,16 +183,16 @@ impl IntoDiagnostic<'_, !> for LayoutError<'_> {
         match self {
             LayoutError::Unknown(ty) => {
                 diag.set_arg("ty", ty);
-                diag.set_primary_message(rustc_errors::fluent::middle_unknown_layout);
+                diag.set_primary_message(fluent::middle_unknown_layout);
             }
             LayoutError::SizeOverflow(ty) => {
                 diag.set_arg("ty", ty);
-                diag.set_primary_message(rustc_errors::fluent::middle_values_too_big);
+                diag.set_primary_message(fluent::middle_values_too_big);
             }
             LayoutError::NormalizationFailure(ty, e) => {
                 diag.set_arg("ty", ty);
                 diag.set_arg("failure_ty", e.get_type_for_failure());
-                diag.set_primary_message(rustc_errors::fluent::middle_cannot_be_normalized);
+                diag.set_primary_message(fluent::middle_cannot_be_normalized);
             }
         }
         diag
@@ -595,7 +596,7 @@ where
                     ty::Adt(def, _) => def.variant(variant_index).fields.len(),
                     _ => bug!(),
                 };
-                tcx.intern_layout(LayoutS {
+                tcx.mk_layout(LayoutS {
                     variants: Variants::Single { index: variant_index },
                     fields: match NonZeroUsize::new(fields) {
                         Some(fields) => FieldsShape::Union(fields),
@@ -608,7 +609,7 @@ where
                 })
             }
 
-            Variants::Multiple { ref variants, .. } => cx.tcx().intern_layout(variants[variant_index].clone()),
+            Variants::Multiple { ref variants, .. } => cx.tcx().mk_layout(variants[variant_index].clone()),
         };
 
         assert_eq!(*layout.variants(), Variants::Single { index: variant_index });
@@ -630,7 +631,7 @@ where
             let tcx = cx.tcx();
             let tag_layout = |tag: Scalar| -> TyAndLayout<'tcx> {
                 TyAndLayout {
-                    layout: tcx.intern_layout(LayoutS::scalar(cx, tag)),
+                    layout: tcx.mk_layout(LayoutS::scalar(cx, tag)),
                     ty: tag.primitive().to_ty(tcx),
                 }
             };
@@ -686,7 +687,7 @@ where
                         Increase this counter if you tried to implement this but
                         failed to do it without duplicating a lot of code from
                         other places in the compiler: 2
-                        tcx.intern_tup(&[
+                        tcx.mk_tup(&[
                             tcx.mk_array(tcx.types.usize, 3),
                             tcx.mk_array(Option<fn()>),
                         ])
@@ -1120,13 +1121,6 @@ impl From<call::AdjustForForeignAbiError> for FnAbiError<'_> {
 
 impl<'tcx> fmt::Display for FnAbiError<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        #[cfg(bootstrap)]
-        match self {
-            Self::Layout(err) => fmt::Display::fmt(err, f),
-            Self::AdjustForForeignAbi(err) => fmt::Display::fmt(err, f),
-        }
-
-        #[cfg(not(bootstrap))]
         match self {
             Self::Layout(err) => err.fmt(f),
             Self::AdjustForForeignAbi(err) => err.fmt(f),
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index f61fe707ac9..17262a0be24 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -12,7 +12,7 @@
 #![allow(rustc::usage_of_ty_tykind)]
 
 pub use self::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
-pub use self::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
+pub use self::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
 pub use self::AssocItemContainer::*;
 pub use self::BorrowKind::*;
 pub use self::IntVarValue::*;
@@ -35,6 +35,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_data_structures::intern::Interned;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
+use rustc_errors::ErrorGuaranteed;
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
@@ -145,10 +146,6 @@ mod structural_impls;
 mod sty;
 mod typeck_results;
 
-pub mod ir {
-    pub use super::{fold::ir::*, visit::ir::*};
-}
-
 // Data types
 
 pub type RegisteredTools = FxHashSet<Ident>;
@@ -760,7 +757,7 @@ impl<'tcx> Predicate<'tcx> {
         let new = EarlyBinder(shifted_pred).subst(tcx, trait_ref.skip_binder().substs);
         // 3) ['x] + ['b] -> ['x, 'b]
         let bound_vars =
-            tcx.mk_bound_variable_kinds(trait_bound_vars.iter().chain(pred_bound_vars));
+            tcx.mk_bound_variable_kinds_from_iter(trait_bound_vars.iter().chain(pred_bound_vars));
         tcx.reuse_or_mk_predicate(self, ty::Binder::bind_with_vars(new, bound_vars))
     }
 }
@@ -921,14 +918,17 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Term<'tcx> {
     }
 }
 
-impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for Term<'tcx> {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
+impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for Term<'tcx> {
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        folder: &mut F,
+    ) -> Result<Self, F::Error> {
         Ok(self.unpack().try_fold_with(folder)?.pack())
     }
 }
 
-impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for Term<'tcx> {
-    fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for Term<'tcx> {
+    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
         self.unpack().visit_with(visitor)
     }
 }
@@ -1359,7 +1359,7 @@ pub struct OpaqueHiddenType<'tcx> {
 }
 
 impl<'tcx> OpaqueHiddenType<'tcx> {
-    pub fn report_mismatch(&self, other: &Self, tcx: TyCtxt<'tcx>) {
+    pub fn report_mismatch(&self, other: &Self, tcx: TyCtxt<'tcx>) -> ErrorGuaranteed {
         // Found different concrete types for the opaque type.
         let sub_diag = if self.span == other.span {
             TypeMismatchReason::ConflictType { span: self.span }
@@ -1371,7 +1371,7 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
             other_ty: other.ty,
             other_span: other.span,
             sub: sub_diag,
-        });
+        })
     }
 
     #[instrument(level = "debug", skip(tcx), ret)]
@@ -1626,8 +1626,8 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> {
     }
 }
 
-impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for ParamEnv<'tcx> {
-    fn try_fold_with<F: ty::fold::FallibleTypeFolder<'tcx>>(
+impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ParamEnv<'tcx> {
+    fn try_fold_with<F: ty::fold::FallibleTypeFolder<TyCtxt<'tcx>>>(
         self,
         folder: &mut F,
     ) -> Result<Self, F::Error> {
@@ -1639,8 +1639,8 @@ impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for ParamEnv<'tcx> {
     }
 }
 
-impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for ParamEnv<'tcx> {
-    fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ParamEnv<'tcx> {
+    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
         self.caller_bounds().visit_with(visitor)?;
         self.reveal().visit_with(visitor)
     }
@@ -1765,7 +1765,7 @@ impl<'tcx> ParamEnv<'tcx> {
     /// `where Box<u32>: Copy`, which are clearly never
     /// satisfiable. We generally want to behave as if they were true,
     /// although the surrounding function is never reachable.
-    pub fn and<T: TypeVisitable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
+    pub fn and<T: TypeVisitable<TyCtxt<'tcx>>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
         match self.reveal() {
             Reveal::UserFacing => ParamEnvAnd { param_env: self, value },
 
diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
index 825e5fbe232..57c8f3075b0 100644
--- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
+++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
@@ -9,11 +9,8 @@
 
 use crate::mir;
 use crate::traits::query::NoSolution;
-use crate::ty::fold::{
-    ir::{FallibleTypeFolder, TypeFolder},
-    TypeFoldable,
-};
-use crate::ty::{self, EarlyBinder, SubstsRef, Ty, TyCtxt};
+use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder};
+use crate::ty::{self, EarlyBinder, SubstsRef, Ty, TyCtxt, TypeVisitableExt};
 
 #[derive(Debug, Copy, Clone, HashStable, TyEncodable, TyDecodable)]
 pub enum NormalizationError<'tcx> {
@@ -41,7 +38,7 @@ impl<'tcx> TyCtxt<'tcx> {
     #[tracing::instrument(level = "debug", skip(self, param_env))]
     pub fn normalize_erasing_regions<T>(self, param_env: ty::ParamEnv<'tcx>, value: T) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         debug!(
             "normalize_erasing_regions::<{}>(value={:?}, param_env={:?})",
@@ -73,7 +70,7 @@ impl<'tcx> TyCtxt<'tcx> {
         value: T,
     ) -> Result<T, NormalizationError<'tcx>>
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         debug!(
             "try_normalize_erasing_regions::<{}>(value={:?}, param_env={:?})",
@@ -110,7 +107,7 @@ impl<'tcx> TyCtxt<'tcx> {
         value: ty::Binder<'tcx, T>,
     ) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         let value = self.erase_late_bound_regions(value);
         self.normalize_erasing_regions(param_env, value)
@@ -130,7 +127,7 @@ impl<'tcx> TyCtxt<'tcx> {
         value: ty::Binder<'tcx, T>,
     ) -> Result<T, NormalizationError<'tcx>>
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         let value = self.erase_late_bound_regions(value);
         self.try_normalize_erasing_regions(param_env, value)
@@ -148,7 +145,7 @@ impl<'tcx> TyCtxt<'tcx> {
         value: T,
     ) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         debug!(
             "subst_and_normalize_erasing_regions(\
@@ -172,7 +169,7 @@ impl<'tcx> TyCtxt<'tcx> {
         value: T,
     ) -> Result<T, NormalizationError<'tcx>>
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         debug!(
             "subst_and_normalize_erasing_regions(\
diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs
index 8aeef4684b3..751f3066c9c 100644
--- a/compiler/rustc_middle/src/ty/opaque_types.rs
+++ b/compiler/rustc_middle/src/ty/opaque_types.rs
@@ -1,9 +1,7 @@
 use crate::error::ConstNotUsedTraitAlias;
-use crate::ty::fold::{ir::TypeFolder, TypeSuperFoldable};
+use crate::ty::fold::{TypeFolder, TypeSuperFoldable};
 use crate::ty::subst::{GenericArg, GenericArgKind};
-#[cfg(not(bootstrap))]
-use crate::ty::TypeFoldable;
-use crate::ty::{self, Ty, TyCtxt};
+use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_span::def_id::DefId;
 use rustc_span::Span;
@@ -81,7 +79,7 @@ impl<'tcx> ReverseMapper<'tcx> {
         // during codegen.
 
         let generics = self.tcx.generics_of(def_id);
-        self.tcx.mk_substs(substs.iter().enumerate().map(|(index, kind)| {
+        self.tcx.mk_substs_from_iter(substs.iter().enumerate().map(|(index, kind)| {
             if index < generics.parent_count {
                 // Accommodate missing regions in the parent kinds...
                 self.fold_kind_no_missing_regions_error(kind)
@@ -188,7 +186,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
                                 .emit();
                         }
 
-                        self.interner().ty_error()
+                        self.interner().ty_error_misc()
                     }
                 }
             }
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index a101127104d..6a053c368d8 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1,7 +1,7 @@
 use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar};
 use crate::ty::{
     self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable,
-    TypeSuperFoldable, TypeSuperVisitable, TypeVisitable,
+    TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
 };
 use crate::ty::{GenericArg, GenericArgKind};
 use rustc_apfloat::ieee::{Double, Single};
@@ -225,7 +225,7 @@ pub trait PrettyPrinter<'tcx>:
 
     fn in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, Self::Error>
     where
-        T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>,
+        T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<TyCtxt<'tcx>>,
     {
         value.as_ref().skip_binder().print(self)
     }
@@ -236,7 +236,7 @@ pub trait PrettyPrinter<'tcx>:
         f: F,
     ) -> Result<Self, Self::Error>
     where
-        T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>,
+        T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<TyCtxt<'tcx>>,
     {
         f(value.as_ref().skip_binder(), self)
     }
@@ -2033,7 +2033,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
 
     fn in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, Self::Error>
     where
-        T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>,
+        T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<TyCtxt<'tcx>>,
     {
         self.pretty_in_binder(value)
     }
@@ -2044,7 +2044,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
         f: C,
     ) -> Result<Self, Self::Error>
     where
-        T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>,
+        T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<TyCtxt<'tcx>>,
     {
         self.pretty_wrap_binder(value, f)
     }
@@ -2224,12 +2224,12 @@ struct RegionFolder<'a, 'tcx> {
             ),
 }
 
-impl<'a, 'tcx> ty::ir::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
+impl<'a, 'tcx> ty::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
     fn interner(&self) -> TyCtxt<'tcx> {
         self.tcx
     }
 
-    fn fold_binder<T: TypeFoldable<'tcx>>(
+    fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
         &mut self,
         t: ty::Binder<'tcx, T>,
     ) -> ty::Binder<'tcx, T> {
@@ -2289,7 +2289,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
         value: &ty::Binder<'tcx, T>,
     ) -> Result<(Self, T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>), fmt::Error>
     where
-        T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
+        T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<TyCtxt<'tcx>>,
     {
         fn name_by_region_index(
             index: usize,
@@ -2452,7 +2452,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
 
     pub fn pretty_in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, fmt::Error>
     where
-        T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
+        T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<TyCtxt<'tcx>>,
     {
         let old_region_index = self.region_index;
         let (new, new_value, _) = self.name_all_regions(value)?;
@@ -2468,7 +2468,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
         f: C,
     ) -> Result<Self, fmt::Error>
     where
-        T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
+        T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<TyCtxt<'tcx>>,
     {
         let old_region_index = self.region_index;
         let (new, new_value, _) = self.name_all_regions(value)?;
@@ -2480,7 +2480,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
 
     fn prepare_region_info<T>(&mut self, value: &ty::Binder<'tcx, T>)
     where
-        T: TypeVisitable<'tcx>,
+        T: TypeVisitable<TyCtxt<'tcx>>,
     {
         struct RegionNameCollector<'tcx> {
             used_region_names: FxHashSet<Symbol>,
@@ -2496,7 +2496,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
             }
         }
 
-        impl<'tcx> ty::visit::ir::TypeVisitor<TyCtxt<'tcx>> for RegionNameCollector<'tcx> {
+        impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for RegionNameCollector<'tcx> {
             type BreakTy = ();
 
             fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
@@ -2533,7 +2533,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
 
 impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::Binder<'tcx, T>
 where
-    T: Print<'tcx, P, Output = P, Error = P::Error> + TypeFoldable<'tcx>,
+    T: Print<'tcx, P, Output = P, Error = P::Error> + TypeFoldable<TyCtxt<'tcx>>,
 {
     type Output = P;
     type Error = P::Error;
diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs
index 5b3f3870429..3d9a5075d4a 100644
--- a/compiler/rustc_middle/src/ty/query.rs
+++ b/compiler/rustc_middle/src/ty/query.rs
@@ -328,8 +328,9 @@ macro_rules! define_callbacks {
 
                 Providers {
                     $($name: |_, key| bug!(
-                        "`tcx.{}({:?})` is not supported for {} crate;\n
-                        hint: Queries can be either made to the local crate, or the external crate. This error means you tried to use it for one that's not supported.\n
+                        "`tcx.{}({:?})` is not supported for {} crate;\n\
+                        hint: Queries can be either made to the local crate, or the external crate. \
+                        This error means you tried to use it for one that's not supported.\n\
                         If that's not the case, {} was likely never assigned to a provider function.\n",
                         stringify!($name),
                         key,
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 2ba25e8bfad..3fc5f5bed8f 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -105,7 +105,7 @@ pub trait TypeRelation<'tcx>: Sized {
         T: Relate<'tcx>;
 }
 
-pub trait Relate<'tcx>: TypeFoldable<'tcx> + PartialEq + Copy {
+pub trait Relate<'tcx>: TypeFoldable<TyCtxt<'tcx>> + PartialEq + Copy {
     fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: Self,
@@ -144,7 +144,7 @@ pub fn relate_substs<'tcx, R: TypeRelation<'tcx>>(
     a_subst: SubstsRef<'tcx>,
     b_subst: SubstsRef<'tcx>,
 ) -> RelateResult<'tcx, SubstsRef<'tcx>> {
-    relation.tcx().mk_substs(iter::zip(a_subst, b_subst).map(|(a, b)| {
+    relation.tcx().mk_substs_from_iter(iter::zip(a_subst, b_subst).map(|(a, b)| {
         relation.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b)
     }))
 }
@@ -171,7 +171,7 @@ pub fn relate_substs_with_variances<'tcx, R: TypeRelation<'tcx>>(
         relation.relate_with_variance(variance, variance_info, a, b)
     });
 
-    tcx.mk_substs(params)
+    tcx.mk_substs_from_iter(params)
 }
 
 impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
@@ -222,7 +222,7 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
                 r => r,
             });
         Ok(ty::FnSig {
-            inputs_and_output: tcx.mk_type_list(inputs_and_output)?,
+            inputs_and_output: tcx.mk_type_list_from_iter(inputs_and_output)?,
             c_variadic: a.c_variadic,
             unsafety,
             abi,
@@ -352,7 +352,8 @@ impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> {
     ) -> RelateResult<'tcx, GeneratorWitness<'tcx>> {
         assert_eq!(a.0.len(), b.0.len());
         let tcx = relation.tcx();
-        let types = tcx.mk_type_list(iter::zip(a.0, b.0).map(|(a, b)| relation.relate(a, b)))?;
+        let types =
+            tcx.mk_type_list_from_iter(iter::zip(a.0, b.0).map(|(a, b)| relation.relate(a, b)))?;
         Ok(GeneratorWitness(types))
     }
 }
@@ -412,7 +413,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
             bug!("bound types encountered in super_relate_tys")
         }
 
-        (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(tcx.ty_error_with_guaranteed(guar)),
+        (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(tcx.ty_error(guar)),
 
         (&ty::Never, _)
         | (&ty::Char, _)
@@ -528,7 +529,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
 
         (&ty::Tuple(as_), &ty::Tuple(bs)) => {
             if as_.len() == bs.len() {
-                Ok(tcx.mk_tup(iter::zip(as_, bs).map(|(a, b)| relation.relate(a, b)))?)
+                Ok(tcx.mk_tup_from_iter(iter::zip(as_, bs).map(|(a, b)| relation.relate(a, b)))?)
             } else if !(as_.is_empty() || bs.is_empty()) {
                 Err(TypeError::TupleSize(expected_found(relation, as_.len(), bs.len())))
             } else {
@@ -673,7 +674,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
                     for (a_arg, b_arg) in aa.iter().zip(ba.iter()) {
                         related_args.push(r.consts(a_arg, b_arg)?);
                     }
-                    let related_args = tcx.intern_const_list(&related_args);
+                    let related_args = tcx.mk_const_list(&related_args);
                     Expr::FunctionCall(func, related_args)
                 }
                 _ => return Err(TypeError::ConstMismatch(expected_found(r, a, b))),
@@ -720,7 +721,7 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
                 _ => Err(TypeError::ExistentialMismatch(expected_found(relation, a, b))),
             }
         });
-        tcx.mk_poly_existential_predicates(v)
+        tcx.mk_poly_existential_predicates_from_iter(v)
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 573105fd8c0..1d4d76da572 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -5,10 +5,10 @@
 
 use crate::mir::interpret;
 use crate::mir::{Field, ProjectionKind};
-use crate::ty::fold::{ir::TypeSuperFoldable, FallibleTypeFolder, TypeFoldable};
+use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
 use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
-use crate::ty::visit::{ir::TypeSuperVisitable, TypeVisitable, TypeVisitor};
-use crate::ty::{self, ir, AliasTy, InferConst, Lift, Term, TermKind, Ty, TyCtxt};
+use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
+use crate::ty::{self, AliasTy, InferConst, Lift, Term, TermKind, Ty, TyCtxt};
 use rustc_hir::def::Namespace;
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_target::abi::TyAndLayout;
@@ -372,32 +372,41 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
 // Traversal implementations.
 
 /// AdtDefs are basically the same as a DefId.
-impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for ty::AdtDef<'tcx> {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
+impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::AdtDef<'tcx> {
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        _folder: &mut F,
+    ) -> Result<Self, F::Error> {
         Ok(self)
     }
 }
 
-impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for ty::AdtDef<'tcx> {
-    fn visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
+impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::AdtDef<'tcx> {
+    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
+        &self,
+        _visitor: &mut V,
+    ) -> ControlFlow<V::BreakTy> {
         ControlFlow::Continue(())
     }
 }
 
-impl<'tcx, T: TypeFoldable<'tcx>> ir::TypeFoldable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
+impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> TypeFoldable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> {
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        folder: &mut F,
+    ) -> Result<Self, F::Error> {
         folder.try_fold_binder(self)
     }
 }
 
-impl<'tcx, T: TypeVisitable<'tcx>> ir::TypeVisitable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> {
-    fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> {
+    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
         visitor.visit_binder(self)
     }
 }
 
-impl<'tcx, T: TypeFoldable<'tcx>> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> {
-    fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
+impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> {
+    fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
         self,
         folder: &mut F,
     ) -> Result<Self, F::Error> {
@@ -405,44 +414,61 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Binder
     }
 }
 
-impl<'tcx, T: TypeVisitable<'tcx>> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> {
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeSuperVisitable<TyCtxt<'tcx>>
+    for ty::Binder<'tcx, T>
+{
+    fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
+        &self,
+        visitor: &mut V,
+    ) -> ControlFlow<V::BreakTy> {
         self.as_ref().skip_binder().visit_with(visitor)
     }
 }
 
-impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
-        ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v))
+impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        folder: &mut F,
+    ) -> Result<Self, F::Error> {
+        ty::util::fold_list(self, folder, |tcx, v| tcx.mk_poly_existential_predicates(v))
     }
 }
 
-impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::Const<'tcx>> {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
-        ty::util::fold_list(self, folder, |tcx, v| tcx.intern_const_list(v))
+impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::Const<'tcx>> {
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        folder: &mut F,
+    ) -> Result<Self, F::Error> {
+        ty::util::fold_list(self, folder, |tcx, v| tcx.mk_const_list(v))
     }
 }
 
-impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ProjectionKind> {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
-        ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v))
+impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ProjectionKind> {
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        folder: &mut F,
+    ) -> Result<Self, F::Error> {
+        ty::util::fold_list(self, folder, |tcx, v| tcx.mk_projs(v))
     }
 }
 
-impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
+impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        folder: &mut F,
+    ) -> Result<Self, F::Error> {
         folder.try_fold_ty(self)
     }
 }
 
-impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
-    fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
+    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
         visitor.visit_ty(*self)
     }
 }
 
 impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
-    fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
+    fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
         self,
         folder: &mut F,
     ) -> Result<Self, F::Error> {
@@ -487,12 +513,15 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
             | ty::Foreign(..) => return Ok(self),
         };
 
-        Ok(if *self.kind() == kind { self } else { folder.interner().mk_ty(kind) })
+        Ok(if *self.kind() == kind { self } else { folder.interner().mk_ty_from_kind(kind) })
     }
 }
 
 impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+    fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
+        &self,
+        visitor: &mut V,
+    ) -> ControlFlow<V::BreakTy> {
         match self.kind() {
             ty::RawPtr(ref tm) => tm.visit_with(visitor),
             ty::Array(typ, sz) => {
@@ -535,20 +564,23 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
     }
 }
 
-impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for ty::Region<'tcx> {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
+impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Region<'tcx> {
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        folder: &mut F,
+    ) -> Result<Self, F::Error> {
         folder.try_fold_region(self)
     }
 }
 
-impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for ty::Region<'tcx> {
-    fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Region<'tcx> {
+    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
         visitor.visit_region(*self)
     }
 }
 
 impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Region<'tcx> {
-    fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
+    fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
         self,
         _folder: &mut F,
     ) -> Result<Self, F::Error> {
@@ -557,25 +589,31 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Region<'tcx> {
 }
 
 impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Region<'tcx> {
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
+    fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
+        &self,
+        _visitor: &mut V,
+    ) -> ControlFlow<V::BreakTy> {
         ControlFlow::Continue(())
     }
 }
 
-impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
+impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        folder: &mut F,
+    ) -> Result<Self, F::Error> {
         folder.try_fold_predicate(self)
     }
 }
 
-impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
-    fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
+    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
         visitor.visit_predicate(*self)
     }
 }
 
 impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
-    fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
+    fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
         self,
         folder: &mut F,
     ) -> Result<Self, F::Error> {
@@ -585,31 +623,40 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
 }
 
 impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+    fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
+        &self,
+        visitor: &mut V,
+    ) -> ControlFlow<V::BreakTy> {
         self.kind().visit_with(visitor)
     }
 }
 
-impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::Predicate<'tcx>> {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
-        ty::util::fold_list(self, folder, |tcx, v| tcx.intern_predicates(v))
+impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::Predicate<'tcx>> {
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        folder: &mut F,
+    ) -> Result<Self, F::Error> {
+        ty::util::fold_list(self, folder, |tcx, v| tcx.mk_predicates(v))
     }
 }
 
-impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
+impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        folder: &mut F,
+    ) -> Result<Self, F::Error> {
         folder.try_fold_const(self)
     }
 }
 
-impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
-    fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
+    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
         visitor.visit_const(*self)
     }
 }
 
 impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
-    fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
+    fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
         self,
         folder: &mut F,
     ) -> Result<Self, F::Error> {
@@ -624,32 +671,44 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
 }
 
 impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+    fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
+        &self,
+        visitor: &mut V,
+    ) -> ControlFlow<V::BreakTy> {
         self.ty().visit_with(visitor)?;
         self.kind().visit_with(visitor)
     }
 }
 
-impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for InferConst<'tcx> {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
+impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for InferConst<'tcx> {
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        _folder: &mut F,
+    ) -> Result<Self, F::Error> {
         Ok(self)
     }
 }
 
-impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for InferConst<'tcx> {
-    fn visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
+impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for InferConst<'tcx> {
+    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
+        &self,
+        _visitor: &mut V,
+    ) -> ControlFlow<V::BreakTy> {
         ControlFlow::Continue(())
     }
 }
 
 impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::UnevaluatedConst<'tcx> {
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+    fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
+        &self,
+        visitor: &mut V,
+    ) -> ControlFlow<V::BreakTy> {
         self.substs.visit_with(visitor)
     }
 }
 
-impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for TyAndLayout<'tcx, Ty<'tcx>> {
-    fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for TyAndLayout<'tcx, Ty<'tcx>> {
+    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
         visitor.visit_ty(self.ty)
     }
 }
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index f8d17433cf7..ba714541c9e 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -7,10 +7,8 @@ use crate::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
 use crate::ty::visit::ValidateBoundVars;
 use crate::ty::InferTy::*;
 use crate::ty::{
-    self,
-    ir::{FallibleTypeFolder, TypeVisitor},
-    AdtDef, DefIdTree, Discr, Term, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeSuperFoldable,
-    TypeSuperVisitable, TypeVisitable,
+    self, AdtDef, DefIdTree, Discr, FallibleTypeFolder, Term, Ty, TyCtxt, TypeFlags, TypeFoldable,
+    TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
 };
 use crate::ty::{List, ParamEnv};
 use hir::def::DefKind;
@@ -252,7 +250,7 @@ impl<'tcx> ClosureSubsts<'tcx> {
         parts: ClosureSubstsParts<'tcx, Ty<'tcx>>,
     ) -> ClosureSubsts<'tcx> {
         ClosureSubsts {
-            substs: tcx.mk_substs(
+            substs: tcx.mk_substs_from_iter(
                 parts.parent_substs.iter().copied().chain(
                     [parts.closure_kind_ty, parts.closure_sig_as_fn_ptr_ty, parts.tupled_upvars_ty]
                         .iter()
@@ -379,7 +377,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
         parts: GeneratorSubstsParts<'tcx, Ty<'tcx>>,
     ) -> GeneratorSubsts<'tcx> {
         GeneratorSubsts {
-            substs: tcx.mk_substs(
+            substs: tcx.mk_substs_from_iter(
                 parts.parent_substs.iter().copied().chain(
                     [
                         parts.resume_ty,
@@ -570,7 +568,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
         self,
         def_id: DefId,
         tcx: TyCtxt<'tcx>,
-    ) -> impl Iterator<Item = impl Iterator<Item = Ty<'tcx>> + Captures<'tcx>> {
+    ) -> impl Iterator<Item: Iterator<Item = Ty<'tcx>> + Captures<'tcx>> {
         let layout = tcx.generator_layout(def_id).unwrap();
         layout.variant_fields.iter().map(move |variant| {
             variant.iter().map(move |field| {
@@ -657,7 +655,7 @@ impl<'tcx> InlineConstSubsts<'tcx> {
         parts: InlineConstSubstsParts<'tcx, Ty<'tcx>>,
     ) -> InlineConstSubsts<'tcx> {
         InlineConstSubsts {
-            substs: tcx.mk_substs(
+            substs: tcx.mk_substs_from_iter(
                 parts.parent_substs.iter().copied().chain(std::iter::once(parts.ty.into())),
             ),
         }
@@ -855,7 +853,7 @@ impl<'tcx> TraitRef<'tcx> {
         substs: SubstsRef<'tcx>,
     ) -> ty::TraitRef<'tcx> {
         let defs = tcx.generics_of(trait_id);
-        tcx.mk_trait_ref(trait_id, tcx.intern_substs(&substs[..defs.params.len()]))
+        tcx.mk_trait_ref(trait_id, tcx.mk_substs(&substs[..defs.params.len()]))
     }
 }
 
@@ -901,7 +899,7 @@ impl<'tcx> ExistentialTraitRef<'tcx> {
 
         ty::ExistentialTraitRef {
             def_id: trait_ref.def_id,
-            substs: tcx.intern_substs(&trait_ref.substs[1..]),
+            substs: tcx.mk_substs(&trait_ref.substs[1..]),
         }
     }
 
@@ -985,7 +983,7 @@ pub struct Binder<'tcx, T>(T, &'tcx List<BoundVariableKind>);
 
 impl<'tcx, T> Binder<'tcx, T>
 where
-    T: TypeVisitable<'tcx>,
+    T: TypeVisitable<TyCtxt<'tcx>>,
 {
     /// Wraps `value` in a binder, asserting that `value` does not
     /// contain any bound vars that would be bound by the
@@ -1053,14 +1051,14 @@ impl<'tcx, T> Binder<'tcx, T> {
         Binder(value, self.1)
     }
 
-    pub fn map_bound_ref<F, U: TypeVisitable<'tcx>>(&self, f: F) -> Binder<'tcx, U>
+    pub fn map_bound_ref<F, U: TypeVisitable<TyCtxt<'tcx>>>(&self, f: F) -> Binder<'tcx, U>
     where
         F: FnOnce(&T) -> U,
     {
         self.as_ref().map_bound(f)
     }
 
-    pub fn map_bound<F, U: TypeVisitable<'tcx>>(self, f: F) -> Binder<'tcx, U>
+    pub fn map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>>(self, f: F) -> Binder<'tcx, U>
     where
         F: FnOnce(T) -> U,
     {
@@ -1072,7 +1070,10 @@ impl<'tcx, T> Binder<'tcx, T> {
         Binder(value, self.1)
     }
 
-    pub fn try_map_bound<F, U: TypeVisitable<'tcx>, E>(self, f: F) -> Result<Binder<'tcx, U>, E>
+    pub fn try_map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>, E>(
+        self,
+        f: F,
+    ) -> Result<Binder<'tcx, U>, E>
     where
         F: FnOnce(T) -> Result<U, E>,
     {
@@ -1095,7 +1096,7 @@ impl<'tcx, T> Binder<'tcx, T> {
     /// in `bind`. This may be (debug) asserted in the future.
     pub fn rebind<U>(&self, value: U) -> Binder<'tcx, U>
     where
-        U: TypeVisitable<'tcx>,
+        U: TypeVisitable<TyCtxt<'tcx>>,
     {
         if cfg!(debug_assertions) {
             let mut validator = ValidateBoundVars::new(self.bound_vars());
@@ -1116,7 +1117,7 @@ impl<'tcx, T> Binder<'tcx, T> {
     /// would not be that useful.)
     pub fn no_bound_vars(self) -> Option<T>
     where
-        T: TypeVisitable<'tcx>,
+        T: TypeVisitable<TyCtxt<'tcx>>,
     {
         if self.0.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
     }
@@ -1164,7 +1165,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for SkipBindersAt<'tcx> {
 
     fn try_fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, Self::Error>
     where
-        T: ty::TypeFoldable<'tcx>,
+        T: ty::TypeFoldable<TyCtxt<'tcx>>,
     {
         self.index.shift_in(1);
         let value = t.try_map_bound(|t| t.try_fold_with(self));
@@ -1550,7 +1551,7 @@ impl<'tcx> ExistentialProjection<'tcx> {
     pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::ExistentialTraitRef<'tcx> {
         let def_id = tcx.parent(self.def_id);
         let subst_count = tcx.generics_of(def_id).count() - 1;
-        let substs = tcx.intern_substs(&self.substs[..subst_count]);
+        let substs = tcx.mk_substs(&self.substs[..subst_count]);
         ty::ExistentialTraitRef { def_id, substs }
     }
 
@@ -1578,7 +1579,7 @@ impl<'tcx> ExistentialProjection<'tcx> {
 
         Self {
             def_id: projection_predicate.projection_ty.def_id,
-            substs: tcx.intern_substs(&projection_predicate.projection_ty.substs[1..]),
+            substs: tcx.mk_substs(&projection_predicate.projection_ty.substs[1..]),
             term: projection_predicate.term,
         }
     }
@@ -1751,6 +1752,13 @@ impl<'tcx> Region<'tcx> {
     pub fn is_var(self) -> bool {
         matches!(self.kind(), ty::ReVar(_))
     }
+
+    pub fn as_var(self) -> Option<RegionVid> {
+        match self.kind() {
+            ty::ReVar(vid) => Some(vid),
+            _ => None,
+        }
+    }
 }
 
 /// Type utilities
@@ -2201,7 +2209,7 @@ impl<'tcx> Ty<'tcx> {
                 let assoc_items = tcx.associated_item_def_ids(
                     tcx.require_lang_item(hir::LangItem::DiscriminantKind, None),
                 );
-                tcx.mk_projection(assoc_items[0], tcx.intern_substs(&[self.into()]))
+                tcx.mk_projection(assoc_items[0], tcx.mk_substs(&[self.into()]))
             }
 
             ty::Bool
diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs
index 6b4a6a17aef..b090bd9d807 100644
--- a/compiler/rustc_middle/src/ty/subst.rs
+++ b/compiler/rustc_middle/src/ty/subst.rs
@@ -1,10 +1,10 @@
 // Type substitutions.
 
 use crate::ty::codec::{TyDecoder, TyEncoder};
-use crate::ty::fold::{ir::TypeFolder, FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
+use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
 use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts};
-use crate::ty::visit::{TypeVisitable, TypeVisitor};
-use crate::ty::{self, ir, Lift, List, ParamConst, Ty, TyCtxt};
+use crate::ty::visit::{TypeVisitable, TypeVisitableExt, TypeVisitor};
+use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
 
 use rustc_data_structures::intern::Interned;
 use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
@@ -71,7 +71,7 @@ impl<'tcx> List<Ty<'tcx>> {
     /// Allows to freely switch between `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>`.
     ///
     /// As lists are interned, `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>` have
-    /// be interned together, see `intern_type_list` for more details.
+    /// be interned together, see `mk_type_list` for more details.
     #[inline]
     pub fn as_substs(&'tcx self) -> SubstsRef<'tcx> {
         assert_eq!(TYPE_TAG, 0);
@@ -227,8 +227,11 @@ impl<'a, 'tcx> Lift<'tcx> for GenericArg<'a> {
     }
 }
 
-impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for GenericArg<'tcx> {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
+impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for GenericArg<'tcx> {
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        folder: &mut F,
+    ) -> Result<Self, F::Error> {
         match self.unpack() {
             GenericArgKind::Lifetime(lt) => lt.try_fold_with(folder).map(Into::into),
             GenericArgKind::Type(ty) => ty.try_fold_with(folder).map(Into::into),
@@ -237,8 +240,8 @@ impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for GenericArg<'tcx> {
     }
 }
 
-impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for GenericArg<'tcx> {
-    fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for GenericArg<'tcx> {
+    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
         match self.unpack() {
             GenericArgKind::Lifetime(lt) => lt.visit_with(visitor),
             GenericArgKind::Type(ty) => ty.visit_with(visitor),
@@ -316,7 +319,7 @@ impl<'tcx> InternalSubsts<'tcx> {
         let count = defs.count();
         let mut substs = SmallVec::with_capacity(count);
         Self::fill_item(&mut substs, tcx, defs, &mut mk_kind);
-        tcx.intern_substs(&substs)
+        tcx.mk_substs(&substs)
     }
 
     pub fn extend_to<F>(&self, tcx: TyCtxt<'tcx>, def_id: DefId, mut mk_kind: F) -> SubstsRef<'tcx>
@@ -465,29 +468,32 @@ impl<'tcx> InternalSubsts<'tcx> {
         target_substs: SubstsRef<'tcx>,
     ) -> SubstsRef<'tcx> {
         let defs = tcx.generics_of(source_ancestor);
-        tcx.mk_substs(target_substs.iter().chain(self.iter().skip(defs.params.len())))
+        tcx.mk_substs_from_iter(target_substs.iter().chain(self.iter().skip(defs.params.len())))
     }
 
     pub fn truncate_to(&self, tcx: TyCtxt<'tcx>, generics: &ty::Generics) -> SubstsRef<'tcx> {
-        tcx.mk_substs(self.iter().take(generics.count()))
+        tcx.mk_substs_from_iter(self.iter().take(generics.count()))
     }
 }
 
-impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for SubstsRef<'tcx> {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
+impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for SubstsRef<'tcx> {
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        folder: &mut F,
+    ) -> Result<Self, F::Error> {
         // This code is hot enough that it's worth specializing for the most
         // common length lists, to avoid the overhead of `SmallVec` creation.
         // The match arms are in order of frequency. The 1, 2, and 0 cases are
         // typically hit in 90--99.99% of cases. When folding doesn't change
         // the substs, it's faster to reuse the existing substs rather than
-        // calling `intern_substs`.
+        // calling `mk_substs`.
         match self.len() {
             1 => {
                 let param0 = self[0].try_fold_with(folder)?;
                 if param0 == self[0] {
                     Ok(self)
                 } else {
-                    Ok(folder.interner().intern_substs(&[param0]))
+                    Ok(folder.interner().mk_substs(&[param0]))
                 }
             }
             2 => {
@@ -496,17 +502,20 @@ impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for SubstsRef<'tcx> {
                 if param0 == self[0] && param1 == self[1] {
                     Ok(self)
                 } else {
-                    Ok(folder.interner().intern_substs(&[param0, param1]))
+                    Ok(folder.interner().mk_substs(&[param0, param1]))
                 }
             }
             0 => Ok(self),
-            _ => ty::util::fold_list(self, folder, |tcx, v| tcx.intern_substs(v)),
+            _ => ty::util::fold_list(self, folder, |tcx, v| tcx.mk_substs(v)),
         }
     }
 }
 
-impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<Ty<'tcx>> {
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
+impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<Ty<'tcx>> {
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        folder: &mut F,
+    ) -> Result<Self, F::Error> {
         // This code is fairly hot, though not as hot as `SubstsRef`.
         //
         // When compiling stage 2, I get the following results:
@@ -529,17 +538,17 @@ impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<Ty<'tcx>> {
                 if param0 == self[0] && param1 == self[1] {
                     Ok(self)
                 } else {
-                    Ok(folder.interner().intern_type_list(&[param0, param1]))
+                    Ok(folder.interner().mk_type_list(&[param0, param1]))
                 }
             }
-            _ => ty::util::fold_list(self, folder, |tcx, v| tcx.intern_type_list(v)),
+            _ => ty::util::fold_list(self, folder, |tcx, v| tcx.mk_type_list(v)),
         }
     }
 }
 
-impl<'tcx, T: TypeVisitable<'tcx>> ir::TypeVisitable<TyCtxt<'tcx>> for &'tcx ty::List<T> {
+impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>> for &'tcx ty::List<T> {
     #[inline]
-    fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
         self.iter().try_for_each(|t| t.visit_with(visitor))
     }
 }
@@ -555,8 +564,8 @@ impl<'tcx, T: TypeVisitable<'tcx>> ir::TypeVisitable<TyCtxt<'tcx>> for &'tcx ty:
 pub struct EarlyBinder<T>(pub T);
 
 /// For early binders, you should first call `subst` before using any visitors.
-impl<'tcx, T> !ir::TypeFoldable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {}
-impl<'tcx, T> !ir::TypeVisitable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {}
+impl<'tcx, T> !TypeFoldable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {}
+impl<'tcx, T> !TypeVisitable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {}
 
 impl<T> EarlyBinder<T> {
     pub fn as_ref(&self) -> EarlyBinder<&T> {
@@ -617,7 +626,7 @@ impl<T, U> EarlyBinder<(T, U)> {
 
 impl<'tcx, 's, I: IntoIterator> EarlyBinder<I>
 where
-    I::Item: TypeFoldable<'tcx>,
+    I::Item: TypeFoldable<TyCtxt<'tcx>>,
 {
     pub fn subst_iter(
         self,
@@ -636,7 +645,7 @@ pub struct SubstIter<'s, 'tcx, I: IntoIterator> {
 
 impl<'tcx, I: IntoIterator> Iterator for SubstIter<'_, 'tcx, I>
 where
-    I::Item: TypeFoldable<'tcx>,
+    I::Item: TypeFoldable<TyCtxt<'tcx>>,
 {
     type Item = I::Item;
 
@@ -652,7 +661,7 @@ where
 impl<'tcx, I: IntoIterator> DoubleEndedIterator for SubstIter<'_, 'tcx, I>
 where
     I::IntoIter: DoubleEndedIterator,
-    I::Item: TypeFoldable<'tcx>,
+    I::Item: TypeFoldable<TyCtxt<'tcx>>,
 {
     fn next_back(&mut self) -> Option<Self::Item> {
         Some(EarlyBinder(self.it.next_back()?).subst(self.tcx, self.substs))
@@ -662,14 +671,14 @@ where
 impl<'tcx, I: IntoIterator> ExactSizeIterator for SubstIter<'_, 'tcx, I>
 where
     I::IntoIter: ExactSizeIterator,
-    I::Item: TypeFoldable<'tcx>,
+    I::Item: TypeFoldable<TyCtxt<'tcx>>,
 {
 }
 
 impl<'tcx, 's, I: IntoIterator> EarlyBinder<I>
 where
     I::Item: Deref,
-    <I::Item as Deref>::Target: Copy + TypeFoldable<'tcx>,
+    <I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>,
 {
     pub fn subst_iter_copied(
         self,
@@ -689,7 +698,7 @@ pub struct SubstIterCopied<'a, 'tcx, I: IntoIterator> {
 impl<'tcx, I: IntoIterator> Iterator for SubstIterCopied<'_, 'tcx, I>
 where
     I::Item: Deref,
-    <I::Item as Deref>::Target: Copy + TypeFoldable<'tcx>,
+    <I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>,
 {
     type Item = <I::Item as Deref>::Target;
 
@@ -706,7 +715,7 @@ impl<'tcx, I: IntoIterator> DoubleEndedIterator for SubstIterCopied<'_, 'tcx, I>
 where
     I::IntoIter: DoubleEndedIterator,
     I::Item: Deref,
-    <I::Item as Deref>::Target: Copy + TypeFoldable<'tcx>,
+    <I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>,
 {
     fn next_back(&mut self) -> Option<Self::Item> {
         Some(EarlyBinder(*self.it.next_back()?).subst(self.tcx, self.substs))
@@ -717,7 +726,7 @@ impl<'tcx, I: IntoIterator> ExactSizeIterator for SubstIterCopied<'_, 'tcx, I>
 where
     I::IntoIter: ExactSizeIterator,
     I::Item: Deref,
-    <I::Item as Deref>::Target: Copy + TypeFoldable<'tcx>,
+    <I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>,
 {
 }
 
@@ -743,7 +752,7 @@ impl<T: Iterator> Iterator for EarlyBinderIter<T> {
     }
 }
 
-impl<'tcx, T: TypeFoldable<'tcx>> ty::EarlyBinder<T> {
+impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> ty::EarlyBinder<T> {
     pub fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> T {
         let mut folder = SubstFolder { tcx, substs, binders_passed: 0 };
         self.0.fold_with(&mut folder)
@@ -784,7 +793,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for SubstFolder<'a, 'tcx> {
         self.tcx
     }
 
-    fn fold_binder<T: TypeFoldable<'tcx>>(
+    fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
         &mut self,
         t: ty::Binder<'tcx, T>,
     ) -> ty::Binder<'tcx, T> {
@@ -977,7 +986,7 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
     /// As indicated in the diagram, here the same type `&'a i32` is substituted once, but in the
     /// first case we do not increase the De Bruijn index and in the second case we do. The reason
     /// is that only in the second case have we passed through a fn binder.
-    fn shift_vars_through_binders<T: TypeFoldable<'tcx>>(&self, val: T) -> T {
+    fn shift_vars_through_binders<T: TypeFoldable<TyCtxt<'tcx>>>(&self, val: T) -> T {
         debug!(
             "shift_vars(val={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})",
             val,
diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs
index a4a82bf247d..233c0df2d3c 100644
--- a/compiler/rustc_middle/src/ty/trait_def.rs
+++ b/compiler/rustc_middle/src/ty/trait_def.rs
@@ -1,6 +1,6 @@
 use crate::traits::specialization_graph;
 use crate::ty::fast_reject::{self, SimplifiedType, TreatParams};
-use crate::ty::visit::TypeVisitable;
+use crate::ty::visit::TypeVisitableExt;
 use crate::ty::{Ident, Ty, TyCtxt};
 use hir::def_id::LOCAL_CRATE;
 use rustc_hir as hir;
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index ca46cf29919..90270e0ee9d 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -4,8 +4,8 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use crate::mir;
 use crate::ty::layout::IntegerExt;
 use crate::ty::{
-    self, ir::TypeFolder, DefIdTree, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable,
-    TypeSuperFoldable,
+    self, DefIdTree, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder,
+    TypeSuperFoldable, TypeVisitableExt,
 };
 use crate::ty::{GenericArgKind, SubstsRef};
 use rustc_apfloat::Float as _;
@@ -761,6 +761,40 @@ impl<'tcx> TyCtxt<'tcx> {
         }
         (generator_layout, generator_saved_local_names)
     }
+
+    /// Query and get an English description for the item's kind.
+    pub fn def_descr(self, def_id: DefId) -> &'static str {
+        self.def_kind_descr(self.def_kind(def_id), def_id)
+    }
+
+    /// Get an English description for the item's kind.
+    pub fn def_kind_descr(self, def_kind: DefKind, def_id: DefId) -> &'static str {
+        match def_kind {
+            DefKind::AssocFn if self.associated_item(def_id).fn_has_self_parameter => "method",
+            DefKind::Generator => match self.generator_kind(def_id).unwrap() {
+                rustc_hir::GeneratorKind::Async(..) => "async closure",
+                rustc_hir::GeneratorKind::Gen => "generator",
+            },
+            _ => def_kind.descr(def_id),
+        }
+    }
+
+    /// Gets an English article for the [`TyCtxt::def_descr`].
+    pub fn def_descr_article(self, def_id: DefId) -> &'static str {
+        self.def_kind_descr_article(self.def_kind(def_id), def_id)
+    }
+
+    /// Gets an English article for the [`TyCtxt::def_kind_descr`].
+    pub fn def_kind_descr_article(self, def_kind: DefKind, def_id: DefId) -> &'static str {
+        match def_kind {
+            DefKind::AssocFn if self.associated_item(def_id).fn_has_self_parameter => "a",
+            DefKind::Generator => match self.generator_kind(def_id).unwrap() {
+                rustc_hir::GeneratorKind::Async(..) => "an",
+                rustc_hir::GeneratorKind::Gen => "a",
+            },
+            _ => def_kind.article(),
+        }
+    }
 }
 
 struct OpaqueTypeExpander<'tcx> {
@@ -1349,8 +1383,8 @@ pub fn fold_list<'tcx, F, T>(
     intern: impl FnOnce(TyCtxt<'tcx>, &[T]) -> &'tcx ty::List<T>,
 ) -> Result<&'tcx ty::List<T>, F::Error>
 where
-    F: FallibleTypeFolder<'tcx>,
-    T: TypeFoldable<'tcx> + PartialEq + Copy,
+    F: FallibleTypeFolder<TyCtxt<'tcx>>,
+    T: TypeFoldable<TyCtxt<'tcx>> + PartialEq + Copy,
 {
     let mut iter = list.iter();
     // Look for the first element that changed
diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs
index 8a93b59900e..6814cadb9a8 100644
--- a/compiler/rustc_middle/src/ty/visit.rs
+++ b/compiler/rustc_middle/src/ty/visit.rs
@@ -5,15 +5,9 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::sso::SsoHashSet;
 use std::ops::ControlFlow;
 
-pub trait TypeVisitable<'tcx> = ir::TypeVisitable<TyCtxt<'tcx>> + TypeVisitableExt<'tcx>;
-pub trait TypeSuperVisitable<'tcx> = ir::TypeSuperVisitable<TyCtxt<'tcx>>;
-pub trait TypeVisitor<'tcx> = ir::TypeVisitor<TyCtxt<'tcx>>;
+pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
 
-pub mod ir {
-    pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
-}
-
-pub trait TypeVisitableExt<'tcx>: ir::TypeVisitable<TyCtxt<'tcx>> {
+pub trait TypeVisitableExt<'tcx>: TypeVisitable<TyCtxt<'tcx>> {
     /// Returns `true` if `self` has any late-bound regions that are either
     /// bound by `binder` or bound by some binder outside of `binder`.
     /// If `binder` is `ty::INNERMOST`, this indicates whether
@@ -135,7 +129,7 @@ pub trait TypeVisitableExt<'tcx>: ir::TypeVisitable<TyCtxt<'tcx>> {
     }
 }
 
-impl<'tcx, T: ir::TypeVisitable<TyCtxt<'tcx>>> TypeVisitableExt<'tcx> for T {}
+impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitableExt<'tcx> for T {}
 
 ///////////////////////////////////////////////////////////////////////////
 // Region folder
@@ -144,7 +138,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Invoke `callback` on every region appearing free in `value`.
     pub fn for_each_free_region(
         self,
-        value: &impl TypeVisitable<'tcx>,
+        value: &impl TypeVisitable<TyCtxt<'tcx>>,
         mut callback: impl FnMut(ty::Region<'tcx>),
     ) {
         self.any_free_region_meets(value, |r| {
@@ -156,7 +150,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Returns `true` if `callback` returns true for every region appearing free in `value`.
     pub fn all_free_regions_meet(
         self,
-        value: &impl TypeVisitable<'tcx>,
+        value: &impl TypeVisitable<TyCtxt<'tcx>>,
         mut callback: impl FnMut(ty::Region<'tcx>) -> bool,
     ) -> bool {
         !self.any_free_region_meets(value, |r| !callback(r))
@@ -165,7 +159,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Returns `true` if `callback` returns true for some region appearing free in `value`.
     pub fn any_free_region_meets(
         self,
-        value: &impl TypeVisitable<'tcx>,
+        value: &impl TypeVisitable<TyCtxt<'tcx>>,
         callback: impl FnMut(ty::Region<'tcx>) -> bool,
     ) -> bool {
         struct RegionVisitor<F> {
@@ -190,13 +184,13 @@ impl<'tcx> TyCtxt<'tcx> {
             callback: F,
         }
 
-        impl<'tcx, F> ir::TypeVisitor<TyCtxt<'tcx>> for RegionVisitor<F>
+        impl<'tcx, F> TypeVisitor<TyCtxt<'tcx>> for RegionVisitor<F>
         where
             F: FnMut(ty::Region<'tcx>) -> bool,
         {
             type BreakTy = ();
 
-            fn visit_binder<T: TypeVisitable<'tcx>>(
+            fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
                 &mut self,
                 t: &Binder<'tcx, T>,
             ) -> ControlFlow<Self::BreakTy> {
@@ -243,7 +237,7 @@ impl<'tcx> TyCtxt<'tcx> {
         value: &Binder<'tcx, T>,
     ) -> FxHashSet<ty::BoundRegionKind>
     where
-        T: TypeVisitable<'tcx>,
+        T: TypeVisitable<TyCtxt<'tcx>>,
     {
         self.collect_late_bound_regions(value, true)
     }
@@ -254,7 +248,7 @@ impl<'tcx> TyCtxt<'tcx> {
         value: &Binder<'tcx, T>,
     ) -> FxHashSet<ty::BoundRegionKind>
     where
-        T: TypeVisitable<'tcx>,
+        T: TypeVisitable<TyCtxt<'tcx>>,
     {
         self.collect_late_bound_regions(value, false)
     }
@@ -265,7 +259,7 @@ impl<'tcx> TyCtxt<'tcx> {
         just_constraint: bool,
     ) -> FxHashSet<ty::BoundRegionKind>
     where
-        T: TypeVisitable<'tcx>,
+        T: TypeVisitable<TyCtxt<'tcx>>,
     {
         let mut collector = LateBoundRegionsCollector::new(just_constraint);
         let result = value.as_ref().skip_binder().visit_with(&mut collector);
@@ -292,10 +286,10 @@ impl<'tcx> ValidateBoundVars<'tcx> {
     }
 }
 
-impl<'tcx> ir::TypeVisitor<TyCtxt<'tcx>> for ValidateBoundVars<'tcx> {
+impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ValidateBoundVars<'tcx> {
     type BreakTy = ();
 
-    fn visit_binder<T: TypeVisitable<'tcx>>(
+    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
         &mut self,
         t: &Binder<'tcx, T>,
     ) -> ControlFlow<Self::BreakTy> {
@@ -404,10 +398,10 @@ struct HasEscapingVarsVisitor {
     outer_index: ty::DebruijnIndex,
 }
 
-impl<'tcx> ir::TypeVisitor<TyCtxt<'tcx>> for HasEscapingVarsVisitor {
+impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasEscapingVarsVisitor {
     type BreakTy = FoundEscapingVars;
 
-    fn visit_binder<T: TypeVisitable<'tcx>>(
+    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
         &mut self,
         t: &Binder<'tcx, T>,
     ) -> ControlFlow<Self::BreakTy> {
@@ -481,7 +475,7 @@ impl std::fmt::Debug for HasTypeFlagsVisitor {
     }
 }
 
-impl<'tcx> ir::TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor {
+impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor {
     type BreakTy = FoundFlags;
 
     #[inline]
@@ -551,8 +545,8 @@ impl LateBoundRegionsCollector {
     }
 }
 
-impl<'tcx> ir::TypeVisitor<TyCtxt<'tcx>> for LateBoundRegionsCollector {
-    fn visit_binder<T: TypeVisitable<'tcx>>(
+impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for LateBoundRegionsCollector {
+    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
         &mut self,
         t: &Binder<'tcx, T>,
     ) -> ControlFlow<Self::BreakTy> {
@@ -613,7 +607,7 @@ impl MaxUniverse {
     }
 }
 
-impl<'tcx> ir::TypeVisitor<TyCtxt<'tcx>> for MaxUniverse {
+impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxUniverse {
     fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
         if let ty::Placeholder(placeholder) = t.kind() {
             self.max_universe = ty::UniverseIndex::from_u32(
diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs
index f77bd9f0c6f..b9b1cd73a8b 100644
--- a/compiler/rustc_middle/src/ty/vtable.rs
+++ b/compiler/rustc_middle/src/ty/vtable.rs
@@ -112,5 +112,5 @@ pub(super) fn vtable_allocation_provider<'tcx>(
     }
 
     vtable.mutability = Mutability::Not;
-    tcx.create_memory_alloc(tcx.intern_const_alloc(vtable))
+    tcx.create_memory_alloc(tcx.mk_const_alloc(vtable))
 }
diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs
index 34e8a559784..c4f526dbdc8 100644
--- a/compiler/rustc_middle/src/values.rs
+++ b/compiler/rustc_middle/src/values.rs
@@ -2,7 +2,7 @@ use crate::dep_graph::DepKind;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan};
 use rustc_hir as hir;
-use rustc_hir::def::DefKind;
+use rustc_hir::def::{DefKind, Res};
 use rustc_middle::ty::Representability;
 use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt};
 use rustc_query_system::query::QueryInfo;
@@ -16,7 +16,7 @@ impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for Ty<'_> {
     fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &[QueryInfo<DepKind>]) -> Self {
         // SAFETY: This is never called when `Self` is not `Ty<'tcx>`.
         // FIXME: Represent the above fact in the trait system somehow.
-        unsafe { std::mem::transmute::<Ty<'tcx>, Ty<'_>>(tcx.ty_error()) }
+        unsafe { std::mem::transmute::<Ty<'tcx>, Ty<'_>>(tcx.ty_error_misc()) }
     }
 }
 
@@ -34,7 +34,7 @@ impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::SymbolName<'_> {
 
 impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::Binder<'_, ty::FnSig<'_>> {
     fn from_cycle_error(tcx: TyCtxt<'tcx>, stack: &[QueryInfo<DepKind>]) -> Self {
-        let err = tcx.ty_error();
+        let err = tcx.ty_error_misc();
 
         let arity = if let Some(frame) = stack.get(0)
             && frame.query.dep_kind == DepKind::fn_sig
@@ -199,7 +199,8 @@ fn find_item_ty_spans(
 ) {
     match ty.kind {
         hir::TyKind::Path(hir::QPath::Resolved(_, path)) => {
-            if let Some(def_id) = path.res.opt_def_id() {
+            if let Res::Def(kind, def_id) = path.res
+                && kind != DefKind::TyAlias {
                 let check_params = def_id.as_local().map_or(true, |def_id| {
                     if def_id == needle {
                         spans.push(ty.span);
diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_mir_build/locales/en-US.ftl
index f9bda721df3..f9bda721df3 100644
--- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl
+++ b/compiler/rustc_mir_build/locales/en-US.ftl
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index 1d96893c7a3..2f63333d46b 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -132,14 +132,14 @@ pub(crate) fn lit_to_mir_constant<'tcx>(
         (ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => {
             let s = s.as_str();
             let allocation = Allocation::from_bytes_byte_aligned_immutable(s.as_bytes());
-            let allocation = tcx.intern_const_alloc(allocation);
+            let allocation = tcx.mk_const_alloc(allocation);
             ConstValue::Slice { data: allocation, start: 0, end: s.len() }
         }
         (ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _))
             if matches!(inner_ty.kind(), ty::Slice(_)) =>
         {
             let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]);
-            let allocation = tcx.intern_const_alloc(allocation);
+            let allocation = tcx.mk_const_alloc(allocation);
             ConstValue::Slice { data: allocation, start: 0, end: data.len() }
         }
         (ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_array() => {
diff --git a/compiler/rustc_mir_build/src/build/expr/as_operand.rs b/compiler/rustc_mir_build/src/build/expr/as_operand.rs
index c621efb3b3a..ff3198847df 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_operand.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs
@@ -170,7 +170,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     // Return the operand *tmp0 to be used as the call argument
                     let place = Place {
                         local: operand,
-                        projection: tcx.intern_place_elems(&[PlaceElem::Deref]),
+                        projection: tcx.mk_place_elems(&[PlaceElem::Deref]),
                     };
 
                     return block.and(Operand::Move(place));
diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
index e22fa6365dc..eb20b2308c0 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -263,7 +263,7 @@ impl<'tcx> PlaceBuilder<'tcx> {
         let resolved = self.resolve_upvar(cx);
         let builder = resolved.as_ref().unwrap_or(self);
         let PlaceBase::Local(local) = builder.base else { return None };
-        let projection = cx.tcx.intern_place_elems(&builder.projection);
+        let projection = cx.tcx.mk_place_elems(&builder.projection);
         Some(Place { local, projection })
     }
 
@@ -692,7 +692,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                             tcx.mk_imm_ref(tcx.lifetimes.re_erased, fake_borrow_deref_ty);
                         let fake_borrow_temp =
                             self.local_decls.push(LocalDecl::new(fake_borrow_ty, expr_span));
-                        let projection = tcx.intern_place_elems(&base_place.projection[..idx]);
+                        let projection = tcx.mk_place_elems(&base_place.projection[..idx]);
                         self.cfg.push_assign(
                             block,
                             source_info,
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index fb0e9181b52..a4e48c1545d 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -520,7 +520,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let source_info = self.source_info(span);
         let bool_ty = self.tcx.types.bool;
         if self.check_overflow && op.is_checkable() && ty.is_integral() {
-            let result_tup = self.tcx.intern_tup(&[ty, bool_ty]);
+            let result_tup = self.tcx.mk_tup(&[ty, bool_ty]);
             let result_value = self.temp(result_tup, span);
 
             self.cfg.push_assign(
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 6b960ebdb16..de2851a1af9 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -1206,7 +1206,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
                     fake_borrows.insert(Place {
                         local: source.local,
-                        projection: self.tcx.intern_place_elems(proj_base),
+                        projection: self.tcx.mk_place_elems(proj_base),
                     });
                 }
             }
@@ -1743,7 +1743,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             .map(|matched_place_ref| {
                 let matched_place = Place {
                     local: matched_place_ref.local,
-                    projection: tcx.intern_place_elems(matched_place_ref.projection),
+                    projection: tcx.mk_place_elems(matched_place_ref.projection),
                 };
                 let fake_borrow_deref_ty = matched_place.ty(&self.local_decls, tcx).ty;
                 let fake_borrow_ty = tcx.mk_imm_ref(tcx.lifetimes.re_erased, fake_borrow_deref_ty);
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index 8859f5002e4..2de89f67dfd 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -832,7 +832,7 @@ fn trait_method<'tcx>(
     tcx: TyCtxt<'tcx>,
     trait_def_id: DefId,
     method_name: Symbol,
-    substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
+    substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
 ) -> ConstantKind<'tcx> {
     // The unhygienic comparison here is acceptable because this is only
     // used on known traits.
diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs
index fbe08a7bd24..c34105174ef 100644
--- a/compiler/rustc_mir_build/src/build/matches/util.rs
+++ b/compiler/rustc_mir_build/src/build/matches/util.rs
@@ -5,7 +5,7 @@ use crate::build::Builder;
 use rustc_middle::mir::*;
 use rustc_middle::thir::*;
 use rustc_middle::ty;
-use rustc_middle::ty::TypeVisitable;
+use rustc_middle::ty::TypeVisitableExt;
 use smallvec::SmallVec;
 
 impl<'a, 'tcx> Builder<'a, 'tcx> {
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 933b1158fa6..a6de8684c0f 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -20,7 +20,7 @@ use rustc_middle::mir::*;
 use rustc_middle::thir::{
     self, BindingMode, Expr, ExprId, LintLevel, LocalVarId, Param, ParamId, PatKind, Thir,
 };
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable, TypeckResults};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypeckResults};
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 use rustc_span::Symbol;
@@ -639,7 +639,7 @@ fn construct_error(
     let hir_id = tcx.hir().local_def_id_to_hir_id(def);
     let generator_kind = tcx.generator_kind(def);
 
-    let ty = tcx.ty_error();
+    let ty = tcx.ty_error(err);
     let num_params = match body_owner_kind {
         hir::BodyOwnerKind::Fn => tcx.fn_sig(def).skip_binder().inputs().skip_binder().len(),
         hir::BodyOwnerKind::Closure => {
@@ -859,7 +859,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
                     let use_place = Place {
                         local: ty::CAPTURE_STRUCT_LOCAL,
-                        projection: tcx.intern_place_elems(&projs),
+                        projection: tcx.mk_place_elems(&projs),
                     };
                     self.var_debug_info.push(VarDebugInfo {
                         name: *sym,
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index ced251267d3..c1f6b8b59ce 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -1,9 +1,10 @@
-use crate::thir::pattern::deconstruct_pat::DeconstructedPat;
-use crate::thir::pattern::MatchCheckCtxt;
-use rustc_errors::Handler;
+use crate::{
+    fluent_generated as fluent,
+    thir::pattern::{deconstruct_pat::DeconstructedPat, MatchCheckCtxt},
+};
 use rustc_errors::{
     error_code, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
-    IntoDiagnostic, MultiSpan, SubdiagnosticMessage,
+    Handler, IntoDiagnostic, MultiSpan, SubdiagnosticMessage,
 };
 use rustc_hir::def::Res;
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
@@ -358,7 +359,7 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
     fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
         let mut diag = handler.struct_span_err_with_code(
             self.span,
-            rustc_errors::fluent::mir_build_non_exhaustive_patterns_type_not_empty,
+            fluent::mir_build_non_exhaustive_patterns_type_not_empty,
             error_code!(E0004),
         );
 
@@ -380,7 +381,7 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
             let mut span: MultiSpan = def_span.into();
             span.push_span_label(def_span, "");
 
-            diag.span_note(span, rustc_errors::fluent::def_note);
+            diag.span_note(span, fluent::mir_build_def_note);
         }
 
         let is_variant_list_non_exhaustive = match self.ty.kind() {
@@ -391,14 +392,14 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
         };
 
         if is_variant_list_non_exhaustive {
-            diag.note(rustc_errors::fluent::non_exhaustive_type_note);
+            diag.note(fluent::mir_build_non_exhaustive_type_note);
         } else {
-            diag.note(rustc_errors::fluent::type_note);
+            diag.note(fluent::mir_build_type_note);
         }
 
         if let ty::Ref(_, sub_ty, _) = self.ty.kind() {
             if !sub_ty.is_inhabited_from(self.cx.tcx, self.cx.module, self.cx.param_env) {
-                diag.note(rustc_errors::fluent::reference_note);
+                diag.note(fluent::mir_build_reference_note);
             }
         }
 
@@ -424,12 +425,12 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
         if let Some((span, sugg)) = suggestion {
             diag.span_suggestion_verbose(
                 span,
-                rustc_errors::fluent::suggestion,
+                fluent::mir_build_suggestion,
                 sugg,
                 Applicability::HasPlaceholders,
             );
         } else {
-            diag.help(rustc_errors::fluent::help);
+            diag.help(fluent::mir_build_help);
         }
 
         diag
@@ -469,7 +470,7 @@ pub struct NonConstPath {
 pub struct UnreachablePattern {
     #[label]
     pub span: Option<Span>,
-    #[label(catchall_label)]
+    #[label(mir_build_catchall_label)]
     pub catchall: Option<Span>,
 }
 
@@ -493,7 +494,7 @@ pub struct LowerRangeBoundMustBeLessThanOrEqualToUpper {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[note(teach_note)]
+    #[note(mir_build_teach_note)]
     pub teach: Option<()>,
 }
 
@@ -585,9 +586,9 @@ pub struct BorrowOfMovedValue<'tcx> {
     #[primary_span]
     pub span: Span,
     #[label]
-    #[label(occurs_because_label)]
+    #[label(mir_build_occurs_because_label)]
     pub binding_span: Span,
-    #[label(value_borrowed_label)]
+    #[label(mir_build_value_borrowed_label)]
     pub conflicts_ref: Vec<Span>,
     pub name: Ident,
     pub ty: Ty<'tcx>,
@@ -708,7 +709,7 @@ pub struct NontrivialStructuralMatch<'tcx> {
 #[diag(mir_build_overlapping_range_endpoints)]
 #[note]
 pub struct OverlappingRangeEndpoints<'tcx> {
-    #[label(range)]
+    #[label(mir_build_range)]
     pub range: Span,
     #[subdiagnostic]
     pub overlap: Vec<Overlap<'tcx>>,
@@ -788,7 +789,7 @@ pub(crate) struct PatternNotCovered<'s, 'tcx> {
     pub interpreted_as_const: Option<InterpretedAsConst>,
     #[subdiagnostic]
     pub adt_defined_here: Option<AdtDefinedHere<'tcx>>,
-    #[note(pattern_ty)]
+    #[note(mir_build_pattern_ty)]
     pub _p: (),
     pub pattern_ty: Ty<'tcx>,
     #[subdiagnostic]
@@ -823,10 +824,10 @@ impl<'tcx> AddToDiagnostic for AdtDefinedHere<'tcx> {
         let mut spans = MultiSpan::from(self.adt_def_span);
 
         for Variant { span } in self.variants {
-            spans.push_span_label(span, rustc_errors::fluent::mir_build_variant_defined_here);
+            spans.push_span_label(span, fluent::mir_build_variant_defined_here);
         }
 
-        diag.span_note(spans, rustc_errors::fluent::mir_build_adt_defined_here);
+        diag.span_note(spans, fluent::mir_build_adt_defined_here);
     }
 }
 
diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs
index 94dae36154c..fbc130501f9 100644
--- a/compiler/rustc_mir_build/src/lib.rs
+++ b/compiler/rustc_mir_build/src/lib.rs
@@ -25,6 +25,11 @@ pub mod thir;
 
 use rustc_middle::ty::query::Providers;
 
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_macros::fluent_messages;
+
+fluent_messages! { "../locales/en-US.ftl" }
+
 pub fn provide(providers: &mut Providers) {
     providers.check_match = thir::pattern::check_match;
     providers.lit_to_const = thir::constant::lit_to_const;
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 261b95ba95b..ae203233bd5 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -307,7 +307,7 @@ impl<'tcx> Cx<'tcx> {
 
                     let arg_tys = args.iter().map(|e| self.typeck_results().expr_ty_adjusted(e));
                     let tupled_args = Expr {
-                        ty: tcx.mk_tup(arg_tys),
+                        ty: tcx.mk_tup_from_iter(arg_tys),
                         temp_lifetime,
                         span: expr.span,
                         kind: ExprKind::Tuple { fields: self.mirror_exprs(args) },
@@ -758,7 +758,7 @@ impl<'tcx> Cx<'tcx> {
             hir::ExprKind::Tup(ref fields) => ExprKind::Tuple { fields: self.mirror_exprs(fields) },
 
             hir::ExprKind::Yield(ref v, _) => ExprKind::Yield { value: self.mirror_expr(v) },
-            hir::ExprKind::Err => unreachable!(),
+            hir::ExprKind::Err(_) => unreachable!(),
         };
 
         Expr { temp_lifetime, ty: expr_ty, span: expr.span, kind }
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index 74c35ef0fc2..20af60a511e 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -133,9 +133,8 @@ impl<'tcx> Cx<'tcx> {
                     bug!("closure expr does not have closure type: {:?}", closure_ty);
                 };
 
-                let bound_vars = self
-                    .tcx
-                    .intern_bound_variable_kinds(&[ty::BoundVariableKind::Region(ty::BrEnv)]);
+                let bound_vars =
+                    self.tcx.mk_bound_variable_kinds(&[ty::BoundVariableKind::Region(ty::BrEnv)]);
                 let br = ty::BoundRegion {
                     var: ty::BoundVar::from_usize(bound_vars.len() - 1),
                     kind: ty::BrEnv,
diff --git a/compiler/rustc_error_messages/locales/en-US/mir_dataflow.ftl b/compiler/rustc_mir_dataflow/locales/en-US.ftl
index 98854152508..98854152508 100644
--- a/compiler/rustc_error_messages/locales/en-US/mir_dataflow.ftl
+++ b/compiler/rustc_mir_dataflow/locales/en-US.ftl
diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs
index 077a21fc8af..2ae3ae02fcc 100644
--- a/compiler/rustc_mir_dataflow/src/framework/direction.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs
@@ -1,4 +1,3 @@
-use rustc_index::bit_set::BitSet;
 use rustc_middle::mir::{self, BasicBlock, Location, SwitchTargets};
 use rustc_middle::ty::TyCtxt;
 use std::ops::RangeInclusive;
@@ -54,7 +53,6 @@ pub trait Direction {
         analysis: &A,
         tcx: TyCtxt<'tcx>,
         body: &mir::Body<'tcx>,
-        dead_unwinds: Option<&BitSet<BasicBlock>>,
         exit_state: &mut A::Domain,
         block: (BasicBlock, &'_ mir::BasicBlockData<'tcx>),
         propagate: impl FnMut(BasicBlock, &A::Domain),
@@ -221,7 +219,6 @@ impl Direction for Backward {
         analysis: &A,
         _tcx: TyCtxt<'tcx>,
         body: &mir::Body<'tcx>,
-        dead_unwinds: Option<&BitSet<BasicBlock>>,
         exit_state: &mut A::Domain,
         (bb, _bb_data): (BasicBlock, &'_ mir::BasicBlockData<'tcx>),
         mut propagate: impl FnMut(BasicBlock, &A::Domain),
@@ -278,20 +275,6 @@ impl Direction for Backward {
                     }
                 }
 
-                // Ignore dead unwinds.
-                mir::TerminatorKind::Call { cleanup: Some(unwind), .. }
-                | mir::TerminatorKind::Assert { cleanup: Some(unwind), .. }
-                | mir::TerminatorKind::Drop { unwind: Some(unwind), .. }
-                | mir::TerminatorKind::DropAndReplace { unwind: Some(unwind), .. }
-                | mir::TerminatorKind::FalseUnwind { unwind: Some(unwind), .. }
-                | mir::TerminatorKind::InlineAsm { cleanup: Some(unwind), .. }
-                    if unwind == bb =>
-                {
-                    if dead_unwinds.map_or(true, |dead| !dead.contains(pred)) {
-                        propagate(pred, exit_state);
-                    }
-                }
-
                 _ => propagate(pred, exit_state),
             }
         }
@@ -304,7 +287,6 @@ struct BackwardSwitchIntEdgeEffectsApplier<'a, 'tcx, D, F> {
     exit_state: &'a mut D,
     bb: BasicBlock,
     propagate: &'a mut F,
-
     effects_applied: bool,
 }
 
@@ -484,7 +466,6 @@ impl Direction for Forward {
         analysis: &A,
         _tcx: TyCtxt<'tcx>,
         _body: &mir::Body<'tcx>,
-        dead_unwinds: Option<&BitSet<BasicBlock>>,
         exit_state: &mut A::Domain,
         (bb, bb_data): (BasicBlock, &'_ mir::BasicBlockData<'tcx>),
         mut propagate: impl FnMut(BasicBlock, &A::Domain),
@@ -502,9 +483,7 @@ impl Direction for Forward {
             | DropAndReplace { target, unwind, value: _, place: _ }
             | FalseUnwind { real_target: target, unwind } => {
                 if let Some(unwind) = unwind {
-                    if dead_unwinds.map_or(true, |dead| !dead.contains(bb)) {
-                        propagate(unwind, exit_state);
-                    }
+                    propagate(unwind, exit_state);
                 }
 
                 propagate(target, exit_state);
@@ -534,9 +513,7 @@ impl Direction for Forward {
                 fn_span: _,
             } => {
                 if let Some(unwind) = cleanup {
-                    if dead_unwinds.map_or(true, |dead| !dead.contains(bb)) {
-                        propagate(unwind, exit_state);
-                    }
+                    propagate(unwind, exit_state);
                 }
 
                 if let Some(target) = target {
@@ -560,9 +537,7 @@ impl Direction for Forward {
                 cleanup,
             } => {
                 if let Some(unwind) = cleanup {
-                    if dead_unwinds.map_or(true, |dead| !dead.contains(bb)) {
-                        propagate(unwind, exit_state);
-                    }
+                    propagate(unwind, exit_state);
                 }
 
                 if let Some(target) = destination {
diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs
index 6ddbe69e17e..91c3bf0ad21 100644
--- a/compiler/rustc_mir_dataflow/src/framework/engine.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs
@@ -12,7 +12,6 @@ use rustc_ast as ast;
 use rustc_data_structures::work_queue::WorkQueue;
 use rustc_graphviz as dot;
 use rustc_hir::def_id::DefId;
-use rustc_index::bit_set::BitSet;
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_middle::mir::{self, traversal, BasicBlock};
 use rustc_middle::mir::{create_dump_file, dump_enabled};
@@ -78,7 +77,6 @@ where
 {
     tcx: TyCtxt<'tcx>,
     body: &'a mir::Body<'tcx>,
-    dead_unwinds: Option<&'a BitSet<BasicBlock>>,
     entry_sets: IndexVec<BasicBlock, A::Domain>,
     pass_name: Option<&'static str>,
     analysis: A,
@@ -154,25 +152,7 @@ where
             bug!("`initialize_start_block` is not yet supported for backward dataflow analyses");
         }
 
-        Engine {
-            analysis,
-            tcx,
-            body,
-            dead_unwinds: None,
-            pass_name: None,
-            entry_sets,
-            apply_trans_for_block,
-        }
-    }
-
-    /// Signals that we do not want dataflow state to propagate across unwind edges for these
-    /// `BasicBlock`s.
-    ///
-    /// You must take care that `dead_unwinds` does not contain a `BasicBlock` that *can* actually
-    /// unwind during execution. Otherwise, your dataflow results will not be correct.
-    pub fn dead_unwinds(mut self, dead_unwinds: &'a BitSet<BasicBlock>) -> Self {
-        self.dead_unwinds = Some(dead_unwinds);
-        self
+        Engine { analysis, tcx, body, pass_name: None, entry_sets, apply_trans_for_block }
     }
 
     /// Adds an identifier to the graphviz output for this particular run of a dataflow analysis.
@@ -190,14 +170,7 @@ where
         A::Domain: DebugWithContext<A>,
     {
         let Engine {
-            analysis,
-            body,
-            dead_unwinds,
-            mut entry_sets,
-            tcx,
-            apply_trans_for_block,
-            pass_name,
-            ..
+            analysis, body, mut entry_sets, tcx, apply_trans_for_block, pass_name, ..
         } = self;
 
         let mut dirty_queue: WorkQueue<BasicBlock> = WorkQueue::with_none(body.basic_blocks.len());
@@ -236,7 +209,6 @@ where
                 &analysis,
                 tcx,
                 body,
-                dead_unwinds,
                 &mut state,
                 (bb, bb_data),
                 |target: BasicBlock, state: &A::Domain| {
diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs
index 3e382f500af..b1e03faff05 100644
--- a/compiler/rustc_mir_dataflow/src/lib.rs
+++ b/compiler/rustc_mir_dataflow/src/lib.rs
@@ -16,7 +16,9 @@ extern crate tracing;
 extern crate rustc_middle;
 
 use rustc_ast::MetaItem;
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
 use rustc_hir::def_id::DefId;
+use rustc_macros::fluent_messages;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::symbol::{sym, Symbol};
 
@@ -44,6 +46,8 @@ pub mod storage;
 pub mod un_derefer;
 pub mod value_analysis;
 
+fluent_messages! { "../locales/en-US.ftl" }
+
 pub(crate) mod indexes {
     pub(crate) use super::move_paths::MovePathIndex;
 }
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 6d30276aeab..4a163028fcf 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -126,7 +126,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                         BorrowedContent {
                             target_place: Place {
                                 local: place.local,
-                                projection: tcx.intern_place_elems(proj),
+                                projection: tcx.mk_place_elems(proj),
                             },
                         },
                     ));
@@ -165,7 +165,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             if union_path.is_none() {
                 base = self.add_move_path(base, elem, |tcx| Place {
                     local: place.local,
-                    projection: tcx.intern_place_elems(&place.projection[..i + 1]),
+                    projection: tcx.mk_place_elems(&place.projection[..i + 1]),
                 });
             }
         }
@@ -476,7 +476,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             // `ConstIndex` patterns. This is done to ensure that all move paths
             // are disjoint, which is expected by drop elaboration.
             let base_place =
-                Place { local: place.local, projection: self.builder.tcx.intern_place_elems(base) };
+                Place { local: place.local, projection: self.builder.tcx.mk_place_elems(base) };
             let base_path = match self.move_path_for(base_place) {
                 Ok(path) => path,
                 Err(MoveError::UnionMove { path }) => {
diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs
index 33ee90ffc11..6b2eefce24d 100644
--- a/compiler/rustc_mir_transform/src/const_prop.rs
+++ b/compiler/rustc_mir_transform/src/const_prop.rs
@@ -13,14 +13,10 @@ use rustc_index::vec::IndexVec;
 use rustc_middle::mir::visit::{
     MutVisitor, MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor,
 };
-use rustc_middle::mir::{
-    BasicBlock, BinOp, Body, Constant, ConstantKind, Local, LocalDecl, LocalKind, Location,
-    Operand, Place, Rvalue, SourceInfo, Statement, StatementKind, Terminator, TerminatorKind,
-    RETURN_PLACE,
-};
+use rustc_middle::mir::*;
 use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout};
 use rustc_middle::ty::InternalSubsts;
-use rustc_middle::ty::{self, ConstKind, Instance, ParamEnv, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, ConstKind, Instance, ParamEnv, Ty, TyCtxt, TypeVisitableExt};
 use rustc_span::{def_id::DefId, Span};
 use rustc_target::abi::{self, Align, HasDataLayout, Size, TargetDataLayout};
 use rustc_target::spec::abi::Abi as CallAbi;
@@ -456,27 +452,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         };
     }
 
-    fn use_ecx<F, T>(&mut self, f: F) -> Option<T>
-    where
-        F: FnOnce(&mut Self) -> InterpResult<'tcx, T>,
-    {
-        match f(self) {
-            Ok(val) => Some(val),
-            Err(error) => {
-                trace!("InterpCx operation failed: {:?}", error);
-                // Some errors shouldn't come up because creating them causes
-                // an allocation, which we should avoid. When that happens,
-                // dedicated error variants should be introduced instead.
-                assert!(
-                    !error.kind().formatted_string(),
-                    "const-prop encountered formatting error: {}",
-                    error
-                );
-                None
-            }
-        }
-    }
-
     /// Returns the value, if any, of evaluating `c`.
     fn eval_constant(&mut self, c: &Constant<'tcx>) -> Option<OpTy<'tcx>> {
         // FIXME we need to revisit this for #67176
@@ -491,7 +466,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
     /// Returns the value, if any, of evaluating `place`.
     fn eval_place(&mut self, place: Place<'tcx>) -> Option<OpTy<'tcx>> {
         trace!("eval_place(place={:?})", place);
-        self.use_ecx(|this| this.ecx.eval_place_to_op(place, None))
+        self.ecx.eval_place_to_op(place, None).ok()
     }
 
     /// Returns the value, if any, of evaluating `op`. Calls upon `eval_constant`
@@ -595,35 +570,37 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         rvalue: &Rvalue<'tcx>,
         place: Place<'tcx>,
     ) -> Option<()> {
-        self.use_ecx(|this| match rvalue {
+        match rvalue {
             Rvalue::BinaryOp(op, box (left, right))
             | Rvalue::CheckedBinaryOp(op, box (left, right)) => {
-                let l = this.ecx.eval_operand(left, None).and_then(|x| this.ecx.read_immediate(&x));
+                let l = self.ecx.eval_operand(left, None).and_then(|x| self.ecx.read_immediate(&x));
                 let r =
-                    this.ecx.eval_operand(right, None).and_then(|x| this.ecx.read_immediate(&x));
+                    self.ecx.eval_operand(right, None).and_then(|x| self.ecx.read_immediate(&x));
 
                 let const_arg = match (l, r) {
                     (Ok(x), Err(_)) | (Err(_), Ok(x)) => x, // exactly one side is known
-                    (Err(e), Err(_)) => return Err(e),      // neither side is known
-                    (Ok(_), Ok(_)) => return this.ecx.eval_rvalue_into_place(rvalue, place), // both sides are known
+                    (Err(_), Err(_)) => return None,        // neither side is known
+                    (Ok(_), Ok(_)) => return self.ecx.eval_rvalue_into_place(rvalue, place).ok(), // both sides are known
                 };
 
                 if !matches!(const_arg.layout.abi, abi::Abi::Scalar(..)) {
                     // We cannot handle Scalar Pair stuff.
                     // No point in calling `eval_rvalue_into_place`, since only one side is known
-                    throw_machine_stop_str!("cannot optimize this")
+                    return None;
                 }
 
-                let arg_value = const_arg.to_scalar().to_bits(const_arg.layout.size)?;
-                let dest = this.ecx.eval_place(place)?;
+                let arg_value = const_arg.to_scalar().to_bits(const_arg.layout.size).ok()?;
+                let dest = self.ecx.eval_place(place).ok()?;
 
                 match op {
-                    BinOp::BitAnd if arg_value == 0 => this.ecx.write_immediate(*const_arg, &dest),
+                    BinOp::BitAnd if arg_value == 0 => {
+                        self.ecx.write_immediate(*const_arg, &dest).ok()
+                    }
                     BinOp::BitOr
                         if arg_value == const_arg.layout.size.truncate(u128::MAX)
                             || (const_arg.layout.ty.is_bool() && arg_value == 1) =>
                     {
-                        this.ecx.write_immediate(*const_arg, &dest)
+                        self.ecx.write_immediate(*const_arg, &dest).ok()
                     }
                     BinOp::Mul if const_arg.layout.ty.is_integral() && arg_value == 0 => {
                         if let Rvalue::CheckedBinaryOp(_, _) = rvalue {
@@ -631,16 +608,16 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                                 const_arg.to_scalar(),
                                 Scalar::from_bool(false),
                             );
-                            this.ecx.write_immediate(val, &dest)
+                            self.ecx.write_immediate(val, &dest).ok()
                         } else {
-                            this.ecx.write_immediate(*const_arg, &dest)
+                            self.ecx.write_immediate(*const_arg, &dest).ok()
                         }
                     }
-                    _ => throw_machine_stop_str!("cannot optimize this"),
+                    _ => None,
                 }
             }
-            _ => this.ecx.eval_rvalue_into_place(rvalue, place),
-        })
+            _ => self.ecx.eval_rvalue_into_place(rvalue, place).ok(),
+        }
     }
 
     /// Creates a new `Operand::Constant` from a `Scalar` value
@@ -682,7 +659,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         }
 
         // FIXME> figure out what to do when read_immediate_raw fails
-        let imm = self.use_ecx(|this| this.ecx.read_immediate_raw(value));
+        let imm = self.ecx.read_immediate_raw(value).ok();
 
         if let Some(Right(imm)) = imm {
             match *imm {
@@ -702,25 +679,23 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                     if let ty::Tuple(types) = ty.kind() {
                         // Only do it if tuple is also a pair with two scalars
                         if let [ty1, ty2] = types[..] {
-                            let alloc = self.use_ecx(|this| {
-                                let ty_is_scalar = |ty| {
-                                    this.ecx.layout_of(ty).ok().map(|layout| layout.abi.is_scalar())
-                                        == Some(true)
-                                };
-                                if ty_is_scalar(ty1) && ty_is_scalar(ty2) {
-                                    let alloc = this
-                                        .ecx
-                                        .intern_with_temp_alloc(value.layout, |ecx, dest| {
-                                            ecx.write_immediate(*imm, dest)
-                                        })
-                                        .unwrap();
-                                    Ok(Some(alloc))
-                                } else {
-                                    Ok(None)
-                                }
-                            });
-
-                            if let Some(Some(alloc)) = alloc {
+                            let ty_is_scalar = |ty| {
+                                self.ecx.layout_of(ty).ok().map(|layout| layout.abi.is_scalar())
+                                    == Some(true)
+                            };
+                            let alloc = if ty_is_scalar(ty1) && ty_is_scalar(ty2) {
+                                let alloc = self
+                                    .ecx
+                                    .intern_with_temp_alloc(value.layout, |ecx, dest| {
+                                        ecx.write_immediate(*imm, dest)
+                                    })
+                                    .unwrap();
+                                Some(alloc)
+                            } else {
+                                None
+                            };
+
+                            if let Some(alloc) = alloc {
                                 // Assign entire constant in a single statement.
                                 // We can't use aggregates, as we run after the aggregate-lowering `MirPhase`.
                                 let const_val = ConstValue::ByRef { alloc, offset: Size::ZERO };
@@ -921,84 +896,80 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
         trace!("visit_statement: {:?}", statement);
         let source_info = statement.source_info;
         self.source_info = Some(source_info);
-        if let StatementKind::Assign(box (place, ref mut rval)) = statement.kind {
-            let can_const_prop = self.ecx.machine.can_const_prop[place.local];
-            if let Some(()) = self.const_prop(rval, place) {
-                // This will return None if the above `const_prop` invocation only "wrote" a
-                // type whose creation requires no write. E.g. a generator whose initial state
-                // consists solely of uninitialized memory (so it doesn't capture any locals).
-                if let Some(ref value) = self.get_const(place) && self.should_const_prop(value) {
-                    trace!("replacing {:?} with {:?}", rval, value);
-                    self.replace_with_const(rval, value, source_info);
-                    if can_const_prop == ConstPropMode::FullConstProp
-                        || can_const_prop == ConstPropMode::OnlyInsideOwnBlock
-                    {
-                        trace!("propagated into {:?}", place);
+        match statement.kind {
+            StatementKind::Assign(box (place, ref mut rval)) => {
+                let can_const_prop = self.ecx.machine.can_const_prop[place.local];
+                if let Some(()) = self.const_prop(rval, place) {
+                    // This will return None if the above `const_prop` invocation only "wrote" a
+                    // type whose creation requires no write. E.g. a generator whose initial state
+                    // consists solely of uninitialized memory (so it doesn't capture any locals).
+                    if let Some(ref value) = self.get_const(place) && self.should_const_prop(value) {
+                        trace!("replacing {:?} with {:?}", rval, value);
+                        self.replace_with_const(rval, value, source_info);
+                        if can_const_prop == ConstPropMode::FullConstProp
+                            || can_const_prop == ConstPropMode::OnlyInsideOwnBlock
+                        {
+                            trace!("propagated into {:?}", place);
+                        }
                     }
-                }
-                match can_const_prop {
-                    ConstPropMode::OnlyInsideOwnBlock => {
-                        trace!(
-                            "found local restricted to its block. \
+                    match can_const_prop {
+                        ConstPropMode::OnlyInsideOwnBlock => {
+                            trace!(
+                                "found local restricted to its block. \
                                 Will remove it from const-prop after block is finished. Local: {:?}",
-                            place.local
-                        );
-                    }
-                    ConstPropMode::OnlyPropagateInto | ConstPropMode::NoPropagation => {
-                        trace!("can't propagate into {:?}", place);
-                        if place.local != RETURN_PLACE {
-                            Self::remove_const(&mut self.ecx, place.local);
+                                place.local
+                            );
                         }
-                    }
-                    ConstPropMode::FullConstProp => {}
-                }
-            } else {
-                // Const prop failed, so erase the destination, ensuring that whatever happens
-                // from here on, does not know about the previous value.
-                // This is important in case we have
-                // ```rust
-                // let mut x = 42;
-                // x = SOME_MUTABLE_STATIC;
-                // // x must now be uninit
-                // ```
-                // FIXME: we overzealously erase the entire local, because that's easier to
-                // implement.
-                trace!(
-                    "propagation into {:?} failed.
-                        Nuking the entire site from orbit, it's the only way to be sure",
-                    place,
-                );
-                Self::remove_const(&mut self.ecx, place.local);
-            }
-        } else {
-            match statement.kind {
-                StatementKind::SetDiscriminant { ref place, .. } => {
-                    match self.ecx.machine.can_const_prop[place.local] {
-                        ConstPropMode::FullConstProp | ConstPropMode::OnlyInsideOwnBlock => {
-                            if self.use_ecx(|this| this.ecx.statement(statement)).is_some() {
-                                trace!("propped discriminant into {:?}", place);
-                            } else {
+                        ConstPropMode::OnlyPropagateInto | ConstPropMode::NoPropagation => {
+                            trace!("can't propagate into {:?}", place);
+                            if place.local != RETURN_PLACE {
                                 Self::remove_const(&mut self.ecx, place.local);
                             }
                         }
-                        ConstPropMode::OnlyPropagateInto | ConstPropMode::NoPropagation => {
-                            Self::remove_const(&mut self.ecx, place.local);
-                        }
+                        ConstPropMode::FullConstProp => {}
                     }
+                } else {
+                    // Const prop failed, so erase the destination, ensuring that whatever happens
+                    // from here on, does not know about the previous value.
+                    // This is important in case we have
+                    // ```rust
+                    // let mut x = 42;
+                    // x = SOME_MUTABLE_STATIC;
+                    // // x must now be uninit
+                    // ```
+                    // FIXME: we overzealously erase the entire local, because that's easier to
+                    // implement.
+                    trace!(
+                        "propagation into {:?} failed.
+                        Nuking the entire site from orbit, it's the only way to be sure",
+                        place,
+                    );
+                    Self::remove_const(&mut self.ecx, place.local);
                 }
-                StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => {
-                    let frame = self.ecx.frame_mut();
-                    frame.locals[local].value =
-                        if let StatementKind::StorageLive(_) = statement.kind {
-                            LocalValue::Live(interpret::Operand::Immediate(
-                                interpret::Immediate::Uninit,
-                            ))
+            }
+            StatementKind::SetDiscriminant { ref place, .. } => {
+                match self.ecx.machine.can_const_prop[place.local] {
+                    ConstPropMode::FullConstProp | ConstPropMode::OnlyInsideOwnBlock => {
+                        if self.ecx.statement(statement).is_ok() {
+                            trace!("propped discriminant into {:?}", place);
                         } else {
-                            LocalValue::Dead
-                        };
+                            Self::remove_const(&mut self.ecx, place.local);
+                        }
+                    }
+                    ConstPropMode::OnlyPropagateInto | ConstPropMode::NoPropagation => {
+                        Self::remove_const(&mut self.ecx, place.local);
+                    }
                 }
-                _ => {}
             }
+            StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => {
+                let frame = self.ecx.frame_mut();
+                frame.locals[local].value = if let StatementKind::StorageLive(_) = statement.kind {
+                    LocalValue::Live(interpret::Operand::Immediate(interpret::Immediate::Uninit))
+                } else {
+                    LocalValue::Dead
+                };
+            }
+            _ => {}
         }
 
         self.super_statement(statement, location);
@@ -1008,12 +979,10 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
         let source_info = terminator.source_info;
         self.source_info = Some(source_info);
         self.super_terminator(terminator, location);
-        // Do NOT early return in this function, it does some crucial fixup of the state at the end!
+
         match &mut terminator.kind {
             TerminatorKind::Assert { expected, ref mut cond, .. } => {
                 if let Some(ref value) = self.eval_operand(&cond)
-                    // FIXME should be used use_ecx rather than a local match... but we have
-                    // quite a few of these read_scalar/read_immediate that need fixing.
                     && let Ok(value_const) = self.ecx.read_scalar(&value)
                     && self.should_const_prop(value)
                 {
@@ -1050,6 +1019,10 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
             // gated on `mir_opt_level=3`.
             TerminatorKind::Call { .. } => {}
         }
+    }
+
+    fn visit_basic_block_data(&mut self, block: BasicBlock, data: &mut BasicBlockData<'tcx>) {
+        self.super_basic_block_data(block, data);
 
         // We remove all Locals which are restricted in propagation to their containing blocks and
         // which were modified in the current block.
diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs
index be41d611fe4..6c1980ff3ad 100644
--- a/compiler/rustc_mir_transform/src/const_prop_lint.rs
+++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs
@@ -21,7 +21,9 @@ use rustc_middle::mir::{
 };
 use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout};
 use rustc_middle::ty::InternalSubsts;
-use rustc_middle::ty::{self, ConstInt, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{
+    self, ConstInt, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitableExt,
+};
 use rustc_session::lint;
 use rustc_span::Span;
 use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout};
diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs
index c57ec137d4b..f27beb64a14 100644
--- a/compiler/rustc_mir_transform/src/copy_prop.rs
+++ b/compiler/rustc_mir_transform/src/copy_prop.rs
@@ -124,7 +124,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
 
     fn visit_place(&mut self, place: &mut Place<'tcx>, ctxt: PlaceContext, loc: Location) {
         if let Some(new_projection) = self.process_projection(&place.projection, loc) {
-            place.projection = self.tcx().intern_place_elems(&new_projection);
+            place.projection = self.tcx().mk_place_elems(&new_projection);
         }
 
         let observes_address = match ctxt {
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index 19019e3ef74..49ded10ba1f 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -122,7 +122,10 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
     ) {
         match rvalue {
             Rvalue::Aggregate(kind, operands) => {
-                state.flood_with(target.as_ref(), self.map(), FlatSet::Bottom);
+                // If we assign `target = Enum::Variant#0(operand)`,
+                // we must make sure that all `target as Variant#i` are `Top`.
+                state.flood(target.as_ref(), self.map());
+
                 if let Some(target_idx) = self.map().find(target.as_ref()) {
                     let (variant_target, variant_index) = match **kind {
                         AggregateKind::Tuple | AggregateKind::Closure(..) => {
@@ -131,18 +134,21 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
                         AggregateKind::Adt(def_id, variant_index, ..) => {
                             match self.tcx.def_kind(def_id) {
                                 DefKind::Struct => (Some(target_idx), None),
-                                DefKind::Enum => (Some(target_idx), Some(variant_index)),
+                                DefKind::Enum => (
+                                    self.map.apply(target_idx, TrackElem::Variant(variant_index)),
+                                    Some(variant_index),
+                                ),
                                 _ => (None, None),
                             }
                         }
                         _ => (None, None),
                     };
-                    if let Some(target) = variant_target {
+                    if let Some(variant_target_idx) = variant_target {
                         for (field_index, operand) in operands.iter().enumerate() {
-                            if let Some(field) = self
-                                .map()
-                                .apply(target, TrackElem::Field(Field::from_usize(field_index)))
-                            {
+                            if let Some(field) = self.map().apply(
+                                variant_target_idx,
+                                TrackElem::Field(Field::from_usize(field_index)),
+                            ) {
                                 let result = self.handle_operand(operand, state);
                                 state.insert_idx(field, result, self.map());
                             }
@@ -151,6 +157,11 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
                     if let Some(variant_index) = variant_index
                         && let Some(discr_idx) = self.map().apply(target_idx, TrackElem::Discriminant)
                     {
+                        // We are assigning the discriminant as part of an aggregate.
+                        // This discriminant can only alias a variant field's value if the operand
+                        // had an invalid value for that type.
+                        // Using invalid values is UB, so we are allowed to perform the assignment
+                        // without extra flooding.
                         let enum_ty = target.ty(self.local_decls, self.tcx).ty;
                         if let Some(discr_val) = self.eval_discriminant(enum_ty, variant_index) {
                             state.insert_value_idx(discr_idx, FlatSet::Elem(discr_val), &self.map);
diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
index dc583471c89..954bb5aff8d 100644
--- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
@@ -17,7 +17,7 @@ pub fn build_ptr_tys<'tcx>(
     unique_did: DefId,
     nonnull_did: DefId,
 ) -> (Ty<'tcx>, Ty<'tcx>, Ty<'tcx>) {
-    let substs = tcx.intern_substs(&[pointee.into()]);
+    let substs = tcx.mk_substs(&[pointee.into()]);
     let unique_ty = tcx.type_of(unique_did).subst(tcx, substs);
     let nonnull_ty = tcx.type_of(nonnull_did).subst(tcx, substs);
     let ptr_ty = tcx.mk_imm_ptr(pointee);
@@ -138,7 +138,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs {
 
                     if let Some(mut new_projections) = new_projections {
                         new_projections.extend_from_slice(&place.projection[last_deref..]);
-                        place.projection = tcx.intern_place_elems(&new_projections);
+                        place.projection = tcx.mk_place_elems(&new_projections);
                     }
                 }
             }
diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs
index c2ff8645635..bdfd8dc6e99 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs
@@ -67,13 +67,11 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
         };
         let un_derefer = UnDerefer { tcx: tcx, derefer_sidetable: side_table };
         let elaborate_patch = {
-            let body = &*body;
             let env = MoveDataParamEnv { move_data, param_env };
-            let dead_unwinds = find_dead_unwinds(tcx, body, &env, &un_derefer);
+            remove_dead_unwinds(tcx, body, &env, &un_derefer);
 
             let inits = MaybeInitializedPlaces::new(tcx, body, &env)
                 .into_engine(tcx, body)
-                .dead_unwinds(&dead_unwinds)
                 .pass_name("elaborate_drops")
                 .iterate_to_fixpoint()
                 .into_results_cursor(body);
@@ -81,11 +79,12 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
             let uninits = MaybeUninitializedPlaces::new(tcx, body, &env)
                 .mark_inactive_variants_as_uninit()
                 .into_engine(tcx, body)
-                .dead_unwinds(&dead_unwinds)
                 .pass_name("elaborate_drops")
                 .iterate_to_fixpoint()
                 .into_results_cursor(body);
 
+            let reachable = traversal::reachable_as_bitset(body);
+
             ElaborateDropsCtxt {
                 tcx,
                 body,
@@ -94,6 +93,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
                 drop_flags: Default::default(),
                 patch: MirPatch::new(body),
                 un_derefer: un_derefer,
+                reachable,
             }
             .elaborate()
         };
@@ -102,22 +102,21 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
     }
 }
 
-/// Returns the set of basic blocks whose unwind edges are known
-/// to not be reachable, because they are `drop` terminators
+/// Removes unwind edges which are known to be unreachable, because they are in `drop` terminators
 /// that can't drop anything.
-fn find_dead_unwinds<'tcx>(
+fn remove_dead_unwinds<'tcx>(
     tcx: TyCtxt<'tcx>,
-    body: &Body<'tcx>,
+    body: &mut Body<'tcx>,
     env: &MoveDataParamEnv<'tcx>,
     und: &UnDerefer<'tcx>,
-) -> BitSet<BasicBlock> {
-    debug!("find_dead_unwinds({:?})", body.span);
+) {
+    debug!("remove_dead_unwinds({:?})", body.span);
     // We only need to do this pass once, because unwind edges can only
     // reach cleanup blocks, which can't have unwind edges themselves.
-    let mut dead_unwinds = BitSet::new_empty(body.basic_blocks.len());
+    let mut dead_unwinds = Vec::new();
     let mut flow_inits = MaybeInitializedPlaces::new(tcx, body, &env)
         .into_engine(tcx, body)
-        .pass_name("find_dead_unwinds")
+        .pass_name("remove_dead_unwinds")
         .iterate_to_fixpoint()
         .into_results_cursor(body);
     for (bb, bb_data) in body.basic_blocks.iter_enumerated() {
@@ -129,16 +128,16 @@ fn find_dead_unwinds<'tcx>(
             _ => continue,
         };
 
-        debug!("find_dead_unwinds @ {:?}: {:?}", bb, bb_data);
+        debug!("remove_dead_unwinds @ {:?}: {:?}", bb, bb_data);
 
         let LookupResult::Exact(path) = env.move_data.rev_lookup.find(place.as_ref()) else {
-            debug!("find_dead_unwinds: has parent; skipping");
+            debug!("remove_dead_unwinds: has parent; skipping");
             continue;
         };
 
         flow_inits.seek_before_primary_effect(body.terminator_loc(bb));
         debug!(
-            "find_dead_unwinds @ {:?}: path({:?})={:?}; init_data={:?}",
+            "remove_dead_unwinds @ {:?}: path({:?})={:?}; init_data={:?}",
             bb,
             place,
             path,
@@ -150,13 +149,22 @@ fn find_dead_unwinds<'tcx>(
             maybe_live |= flow_inits.contains(child);
         });
 
-        debug!("find_dead_unwinds @ {:?}: maybe_live={}", bb, maybe_live);
+        debug!("remove_dead_unwinds @ {:?}: maybe_live={}", bb, maybe_live);
         if !maybe_live {
-            dead_unwinds.insert(bb);
+            dead_unwinds.push(bb);
         }
     }
 
-    dead_unwinds
+    if dead_unwinds.is_empty() {
+        return;
+    }
+
+    let basic_blocks = body.basic_blocks.as_mut();
+    for &bb in dead_unwinds.iter() {
+        if let Some(unwind) = basic_blocks[bb].terminator_mut().unwind_mut() {
+            *unwind = None;
+        }
+    }
 }
 
 struct InitializationData<'mir, 'tcx> {
@@ -290,6 +298,7 @@ struct ElaborateDropsCtxt<'a, 'tcx> {
     drop_flags: FxHashMap<MovePathIndex, Local>,
     patch: MirPatch<'tcx>,
     un_derefer: UnDerefer<'tcx>,
+    reachable: BitSet<BasicBlock>,
 }
 
 impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
@@ -329,6 +338,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
 
     fn collect_drop_flags(&mut self) {
         for (bb, data) in self.body.basic_blocks.iter_enumerated() {
+            if !self.reachable.contains(bb) {
+                continue;
+            }
             let terminator = data.terminator();
             let place = match terminator.kind {
                 TerminatorKind::Drop { ref place, .. }
@@ -384,6 +396,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
 
     fn elaborate_drops(&mut self) {
         for (bb, data) in self.body.basic_blocks.iter_enumerated() {
+            if !self.reachable.contains(bb) {
+                continue;
+            }
             let loc = Location { block: bb, statement_index: data.statements.len() };
             let terminator = data.terminator();
 
@@ -541,6 +556,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
 
     fn drop_flags_for_fn_rets(&mut self) {
         for (bb, data) in self.body.basic_blocks.iter_enumerated() {
+            if !self.reachable.contains(bb) {
+                continue;
+            }
             if let TerminatorKind::Call {
                 destination, target: Some(tgt), cleanup: Some(_), ..
             } = data.terminator().kind
@@ -576,6 +594,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
         // clobbered before they are read.
 
         for (bb, data) in self.body.basic_blocks.iter_enumerated() {
+            if !self.reachable.contains(bb) {
+                continue;
+            }
             debug!("drop_flags_for_locs({:?})", data);
             for i in 0..(data.statements.len() + 1) {
                 debug!("drop_flag_for_locs: stmt {}", i);
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index dc5f88f24f8..2e97312ee50 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -126,7 +126,7 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor<'tcx> {
                 place,
                 Place {
                     local: SELF_ARG,
-                    projection: self.tcx().intern_place_elems(&[ProjectionElem::Deref]),
+                    projection: self.tcx().mk_place_elems(&[ProjectionElem::Deref]),
                 },
                 self.tcx,
             );
@@ -162,10 +162,9 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> {
                 place,
                 Place {
                     local: SELF_ARG,
-                    projection: self.tcx().intern_place_elems(&[ProjectionElem::Field(
-                        Field::new(0),
-                        self.ref_gen_ty,
-                    )]),
+                    projection: self
+                        .tcx()
+                        .mk_place_elems(&[ProjectionElem::Field(Field::new(0), self.ref_gen_ty)]),
                 },
                 self.tcx,
             );
@@ -187,7 +186,7 @@ fn replace_base<'tcx>(place: &mut Place<'tcx>, new_base: Place<'tcx>, tcx: TyCtx
     let mut new_projection = new_base.projection.to_vec();
     new_projection.append(&mut place.projection.to_vec());
 
-    place.projection = tcx.intern_place_elems(&new_projection);
+    place.projection = tcx.mk_place_elems(&new_projection);
 }
 
 const SELF_ARG: Local = Local::from_u32(1);
@@ -300,7 +299,7 @@ impl<'tcx> TransformVisitor<'tcx> {
         let mut projection = base.projection.to_vec();
         projection.push(ProjectionElem::Field(Field::new(idx), ty));
 
-        Place { local: base.local, projection: self.tcx.intern_place_elems(&projection) }
+        Place { local: base.local, projection: self.tcx.mk_place_elems(&projection) }
     }
 
     // Create a statement which changes the discriminant
@@ -427,7 +426,7 @@ fn make_generator_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body
 
     let pin_did = tcx.require_lang_item(LangItem::Pin, Some(body.span));
     let pin_adt_ref = tcx.adt_def(pin_did);
-    let substs = tcx.intern_substs(&[ref_gen_ty.into()]);
+    let substs = tcx.mk_substs(&[ref_gen_ty.into()]);
     let pin_ref_gen_ty = tcx.mk_adt(pin_adt_ref, substs);
 
     // Replace the by ref generator argument
@@ -1450,13 +1449,13 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
             // Compute Poll<return_ty>
             let poll_did = tcx.require_lang_item(LangItem::Poll, None);
             let poll_adt_ref = tcx.adt_def(poll_did);
-            let poll_substs = tcx.intern_substs(&[body.return_ty().into()]);
+            let poll_substs = tcx.mk_substs(&[body.return_ty().into()]);
             (poll_adt_ref, poll_substs)
         } else {
             // Compute GeneratorState<yield_ty, return_ty>
             let state_did = tcx.require_lang_item(LangItem::GeneratorState, None);
             let state_adt_ref = tcx.adt_def(state_did);
-            let state_substs = tcx.intern_substs(&[yield_ty.into(), body.return_ty().into()]);
+            let state_substs = tcx.mk_substs(&[yield_ty.into(), body.return_ty().into()]);
             (state_adt_ref, state_substs)
         };
         let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 8c6b0463a73..6e6d6566f4b 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -888,7 +888,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
         location: Location,
     ) {
         if let ProjectionElem::Field(f, ty) = elem {
-            let parent = Place { local, projection: self.tcx.intern_place_elems(proj_base) };
+            let parent = Place { local, projection: self.tcx.mk_place_elems(proj_base) };
             let parent_ty = parent.ty(&self.callee_body.local_decls, self.tcx);
             let check_equal = |this: &mut Self, f_ty| {
                 if !util::is_equal_up_to_subtyping(this.tcx, this.param_env, ty, f_ty) {
diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs
index b027f94925d..792457c80b0 100644
--- a/compiler/rustc_mir_transform/src/inline/cycle.rs
+++ b/compiler/rustc_mir_transform/src/inline/cycle.rs
@@ -2,7 +2,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::mir::TerminatorKind;
-use rustc_middle::ty::TypeVisitable;
+use rustc_middle::ty::TypeVisitableExt;
 use rustc_middle::ty::{self, subst::SubstsRef, InstanceDef, TyCtxt};
 use rustc_session::Limit;
 
diff --git a/compiler/rustc_mir_transform/src/instcombine.rs b/compiler/rustc_mir_transform/src/instcombine.rs
index 0534e688703..14e644bc344 100644
--- a/compiler/rustc_mir_transform/src/instcombine.rs
+++ b/compiler/rustc_mir_transform/src/instcombine.rs
@@ -30,6 +30,7 @@ impl<'tcx> MirPass<'tcx> for InstCombine {
                         ctx.combine_bool_cmp(&statement.source_info, rvalue);
                         ctx.combine_ref_deref(&statement.source_info, rvalue);
                         ctx.combine_len(&statement.source_info, rvalue);
+                        ctx.combine_cast(&statement.source_info, rvalue);
                     }
                     _ => {}
                 }
@@ -120,7 +121,7 @@ impl<'tcx> InstCombineContext<'tcx, '_> {
 
                 *rvalue = Rvalue::Use(Operand::Copy(Place {
                     local: base.local,
-                    projection: self.tcx.intern_place_elems(base.projection),
+                    projection: self.tcx.mk_place_elems(base.projection),
                 }));
             }
         }
@@ -142,6 +143,14 @@ impl<'tcx> InstCombineContext<'tcx, '_> {
         }
     }
 
+    fn combine_cast(&self, _source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
+        if let Rvalue::Cast(_kind, operand, ty) = rvalue {
+            if operand.ty(self.local_decls, self.tcx) == *ty {
+                *rvalue = Rvalue::Use(operand.clone());
+            }
+        }
+    }
+
     fn combine_primitive_clone(
         &self,
         terminator: &mut Terminator<'tcx>,
diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs
index 2ca33a624e2..89e0a007dac 100644
--- a/compiler/rustc_mir_transform/src/large_enums.rs
+++ b/compiler/rustc_mir_transform/src/large_enums.rs
@@ -114,7 +114,7 @@ impl EnumSizeOpt {
             tcx.data_layout.ptr_sized_integer().align(&tcx.data_layout).abi,
             Mutability::Not,
         );
-        let alloc = tcx.create_memory_alloc(tcx.intern_const_alloc(alloc));
+        let alloc = tcx.create_memory_alloc(tcx.mk_const_alloc(alloc));
         Some((*adt_def, num_discrs, *alloc_cache.entry(ty).or_insert(alloc)))
     }
     fn optim<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
@@ -197,9 +197,8 @@ impl EnumSizeOpt {
                             size_place,
                             Rvalue::Use(Operand::Copy(Place {
                                 local: size_array_local,
-                                projection: tcx.intern_place_elems(&[PlaceElem::Index(
-                                    discr_cast_place.local,
-                                )]),
+                                projection: tcx
+                                    .mk_place_elems(&[PlaceElem::Index(discr_cast_place.local)]),
                             })),
                         )),
                     };
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 45cd4024c9f..4193eb7d6e8 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -35,7 +35,7 @@ use rustc_middle::mir::{
     TerminatorKind,
 };
 use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
 use rustc_span::sym;
 
 #[macro_use]
@@ -192,7 +192,7 @@ fn remap_mir_for_const_eval_select<'tcx>(
                 let arguments = (0..num_args).map(|x| {
                     let mut place_elems = place_elems.to_vec();
                     place_elems.push(ProjectionElem::Field(x.into(), fields[x]));
-                    let projection = tcx.intern_place_elems(&place_elems);
+                    let projection = tcx.mk_place_elems(&place_elems);
                     let place = Place {
                         local: place.local,
                         projection,
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index 682ad081f5c..ebe63d6cb7e 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -147,7 +147,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
     assert!(!matches!(ty, Some(ty) if ty.is_generator()));
 
     let substs = if let Some(ty) = ty {
-        tcx.intern_substs(&[ty.into()])
+        tcx.mk_substs(&[ty.into()])
     } else {
         InternalSubsts::identity_for_item(tcx, def_id)
     };
@@ -597,7 +597,7 @@ fn build_call_shim<'tcx>(
         let untuple_args = sig.inputs();
 
         // Create substitutions for the `Self` and `Args` generic parameters of the shim body.
-        let arg_tup = tcx.intern_tup(untuple_args);
+        let arg_tup = tcx.mk_tup(untuple_args);
 
         (Some([ty.into(), arg_tup.into()]), Some(untuple_args))
     } else {
@@ -632,7 +632,7 @@ fn build_call_shim<'tcx>(
             Adjustment::Deref => tcx.mk_imm_ptr(fnty),
             Adjustment::RefMut => tcx.mk_mut_ptr(fnty),
         };
-        sig.inputs_and_output = tcx.intern_type_list(&inputs_and_output);
+        sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
     }
 
     // FIXME(eddyb) avoid having this snippet both here and in
@@ -643,7 +643,7 @@ fn build_call_shim<'tcx>(
         let self_arg = &mut inputs_and_output[0];
         debug_assert!(tcx.generics_of(def_id).has_self && *self_arg == tcx.types.self_param);
         *self_arg = tcx.mk_mut_ptr(*self_arg);
-        sig.inputs_and_output = tcx.intern_type_list(&inputs_and_output);
+        sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
     }
 
     let span = tcx.def_span(def_id);
diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs
index 8a37423b2a0..13168e9a268 100644
--- a/compiler/rustc_mir_transform/src/sroa.rs
+++ b/compiler/rustc_mir_transform/src/sroa.rs
@@ -122,7 +122,7 @@ impl<'tcx> ReplacementMap<'tcx> {
         let &[PlaceElem::Field(f, _), ref rest @ ..] = place.projection else { return None; };
         let fields = self.fragments[place.local].as_ref()?;
         let (_, new_local) = fields[f]?;
-        Some(Place { local: new_local, projection: tcx.intern_place_elems(&rest) })
+        Some(Place { local: new_local, projection: tcx.mk_place_elems(&rest) })
     }
 
     fn place_fragments(
diff --git a/compiler/rustc_error_messages/locales/en-US/monomorphize.ftl b/compiler/rustc_monomorphize/locales/en-US.ftl
index 6cea6a603f3..6cea6a603f3 100644
--- a/compiler/rustc_error_messages/locales/en-US/monomorphize.ftl
+++ b/compiler/rustc_monomorphize/locales/en-US.ftl
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 55a9f912e08..45e659eab6c 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -189,7 +189,9 @@ use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCast};
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::query::TyCtxtAt;
 use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
-use rustc_middle::ty::{self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable, VtblEntry};
+use rustc_middle::ty::{
+    self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, VtblEntry,
+};
 use rustc_middle::{middle::codegen_fn_attrs::CodegenFnAttrFlags, mir::visit::TyContext};
 use rustc_session::config::EntryFnType;
 use rustc_session::lint::builtin::LARGE_ASSIGNMENTS;
@@ -658,7 +660,7 @@ struct MirNeighborCollector<'a, 'tcx> {
 impl<'a, 'tcx> MirNeighborCollector<'a, 'tcx> {
     pub fn monomorphize<T>(&self, value: T) -> T
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         debug!("monomorphize: self.instance={:?}", self.instance);
         self.instance.subst_mir_and_normalize_erasing_regions(
@@ -1296,7 +1298,7 @@ impl<'v> RootCollector<'_, 'v> {
             self.tcx,
             ty::ParamEnv::reveal_all(),
             start_def_id,
-            self.tcx.intern_substs(&[main_ret_ty.into()]),
+            self.tcx.mk_substs(&[main_ret_ty.into()]),
         )
         .unwrap()
         .unwrap();
diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs
index a53bd7e1fef..495a73490a2 100644
--- a/compiler/rustc_monomorphize/src/errors.rs
+++ b/compiler/rustc_monomorphize/src/errors.rs
@@ -1,5 +1,6 @@
 use std::path::PathBuf;
 
+use crate::fluent_generated as fluent;
 use rustc_errors::ErrorGuaranteed;
 use rustc_errors::IntoDiagnostic;
 use rustc_macros::{Diagnostic, LintDiagnostic};
@@ -44,7 +45,7 @@ impl IntoDiagnostic<'_> for UnusedGenericParamsHint {
         self,
         handler: &'_ rustc_errors::Handler,
     ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
-        let mut diag = handler.struct_err(rustc_errors::fluent::monomorphize_unused_generic_params);
+        let mut diag = handler.struct_err(fluent::monomorphize_unused_generic_params);
         diag.set_span(self.span);
         for (span, name) in self.param_spans.into_iter().zip(self.param_names) {
             // FIXME: I can figure out how to do a label with a fluent string with a fixed message,
diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs
index f88155e4fc7..f6b791f29c1 100644
--- a/compiler/rustc_monomorphize/src/lib.rs
+++ b/compiler/rustc_monomorphize/src/lib.rs
@@ -9,7 +9,9 @@ extern crate tracing;
 #[macro_use]
 extern crate rustc_middle;
 
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
 use rustc_hir::lang_items::LangItem;
+use rustc_macros::fluent_messages;
 use rustc_middle::traits;
 use rustc_middle::ty::adjustment::CustomCoerceUnsized;
 use rustc_middle::ty::query::{Providers, TyCtxtAt};
@@ -21,6 +23,8 @@ mod partitioning;
 mod polymorphize;
 mod util;
 
+fluent_messages! { "../locales/en-US.ftl" }
+
 fn custom_coerce_unsize_info<'tcx>(
     tcx: TyCtxtAt<'tcx>,
     source_ty: Ty<'tcx>,
diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs
index 62bafb981e7..2c56edd89bc 100644
--- a/compiler/rustc_monomorphize/src/partitioning/default.rs
+++ b/compiler/rustc_monomorphize/src/partitioning/default.rs
@@ -9,7 +9,7 @@ use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel
 use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, Linkage, Visibility};
 use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
 use rustc_middle::ty::print::characteristic_def_id_of_type;
-use rustc_middle::ty::{self, visit::TypeVisitable, DefIdTree, InstanceDef, TyCtxt};
+use rustc_middle::ty::{self, visit::TypeVisitableExt, DefIdTree, InstanceDef, TyCtxt};
 use rustc_span::symbol::Symbol;
 
 use super::PartitioningCx;
diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs
index 207ad332c22..b7c3dbcc091 100644
--- a/compiler/rustc_monomorphize/src/polymorphize.rs
+++ b/compiler/rustc_monomorphize/src/polymorphize.rs
@@ -15,7 +15,7 @@ use rustc_middle::ty::{
     self,
     query::Providers,
     subst::SubstsRef,
-    visit::{ir::TypeVisitor, TypeSuperVisitable, TypeVisitable},
+    visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor},
     Const, Ty, TyCtxt, UnusedGenericParams,
 };
 use rustc_span::symbol::sym;
diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml
index dbcfb390333..3eb158c817c 100644
--- a/compiler/rustc_parse/Cargo.toml
+++ b/compiler/rustc_parse/Cargo.toml
@@ -16,7 +16,7 @@ rustc_lexer = { path = "../rustc_lexer" }
 rustc_macros = { path = "../rustc_macros" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
-thin-vec = "0.2.8"
+thin-vec = "0.2.12"
 tracing = "0.1"
 unicode-normalization = "0.1.11"
 unicode-width = "0.1.4"
diff --git a/compiler/rustc_error_messages/locales/en-US/parse.ftl b/compiler/rustc_parse/locales/en-US.ftl
index c9cf7b62071..a31b1f6ac1a 100644
--- a/compiler/rustc_error_messages/locales/en-US/parse.ftl
+++ b/compiler/rustc_parse/locales/en-US.ftl
@@ -93,6 +93,26 @@ parse_do_catch_syntax_removed = found removed `do catch` syntax
 parse_float_literal_requires_integer_part = float literals must have an integer part
     .suggestion = must have an integer part
 
+parse_invalid_int_literal_width = invalid width `{$width}` for integer literal
+    .help = valid widths are 8, 16, 32, 64 and 128
+
+parse_invalid_num_literal_base_prefix = invalid base prefix for number literal
+    .note = base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase
+    .suggestion = try making the prefix lowercase
+
+parse_invalid_num_literal_suffix = invalid suffix `{$suffix}` for number literal
+    .label = invalid suffix `{$suffix}`
+    .help = the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+parse_invalid_float_literal_width = invalid width `{$width}` for float literal
+    .help = valid widths are 32 and 64
+
+parse_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float literal
+    .label = invalid suffix `{$suffix}`
+    .help = valid suffixes are `f32` and `f64`
+
+parse_int_literal_too_large = integer literal is too large
+
 parse_missing_semicolon_before_array = expected `;`, found `[`
     .suggestion = consider adding `;` here
 
@@ -219,6 +239,14 @@ parse_struct_literal_not_allowed_here = struct literals are not allowed here
 
 parse_invalid_interpolated_expression = invalid interpolated expression
 
+parse_hexadecimal_float_literal_not_supported = hexadecimal float literal is not supported
+parse_octal_float_literal_not_supported = octal float literal is not supported
+parse_binary_float_literal_not_supported = binary float literal is not supported
+parse_not_supported = not supported
+
+parse_invalid_literal_suffix = suffixes on {$kind} literals are invalid
+    .label = invalid suffix `{$suffix}`
+
 parse_invalid_literal_suffix_on_tuple_index = suffixes on a tuple index are invalid
     .label = invalid suffix `{$suffix}`
     .tuple_exception_line_1 = `{$suffix}` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 63bf864f2a8..c746a870964 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -2,13 +2,14 @@ use std::borrow::Cow;
 
 use rustc_ast::token::Token;
 use rustc_ast::{Path, Visibility};
-use rustc_errors::{fluent, AddToDiagnostic, Applicability, EmissionGuarantee, IntoDiagnostic};
+use rustc_errors::{AddToDiagnostic, Applicability, EmissionGuarantee, IntoDiagnostic};
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::edition::{Edition, LATEST_STABLE_EDITION};
 use rustc_span::symbol::Ident;
 use rustc_span::{Span, Symbol};
 
+use crate::fluent_generated as fluent;
 use crate::parser::TokenDescription;
 
 #[derive(Diagnostic)]
@@ -78,7 +79,7 @@ pub(crate) struct IncorrectSemicolon<'a> {
 #[diag(parse_incorrect_use_of_await)]
 pub(crate) struct IncorrectUseOfAwait {
     #[primary_span]
-    #[suggestion(parentheses_suggestion, code = "", applicability = "machine-applicable")]
+    #[suggestion(parse_parentheses_suggestion, code = "", applicability = "machine-applicable")]
     pub span: Span,
 }
 
@@ -87,7 +88,7 @@ pub(crate) struct IncorrectUseOfAwait {
 pub(crate) struct IncorrectAwait {
     #[primary_span]
     pub span: Span,
-    #[suggestion(postfix_suggestion, code = "{expr}.await{question_mark}")]
+    #[suggestion(parse_postfix_suggestion, code = "{expr}.await{question_mark}")]
     pub sugg_span: (Span, Applicability),
     pub expr: String,
     pub question_mark: &'static str,
@@ -140,7 +141,7 @@ pub(crate) struct InvalidComparisonOperator {
 #[derive(Subdiagnostic)]
 pub(crate) enum InvalidComparisonOperatorSub {
     #[suggestion(
-        use_instead,
+        parse_use_instead,
         style = "short",
         applicability = "machine-applicable",
         code = "{correct}"
@@ -151,7 +152,7 @@ pub(crate) enum InvalidComparisonOperatorSub {
         invalid: String,
         correct: String,
     },
-    #[label(spaceship_operator_invalid)]
+    #[label(parse_spaceship_operator_invalid)]
     Spaceship(#[primary_span] Span),
 }
 
@@ -169,14 +170,14 @@ pub(crate) struct InvalidLogicalOperator {
 #[derive(Subdiagnostic)]
 pub(crate) enum InvalidLogicalOperatorSub {
     #[suggestion(
-        use_amp_amp_for_conjunction,
+        parse_use_amp_amp_for_conjunction,
         style = "short",
         applicability = "machine-applicable",
         code = "&&"
     )]
     Conjunction(#[primary_span] Span),
     #[suggestion(
-        use_pipe_pipe_for_disjunction,
+        parse_use_pipe_pipe_for_disjunction,
         style = "short",
         applicability = "machine-applicable",
         code = "||"
@@ -262,14 +263,14 @@ pub(crate) struct UnexpectedTokenAfterLabel {
     #[primary_span]
     #[label(parse_unexpected_token_after_label)]
     pub span: Span,
-    #[suggestion(suggestion_remove_label, style = "verbose", code = "")]
+    #[suggestion(parse_suggestion_remove_label, style = "verbose", code = "")]
     pub remove_label: Option<Span>,
     #[subdiagnostic]
     pub enclose_in_block: Option<UnexpectedTokenAfterLabelSugg>,
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(suggestion_enclose_in_block, applicability = "machine-applicable")]
+#[multipart_suggestion(parse_suggestion_enclose_in_block, applicability = "machine-applicable")]
 pub(crate) struct UnexpectedTokenAfterLabelSugg {
     #[suggestion_part(code = "{{ ")]
     pub left: Span,
@@ -347,9 +348,9 @@ pub(crate) struct IfExpressionMissingThenBlock {
 
 #[derive(Subdiagnostic)]
 pub(crate) enum IfExpressionMissingThenBlockSub {
-    #[help(condition_possibly_unfinished)]
+    #[help(parse_condition_possibly_unfinished)]
     UnfinishedCondition(#[primary_span] Span),
-    #[help(add_then_block)]
+    #[help(parse_add_then_block)]
     AddThenBlock(#[primary_span] Span),
 }
 
@@ -364,9 +365,9 @@ pub(crate) struct IfExpressionLetSomeSub {
 #[diag(parse_if_expression_missing_condition)]
 pub(crate) struct IfExpressionMissingCondition {
     #[primary_span]
-    #[label(condition_label)]
+    #[label(parse_condition_label)]
     pub if_span: Span,
-    #[label(block_label)]
+    #[label(parse_block_label)]
     pub block_span: Span,
 }
 
@@ -404,10 +405,10 @@ pub(crate) struct OuterAttributeNotAllowedOnIfElse {
     #[primary_span]
     pub last: Span,
 
-    #[label(branch_label)]
+    #[label(parse_branch_label)]
     pub branch_span: Span,
 
-    #[label(ctx_label)]
+    #[label(parse_ctx_label)]
     pub ctx_span: Span,
     pub ctx: String,
 
@@ -427,9 +428,14 @@ pub(crate) struct MissingInInForLoop {
 #[derive(Subdiagnostic)]
 pub(crate) enum MissingInInForLoopSub {
     // Has been misleading, at least in the past (closed Issue #48492), thus maybe-incorrect
-    #[suggestion(use_in_not_of, style = "short", applicability = "maybe-incorrect", code = "in")]
+    #[suggestion(
+        parse_use_in_not_of,
+        style = "short",
+        applicability = "maybe-incorrect",
+        code = "in"
+    )]
     InNotOf(#[primary_span] Span),
-    #[suggestion(add_in, style = "short", applicability = "maybe-incorrect", code = " in ")]
+    #[suggestion(parse_add_in, style = "short", applicability = "maybe-incorrect", code = " in ")]
     AddIn(#[primary_span] Span),
 }
 
@@ -484,8 +490,8 @@ pub(crate) struct EqFieldInit {
 #[diag(parse_dotdotdot)]
 pub(crate) struct DotDotDot {
     #[primary_span]
-    #[suggestion(suggest_exclusive_range, applicability = "maybe-incorrect", code = "..")]
-    #[suggestion(suggest_inclusive_range, applicability = "maybe-incorrect", code = "..=")]
+    #[suggestion(parse_suggest_exclusive_range, applicability = "maybe-incorrect", code = "..")]
+    #[suggestion(parse_suggest_inclusive_range, applicability = "maybe-incorrect", code = "..=")]
     pub span: Span,
 }
 
@@ -525,10 +531,10 @@ pub(crate) struct UseEmptyBlockNotSemi {
 #[diag(parse_comparison_interpreted_as_generic)]
 pub(crate) struct ComparisonInterpretedAsGeneric {
     #[primary_span]
-    #[label(label_comparison)]
+    #[label(parse_label_comparison)]
     pub comparison: Span,
     pub r#type: Path,
-    #[label(label_args)]
+    #[label(parse_label_args)]
     pub args: Span,
     #[subdiagnostic]
     pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
@@ -538,17 +544,17 @@ pub(crate) struct ComparisonInterpretedAsGeneric {
 #[diag(parse_shift_interpreted_as_generic)]
 pub(crate) struct ShiftInterpretedAsGeneric {
     #[primary_span]
-    #[label(label_comparison)]
+    #[label(parse_label_comparison)]
     pub shift: Span,
     pub r#type: Path,
-    #[label(label_args)]
+    #[label(parse_label_args)]
     pub args: Span,
     #[subdiagnostic]
     pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
+#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
 pub(crate) struct ComparisonOrShiftInterpretedAsGenericSugg {
     #[suggestion_part(code = "(")]
     pub left: Span,
@@ -574,7 +580,7 @@ pub(crate) struct LeadingPlusNotSupported {
     #[label]
     pub span: Span,
     #[suggestion(
-        suggestion_remove_plus,
+        parse_suggestion_remove_plus,
         style = "verbose",
         code = "",
         applicability = "machine-applicable"
@@ -597,7 +603,7 @@ pub(crate) struct ParenthesesWithStructFields {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(suggestion_braces_for_struct, applicability = "maybe-incorrect")]
+#[multipart_suggestion(parse_suggestion_braces_for_struct, applicability = "maybe-incorrect")]
 pub(crate) struct BracesForStructLiteral {
     #[suggestion_part(code = " {{ ")]
     pub first: Span,
@@ -606,7 +612,7 @@ pub(crate) struct BracesForStructLiteral {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(suggestion_no_fields_for_fn, applicability = "maybe-incorrect")]
+#[multipart_suggestion(parse_suggestion_no_fields_for_fn, applicability = "maybe-incorrect")]
 pub(crate) struct NoFieldsForFnCall {
     #[suggestion_part(code = "")]
     pub fields: Vec<Span>,
@@ -643,7 +649,7 @@ pub(crate) struct ArrayBracketsInsteadOfSpaces {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(suggestion, applicability = "maybe-incorrect")]
+#[multipart_suggestion(parse_suggestion, applicability = "maybe-incorrect")]
 pub(crate) struct ArrayBracketsInsteadOfSpacesSugg {
     #[suggestion_part(code = "[")]
     pub left: Span,
@@ -655,9 +661,9 @@ pub(crate) struct ArrayBracketsInsteadOfSpacesSugg {
 #[diag(parse_match_arm_body_without_braces)]
 pub(crate) struct MatchArmBodyWithoutBraces {
     #[primary_span]
-    #[label(label_statements)]
+    #[label(parse_label_statements)]
     pub statements: Span,
-    #[label(label_arrow)]
+    #[label(parse_label_arrow)]
     pub arrow: Span,
     pub num_statements: usize,
     #[subdiagnostic]
@@ -670,7 +676,7 @@ pub(crate) struct MatchArmBodyWithoutBraces {
 pub(crate) struct InclusiveRangeExtraEquals {
     #[primary_span]
     #[suggestion(
-        suggestion_remove_eq,
+        parse_suggestion_remove_eq,
         style = "short",
         code = "..=",
         applicability = "maybe-incorrect"
@@ -695,7 +701,7 @@ pub(crate) struct InclusiveRangeMatchArrow {
 pub(crate) struct InclusiveRangeNoEnd {
     #[primary_span]
     #[suggestion(
-        suggestion_open_range,
+        parse_suggestion_open_range,
         code = "..",
         applicability = "machine-applicable",
         style = "short"
@@ -705,7 +711,7 @@ pub(crate) struct InclusiveRangeNoEnd {
 
 #[derive(Subdiagnostic)]
 pub(crate) enum MatchArmBodyWithoutBracesSugg {
-    #[multipart_suggestion(suggestion_add_braces, applicability = "machine-applicable")]
+    #[multipart_suggestion(parse_suggestion_add_braces, applicability = "machine-applicable")]
     AddBraces {
         #[suggestion_part(code = "{{ ")]
         left: Span,
@@ -713,7 +719,7 @@ pub(crate) enum MatchArmBodyWithoutBracesSugg {
         right: Span,
     },
     #[suggestion(
-        suggestion_use_comma_not_semicolon,
+        parse_suggestion_use_comma_not_semicolon,
         code = ",",
         applicability = "machine-applicable"
     )]
@@ -733,7 +739,7 @@ pub(crate) struct StructLiteralNotAllowedHere {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
+#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
 pub(crate) struct StructLiteralNotAllowedHereSugg {
     #[suggestion_part(code = "(")]
     pub left: Span,
@@ -755,9 +761,9 @@ pub(crate) struct InvalidLiteralSuffixOnTupleIndex {
     #[label]
     pub span: Span,
     pub suffix: Symbol,
-    #[help(tuple_exception_line_1)]
-    #[help(tuple_exception_line_2)]
-    #[help(tuple_exception_line_3)]
+    #[help(parse_tuple_exception_line_1)]
+    #[help(parse_tuple_exception_line_2)]
+    #[help(parse_tuple_exception_line_3)]
     pub exception: Option<()>,
 }
 
@@ -775,11 +781,11 @@ pub(crate) struct MismatchedClosingDelimiter {
     #[primary_span]
     pub spans: Vec<Span>,
     pub delimiter: String,
-    #[label(label_unmatched)]
+    #[label(parse_label_unmatched)]
     pub unmatched: Span,
-    #[label(label_opening_candidate)]
+    #[label(parse_label_opening_candidate)]
     pub opening_candidate: Option<Span>,
-    #[label(label_unclosed)]
+    #[label(parse_label_unclosed)]
     pub unclosed: Option<Span>,
 }
 
@@ -930,7 +936,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier {
         self,
         handler: &'a rustc_errors::Handler,
     ) -> rustc_errors::DiagnosticBuilder<'a, G> {
-        let token_descr = super::parser::TokenDescription::from_token(&self.token);
+        let token_descr = TokenDescription::from_token(&self.token);
 
         let mut diag = handler.struct_diagnostic(match token_descr {
             Some(TokenDescription::ReservedIdentifier) => {
@@ -976,7 +982,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedSemi {
         self,
         handler: &'a rustc_errors::Handler,
     ) -> rustc_errors::DiagnosticBuilder<'a, G> {
-        let token_descr = super::parser::TokenDescription::from_token(&self.token);
+        let token_descr = TokenDescription::from_token(&self.token);
 
         let mut diag = handler.struct_diagnostic(match token_descr {
             Some(TokenDescription::ReservedIdentifier) => {
@@ -1025,7 +1031,7 @@ pub(crate) struct StructLiteralBodyWithoutPath {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(suggestion, applicability = "has-placeholders")]
+#[multipart_suggestion(parse_suggestion, applicability = "has-placeholders")]
 pub(crate) struct StructLiteralBodyWithoutPathSugg {
     #[suggestion_part(code = "{{ SomeStruct ")]
     pub before: Span,
@@ -1043,7 +1049,7 @@ pub(crate) struct StructLiteralNeedingParens {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
+#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
 pub(crate) struct StructLiteralNeedingParensSugg {
     #[suggestion_part(code = "(")]
     pub before: Span,
@@ -1070,7 +1076,7 @@ pub(crate) struct GenericParamsWithoutAngleBrackets {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
+#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
 pub(crate) struct GenericParamsWithoutAngleBracketsSugg {
     #[suggestion_part(code = "<")]
     pub left: Span,
@@ -1091,7 +1097,7 @@ pub(crate) struct ComparisonOperatorsCannotBeChained {
     )]
     pub suggest_turbofish: Option<Span>,
     #[help(parse_sugg_turbofish_syntax)]
-    #[help(sugg_parentheses_for_function_args)]
+    #[help(parse_sugg_parentheses_for_function_args)]
     pub help_turbofish: Option<()>,
     #[subdiagnostic]
     pub chaining_sugg: Option<ComparisonOperatorsCannotBeChainedSugg>,
@@ -1100,7 +1106,7 @@ pub(crate) struct ComparisonOperatorsCannotBeChained {
 #[derive(Subdiagnostic)]
 pub(crate) enum ComparisonOperatorsCannotBeChainedSugg {
     #[suggestion(
-        sugg_split_comparison,
+        parse_sugg_split_comparison,
         style = "verbose",
         code = " && {middle_term}",
         applicability = "maybe-incorrect"
@@ -1110,7 +1116,7 @@ pub(crate) enum ComparisonOperatorsCannotBeChainedSugg {
         span: Span,
         middle_term: String,
     },
-    #[multipart_suggestion(sugg_parenthesize, applicability = "maybe-incorrect")]
+    #[multipart_suggestion(parse_sugg_parenthesize, applicability = "maybe-incorrect")]
     Parenthesize {
         #[suggestion_part(code = "(")]
         left: Span,
@@ -1130,7 +1136,7 @@ pub(crate) struct QuestionMarkInType {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
+#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
 pub(crate) struct QuestionMarkInTypeSugg {
     #[suggestion_part(code = "Option<")]
     pub left: Span,
@@ -1148,7 +1154,7 @@ pub(crate) struct ParenthesesInForHead {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
+#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
 pub(crate) struct ParenthesesInForHeadSugg {
     #[suggestion_part(code = "{left_snippet}")]
     pub left: Span,
@@ -1208,7 +1214,7 @@ pub(crate) struct ConstGenericWithoutBraces {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
+#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
 pub(crate) struct ConstGenericWithoutBracesSugg {
     #[suggestion_part(code = "{{ ")]
     pub left: Span,
@@ -1228,7 +1234,7 @@ pub(crate) struct UnexpectedConstParamDeclaration {
 
 #[derive(Subdiagnostic)]
 pub(crate) enum UnexpectedConstParamDeclarationSugg {
-    #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
+    #[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
     AddParam {
         #[suggestion_part(code = "<{snippet}>")]
         impl_generics: Span,
@@ -1237,7 +1243,7 @@ pub(crate) enum UnexpectedConstParamDeclarationSugg {
         snippet: String,
         ident: String,
     },
-    #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
+    #[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
     AppendParam {
         #[suggestion_part(code = ", {snippet}")]
         impl_generics_end: Span,
@@ -1284,7 +1290,7 @@ pub(crate) struct FnPtrWithGenerics {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(suggestion, applicability = "maybe-incorrect")]
+#[multipart_suggestion(parse_suggestion, applicability = "maybe-incorrect")]
 pub(crate) struct FnPtrWithGenericsSugg {
     #[suggestion_part(code = "{snippet}")]
     pub left: Span,
@@ -1325,16 +1331,16 @@ pub(crate) struct WhereClauseBeforeTupleStructBody {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(name_label)]
+    #[label(parse_name_label)]
     pub name: Span,
-    #[label(body_label)]
+    #[label(parse_body_label)]
     pub body: Span,
     #[subdiagnostic]
     pub sugg: Option<WhereClauseBeforeTupleStructBodySugg>,
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
+#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
 pub(crate) struct WhereClauseBeforeTupleStructBodySugg {
     #[suggestion_part(code = "{snippet}")]
     pub left: Span,
@@ -1429,13 +1435,13 @@ pub(crate) enum MissingKeywordForItemDefinition {
 
 #[derive(Subdiagnostic)]
 pub(crate) enum AmbiguousMissingKwForItemSub {
-    #[suggestion(suggestion, applicability = "maybe-incorrect", code = "{snippet}!")]
+    #[suggestion(parse_suggestion, applicability = "maybe-incorrect", code = "{snippet}!")]
     SuggestMacro {
         #[primary_span]
         span: Span,
         snippet: String,
     },
-    #[help(help)]
+    #[help(parse_help)]
     HelpMacro,
 }
 
@@ -1443,9 +1449,9 @@ pub(crate) enum AmbiguousMissingKwForItemSub {
 #[diag(parse_missing_trait_in_trait_impl)]
 pub(crate) struct MissingTraitInTraitImpl {
     #[primary_span]
-    #[suggestion(suggestion_add_trait, code = " Trait ", applicability = "has-placeholders")]
+    #[suggestion(parse_suggestion_add_trait, code = " Trait ", applicability = "has-placeholders")]
     pub span: Span,
-    #[suggestion(suggestion_remove_for, code = "", applicability = "maybe-incorrect")]
+    #[suggestion(parse_suggestion_remove_for, code = "", applicability = "maybe-incorrect")]
     pub for_span: Span,
 }
 
@@ -1505,7 +1511,7 @@ pub(crate) struct ExternCrateNameWithDashes {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
+#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
 pub(crate) struct ExternCrateNameWithDashesSugg {
     #[suggestion_part(code = "_")]
     pub dashes: Vec<Span>,
@@ -1726,10 +1732,15 @@ pub struct UnknownPrefix<'a> {
 
 #[derive(Subdiagnostic)]
 pub enum UnknownPrefixSugg {
-    #[suggestion(suggestion_br, code = "br", applicability = "maybe-incorrect", style = "verbose")]
+    #[suggestion(
+        parse_suggestion_br,
+        code = "br",
+        applicability = "maybe-incorrect",
+        style = "verbose"
+    )]
     UseBr(#[primary_span] Span),
     #[suggestion(
-        suggestion_whitespace,
+        parse_suggestion_whitespace,
         code = " ",
         applicability = "maybe-incorrect",
         style = "verbose"
@@ -1761,7 +1772,7 @@ pub struct UnknownTokenStart {
 
 #[derive(Subdiagnostic)]
 pub enum TokenSubstitution {
-    #[suggestion(sugg_quotes, code = "{suggestion}", applicability = "maybe-incorrect")]
+    #[suggestion(parse_sugg_quotes, code = "{suggestion}", applicability = "maybe-incorrect")]
     DirectedQuotes {
         #[primary_span]
         span: Span,
@@ -1769,7 +1780,7 @@ pub enum TokenSubstitution {
         ascii_str: &'static str,
         ascii_name: &'static str,
     },
-    #[suggestion(sugg_other, code = "{suggestion}", applicability = "maybe-incorrect")]
+    #[suggestion(parse_sugg_other, code = "{suggestion}", applicability = "maybe-incorrect")]
     Other {
         #[primary_span]
         span: Span,
@@ -1782,13 +1793,13 @@ pub enum TokenSubstitution {
 }
 
 #[derive(Subdiagnostic)]
-#[note(note_repeats)]
+#[note(parse_note_repeats)]
 pub struct UnknownTokenRepeat {
     pub repeats: usize,
 }
 
 #[derive(Subdiagnostic)]
-#[help(help_null)]
+#[help(parse_help_null)]
 pub struct UnknownTokenNull;
 
 #[derive(Diagnostic)]
@@ -1805,7 +1816,7 @@ pub enum UnescapeError {
     EscapeOnlyChar {
         #[primary_span]
         span: Span,
-        #[suggestion(escape, applicability = "machine-applicable", code = "{escaped_sugg}")]
+        #[suggestion(parse_escape, applicability = "machine-applicable", code = "{escaped_sugg}")]
         char_span: Span,
         escaped_sugg: String,
         escaped_msg: String,
@@ -1814,7 +1825,7 @@ pub enum UnescapeError {
     #[diag(parse_bare_cr)]
     BareCr {
         #[primary_span]
-        #[suggestion(escape, applicability = "machine-applicable", code = "\\r")]
+        #[suggestion(parse_escape, applicability = "machine-applicable", code = "\\r")]
         span: Span,
         double_quotes: bool,
     },
@@ -1854,7 +1865,12 @@ pub enum UnescapeError {
         #[primary_span]
         #[label]
         Span,
-        #[suggestion(terminate, code = "}}", applicability = "maybe-incorrect", style = "verbose")]
+        #[suggestion(
+            parse_terminate,
+            code = "}}",
+            applicability = "maybe-incorrect",
+            style = "verbose"
+        )]
         Span,
     ),
     #[diag(parse_no_brace_unicode_escape)]
@@ -1918,20 +1934,24 @@ pub enum UnescapeError {
 
 #[derive(Subdiagnostic)]
 pub enum MoreThanOneCharSugg {
-    #[suggestion(consider_normalized, code = "{normalized}", applicability = "machine-applicable")]
+    #[suggestion(
+        parse_consider_normalized,
+        code = "{normalized}",
+        applicability = "machine-applicable"
+    )]
     NormalizedForm {
         #[primary_span]
         span: Span,
         ch: String,
         normalized: String,
     },
-    #[suggestion(remove_non, code = "{ch}", applicability = "maybe-incorrect")]
+    #[suggestion(parse_remove_non, code = "{ch}", applicability = "maybe-incorrect")]
     RemoveNonPrinting {
         #[primary_span]
         span: Span,
         ch: String,
     },
-    #[suggestion(use_double_quotes, code = "{sugg}", applicability = "machine-applicable")]
+    #[suggestion(parse_use_double_quotes, code = "{sugg}", applicability = "machine-applicable")]
     Quotes {
         #[primary_span]
         span: Span,
@@ -1942,7 +1962,7 @@ pub enum MoreThanOneCharSugg {
 
 #[derive(Subdiagnostic)]
 pub enum MoreThanOneCharNote {
-    #[note(followed_by)]
+    #[note(parse_followed_by)]
     AllCombining {
         #[primary_span]
         span: Span,
@@ -1950,7 +1970,7 @@ pub enum MoreThanOneCharNote {
         len: usize,
         escaped_marks: String,
     },
-    #[note(non_printing)]
+    #[note(parse_non_printing)]
     NonPrinting {
         #[primary_span]
         span: Span,
@@ -1960,13 +1980,13 @@ pub enum MoreThanOneCharNote {
 
 #[derive(Subdiagnostic)]
 pub enum NoBraceUnicodeSub {
-    #[suggestion(use_braces, code = "{suggestion}", applicability = "maybe-incorrect")]
+    #[suggestion(parse_use_braces, code = "{suggestion}", applicability = "maybe-incorrect")]
     Suggestion {
         #[primary_span]
         span: Span,
         suggestion: String,
     },
-    #[help(format_of_unicode)]
+    #[help(parse_format_of_unicode)]
     Help,
 }
 
@@ -2042,9 +2062,9 @@ pub(crate) struct PatternOnWrongSideOfAt {
     #[suggestion(code = "{whole_pat}", applicability = "machine-applicable")]
     pub whole_span: Span,
     pub whole_pat: String,
-    #[label(label_pattern)]
+    #[label(parse_label_pattern)]
     pub pattern: Span,
-    #[label(label_binding)]
+    #[label(parse_label_binding)]
     pub binding: Span,
 }
 
@@ -2054,9 +2074,9 @@ pub(crate) struct PatternOnWrongSideOfAt {
 pub(crate) struct ExpectedBindingLeftOfAt {
     #[primary_span]
     pub whole_span: Span,
-    #[label(label_lhs)]
+    #[label(parse_label_lhs)]
     pub lhs: Span,
-    #[label(label_rhs)]
+    #[label(parse_label_rhs)]
     pub rhs: Span,
 }
 
@@ -2236,7 +2256,7 @@ pub(crate) struct NegativeBoundsNotSupported {
 
 #[derive(Subdiagnostic)]
 #[suggestion(
-    suggestion,
+    parse_suggestion,
     style = "tool-only",
     code = "{fixed}",
     applicability = "machine-applicable"
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index b49a01d75ed..6f37e9758fc 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -19,6 +19,8 @@ use rustc_ast::{AttrItem, Attribute, MetaItem};
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Applicability, Diagnostic, FatalError, Level, PResult};
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_macros::fluent_messages;
 use rustc_session::parse::ParseSess;
 use rustc_span::{FileName, SourceFile, Span};
 
@@ -34,6 +36,8 @@ pub mod validate_attr;
 
 mod errors;
 
+fluent_messages! { "../locales/en-US.ftl" }
+
 // A bunch of utility functions of the form `parse_<thing>_from_<source>`
 // where <thing> includes crate, expr, item, stmt, tts, and one that
 // uses a HOF to parse anything, and <source> includes file and
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index 686454a8f18..e3e7c63e344 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -1,11 +1,15 @@
 use crate::errors::{InvalidMetaItem, SuffixedLiteralInAttribute};
+use crate::fluent_generated as fluent;
 
 use super::{AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, PathStyle};
 use rustc_ast as ast;
 use rustc_ast::attr;
 use rustc_ast::token::{self, Delimiter, Nonterminal};
-use rustc_errors::{error_code, fluent, Diagnostic, IntoDiagnostic, PResult};
+use rustc_errors::{error_code, Diagnostic, IntoDiagnostic, PResult};
 use rustc_span::{sym, BytePos, Span};
+use std::convert::TryInto;
+use thin_vec::ThinVec;
+use tracing::debug;
 
 // Public for rustfmt usage
 #[derive(Debug)]
@@ -65,10 +69,10 @@ impl<'a> Parser<'a> {
                             token::CommentKind::Block => OuterAttributeType::DocBlockComment,
                         },
                     ) {
-                        err.note(fluent::note);
+                        err.note(fluent::parse_note);
                         err.span_suggestion_verbose(
                             replacement_span,
-                            fluent::suggestion,
+                            fluent::parse_suggestion,
                             "",
                             rustc_errors::Applicability::MachineApplicable,
                         );
@@ -172,10 +176,10 @@ impl<'a> Parser<'a> {
             Ok(Some(item)) => {
                 // FIXME(#100717)
                 err.set_arg("item", item.kind.descr());
-                err.span_label(item.span, fluent::label_does_not_annotate_this);
+                err.span_label(item.span, fluent::parse_label_does_not_annotate_this);
                 err.span_suggestion_verbose(
                     replacement_span,
-                    fluent::sugg_change_inner_to_outer,
+                    fluent::parse_sugg_change_inner_to_outer,
                     match attr_type {
                         OuterAttributeType::Attribute => "",
                         OuterAttributeType::DocBlockComment => "*",
@@ -201,8 +205,8 @@ impl<'a> Parser<'a> {
                         attr_sp,
                         fluent::parse_inner_attr_not_permitted_after_outer_doc_comment,
                     );
-                    diag.span_label(attr_sp, fluent::label_attr)
-                        .span_label(prev_doc_comment_span, fluent::label_prev_doc_comment);
+                    diag.span_label(attr_sp, fluent::parse_label_attr)
+                        .span_label(prev_doc_comment_span, fluent::parse_label_prev_doc_comment);
                     diag
                 }
                 Some(InnerAttrForbiddenReason::AfterOuterAttribute { prev_outer_attr_sp }) => {
@@ -210,8 +214,8 @@ impl<'a> Parser<'a> {
                         attr_sp,
                         fluent::parse_inner_attr_not_permitted_after_outer_attr,
                     );
-                    diag.span_label(attr_sp, fluent::label_attr)
-                        .span_label(prev_outer_attr_sp, fluent::label_prev_attr);
+                    diag.span_label(attr_sp, fluent::parse_label_attr)
+                        .span_label(prev_outer_attr_sp, fluent::parse_label_prev_attr);
                     diag
                 }
                 Some(InnerAttrForbiddenReason::InCodeBlock) | None => {
@@ -346,9 +350,9 @@ impl<'a> Parser<'a> {
     }
 
     /// Matches `COMMASEP(meta_item_inner)`.
-    pub(crate) fn parse_meta_seq_top(&mut self) -> PResult<'a, Vec<ast::NestedMetaItem>> {
+    pub(crate) fn parse_meta_seq_top(&mut self) -> PResult<'a, ThinVec<ast::NestedMetaItem>> {
         // Presumably, the majority of the time there will only be one attr.
-        let mut nmis = Vec::with_capacity(1);
+        let mut nmis = ThinVec::with_capacity(1);
         while self.token.kind != token::Eof {
             nmis.push(self.parse_meta_item_inner()?);
             if !self.eat(&token::Comma) {
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 49eff41329c..b4948dddcc9 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -18,6 +18,7 @@ use crate::errors::{
     UseEqInstead,
 };
 
+use crate::fluent_generated as fluent;
 use crate::lexer::UnmatchedBrace;
 use crate::parser;
 use rustc_ast as ast;
@@ -32,10 +33,9 @@ use rustc_ast::{
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{
-    fluent, Applicability, DiagnosticBuilder, DiagnosticMessage, FatalError, Handler, MultiSpan,
-    PResult,
+    pluralize, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed,
+    FatalError, Handler, IntoDiagnostic, MultiSpan, PResult,
 };
-use rustc_errors::{pluralize, Diagnostic, ErrorGuaranteed, IntoDiagnostic};
 use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym, Ident};
@@ -693,7 +693,7 @@ impl<'a> Parser<'a> {
                 span: self.prev_token.span.shrink_to_lo(),
                 tokens: None,
             };
-            let struct_expr = snapshot.parse_struct_expr(None, path, false);
+            let struct_expr = snapshot.parse_expr_struct(None, path, false);
             let block_tail = self.parse_block_tail(lo, s, AttemptLocalParseRecovery::No);
             return Some(match (struct_expr, block_tail) {
                 (Ok(expr), Err(mut err)) => {
@@ -708,7 +708,7 @@ impl<'a> Parser<'a> {
                     err.delay_as_bug();
                     self.restore_snapshot(snapshot);
                     let mut tail = self.mk_block(
-                        vec![self.mk_stmt_err(expr.span)],
+                        thin_vec![self.mk_stmt_err(expr.span)],
                         s,
                         lo.to(self.prev_token.span),
                     );
@@ -1624,7 +1624,7 @@ impl<'a> Parser<'a> {
             // Handle `await { <expr> }`.
             // This needs to be handled separately from the next arm to avoid
             // interpreting `await { <expr> }?` as `<expr>?.await`.
-            self.parse_block_expr(None, self.token.span, BlockCheckMode::Default)
+            self.parse_expr_block(None, self.token.span, BlockCheckMode::Default)
         } else {
             self.parse_expr()
         }
@@ -2175,7 +2175,7 @@ impl<'a> Parser<'a> {
     /// the parameters are *names* (so we don't emit errors about not being able to find `b` in
     /// the local scope), but if we find the same name multiple times, like in `fn foo(i8, i8)`,
     /// we deduplicate them to not complain about duplicated parameter names.
-    pub(super) fn deduplicate_recovered_params_names(&self, fn_inputs: &mut Vec<Param>) {
+    pub(super) fn deduplicate_recovered_params_names(&self, fn_inputs: &mut ThinVec<Param>) {
         let mut seen_inputs = FxHashSet::default();
         for input in fn_inputs.iter_mut() {
             let opt_ident = if let (PatKind::Ident(_, ident, _), TyKind::Err) =
@@ -2199,7 +2199,7 @@ impl<'a> Parser<'a> {
     /// like the user has forgotten them.
     pub fn handle_ambiguous_unbraced_const_arg(
         &mut self,
-        args: &mut Vec<AngleBracketedArg>,
+        args: &mut ThinVec<AngleBracketedArg>,
     ) -> PResult<'a, bool> {
         // If we haven't encountered a closing `>`, then the argument is malformed.
         // It's likely that the user has written a const expression without enclosing it
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 2fc8ce98af0..33254d034c9 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -31,6 +31,7 @@ use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc_span::source_map::{self, Span, Spanned};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{BytePos, Pos};
+use thin_vec::{thin_vec, ThinVec};
 
 /// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression
 /// dropped into the token stream, which happens while parsing the result of
@@ -102,7 +103,7 @@ impl<'a> Parser<'a> {
         self.collect_tokens_no_attrs(|this| this.parse_expr())
     }
 
-    pub fn parse_anon_const_expr(&mut self) -> PResult<'a, AnonConst> {
+    pub fn parse_expr_anon_const(&mut self) -> PResult<'a, AnonConst> {
         self.parse_expr().map(|value| AnonConst { id: DUMMY_NODE_ID, value })
     }
 
@@ -124,7 +125,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a sequence of expressions delimited by parentheses.
-    fn parse_paren_expr_seq(&mut self) -> PResult<'a, Vec<P<Expr>>> {
+    fn parse_expr_paren_seq(&mut self) -> PResult<'a, ThinVec<P<Expr>>> {
         self.parse_paren_comma_seq(|p| p.parse_expr_catch_underscore()).map(|(r, _)| r)
     }
 
@@ -135,7 +136,7 @@ impl<'a> Parser<'a> {
         r: Restrictions,
         already_parsed_attrs: Option<AttrWrapper>,
     ) -> PResult<'a, P<Expr>> {
-        self.with_res(r, |this| this.parse_assoc_expr(already_parsed_attrs))
+        self.with_res(r, |this| this.parse_expr_assoc(already_parsed_attrs))
     }
 
     /// Parses an associative expression.
@@ -143,15 +144,15 @@ impl<'a> Parser<'a> {
     /// This parses an expression accounting for associativity and precedence of the operators in
     /// the expression.
     #[inline]
-    fn parse_assoc_expr(
+    fn parse_expr_assoc(
         &mut self,
         already_parsed_attrs: Option<AttrWrapper>,
     ) -> PResult<'a, P<Expr>> {
-        self.parse_assoc_expr_with(0, already_parsed_attrs.into())
+        self.parse_expr_assoc_with(0, already_parsed_attrs.into())
     }
 
     /// Parses an associative expression with operators of at least `min_prec` precedence.
-    pub(super) fn parse_assoc_expr_with(
+    pub(super) fn parse_expr_assoc_with(
         &mut self,
         min_prec: usize,
         lhs: LhsExpr,
@@ -166,9 +167,9 @@ impl<'a> Parser<'a> {
                 _ => None,
             };
             if self.token.is_range_separator() {
-                return self.parse_prefix_range_expr(attrs);
+                return self.parse_expr_prefix_range(attrs);
             } else {
-                self.parse_prefix_expr(attrs)?
+                self.parse_expr_prefix(attrs)?
             }
         };
         let last_type_ascription_set = self.last_type_ascription.is_some();
@@ -292,7 +293,7 @@ impl<'a> Parser<'a> {
             } else if op == AssocOp::DotDot || op == AssocOp::DotDotEq {
                 // If we didn't have to handle `x..`/`x..=`, it would be pretty easy to
                 // generalise it to the Fixity::None code.
-                lhs = self.parse_range_expr(prec, lhs, op, cur_op_span)?;
+                lhs = self.parse_expr_range(prec, lhs, op, cur_op_span)?;
                 break;
             }
 
@@ -305,7 +306,7 @@ impl<'a> Parser<'a> {
                 Fixity::None => 1,
             };
             let rhs = self.with_res(restrictions - Restrictions::STMT_EXPR, |this| {
-                this.parse_assoc_expr_with(prec + prec_adjustment, LhsExpr::NotYetParsed)
+                this.parse_expr_assoc_with(prec + prec_adjustment, LhsExpr::NotYetParsed)
             })?;
 
             let span = self.mk_expr_sp(&lhs, lhs_span, rhs.span);
@@ -457,7 +458,7 @@ impl<'a> Parser<'a> {
 
     /// Parses `x..y`, `x..=y`, and `x..`/`x..=`.
     /// The other two variants are handled in `parse_prefix_range_expr` below.
-    fn parse_range_expr(
+    fn parse_expr_range(
         &mut self,
         prec: usize,
         lhs: P<Expr>,
@@ -465,7 +466,7 @@ impl<'a> Parser<'a> {
         cur_op_span: Span,
     ) -> PResult<'a, P<Expr>> {
         let rhs = if self.is_at_start_of_range_notation_rhs() {
-            Some(self.parse_assoc_expr_with(prec + 1, LhsExpr::NotYetParsed)?)
+            Some(self.parse_expr_assoc_with(prec + 1, LhsExpr::NotYetParsed)?)
         } else {
             None
         };
@@ -490,7 +491,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses prefix-forms of range notation: `..expr`, `..`, `..=expr`.
-    fn parse_prefix_range_expr(&mut self, attrs: Option<AttrWrapper>) -> PResult<'a, P<Expr>> {
+    fn parse_expr_prefix_range(&mut self, attrs: Option<AttrWrapper>) -> PResult<'a, P<Expr>> {
         // Check for deprecated `...` syntax.
         if self.token == token::DotDotDot {
             self.err_dotdotdot_syntax(self.token.span);
@@ -517,7 +518,7 @@ impl<'a> Parser<'a> {
             this.bump();
             let (span, opt_end) = if this.is_at_start_of_range_notation_rhs() {
                 // RHS must be parsed with more associativity than the dots.
-                this.parse_assoc_expr_with(op.unwrap().precedence() + 1, LhsExpr::NotYetParsed)
+                this.parse_expr_assoc_with(op.unwrap().precedence() + 1, LhsExpr::NotYetParsed)
                     .map(|x| (lo.to(x.span), Some(x)))?
             } else {
                 (lo, None)
@@ -528,7 +529,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a prefix-unary-operator expr.
-    fn parse_prefix_expr(&mut self, attrs: Option<AttrWrapper>) -> PResult<'a, P<Expr>> {
+    fn parse_expr_prefix(&mut self, attrs: Option<AttrWrapper>) -> PResult<'a, P<Expr>> {
         let attrs = self.parse_or_use_outer_attributes(attrs)?;
         let lo = self.token.span;
 
@@ -546,20 +547,20 @@ impl<'a> Parser<'a> {
         // Note: when adding new unary operators, don't forget to adjust TokenKind::can_begin_expr()
         match this.token.uninterpolate().kind {
             // `!expr`
-            token::Not => make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Not)),
+            token::Not => make_it!(this, attrs, |this, _| this.parse_expr_unary(lo, UnOp::Not)),
             // `~expr`
             token::Tilde => make_it!(this, attrs, |this, _| this.recover_tilde_expr(lo)),
             // `-expr`
             token::BinOp(token::Minus) => {
-                make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Neg))
+                make_it!(this, attrs, |this, _| this.parse_expr_unary(lo, UnOp::Neg))
             }
             // `*expr`
             token::BinOp(token::Star) => {
-                make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Deref))
+                make_it!(this, attrs, |this, _| this.parse_expr_unary(lo, UnOp::Deref))
             }
             // `&expr` and `&&expr`
             token::BinOp(token::And) | token::AndAnd => {
-                make_it!(this, attrs, |this, _| this.parse_borrow_expr(lo))
+                make_it!(this, attrs, |this, _| this.parse_expr_borrow(lo))
             }
             // `+lit`
             token::BinOp(token::Plus) if this.look_ahead(1, |tok| tok.is_numeric_lit()) => {
@@ -578,7 +579,7 @@ impl<'a> Parser<'a> {
                 this.sess.emit_err(err);
 
                 this.bump();
-                this.parse_prefix_expr(None)
+                this.parse_expr_prefix(None)
             }
             // Recover from `++x`:
             token::BinOp(token::Plus)
@@ -591,28 +592,28 @@ impl<'a> Parser<'a> {
                 this.bump();
                 this.bump();
 
-                let operand_expr = this.parse_dot_or_call_expr(Default::default())?;
+                let operand_expr = this.parse_expr_dot_or_call(Default::default())?;
                 this.recover_from_prefix_increment(operand_expr, pre_span, starts_stmt)
             }
             token::Ident(..) if this.token.is_keyword(kw::Box) => {
-                make_it!(this, attrs, |this, _| this.parse_box_expr(lo))
+                make_it!(this, attrs, |this, _| this.parse_expr_box(lo))
             }
             token::Ident(..) if this.may_recover() && this.is_mistaken_not_ident_negation() => {
                 make_it!(this, attrs, |this, _| this.recover_not_expr(lo))
             }
-            _ => return this.parse_dot_or_call_expr(Some(attrs)),
+            _ => return this.parse_expr_dot_or_call(Some(attrs)),
         }
     }
 
-    fn parse_prefix_expr_common(&mut self, lo: Span) -> PResult<'a, (Span, P<Expr>)> {
+    fn parse_expr_prefix_common(&mut self, lo: Span) -> PResult<'a, (Span, P<Expr>)> {
         self.bump();
-        let expr = self.parse_prefix_expr(None);
+        let expr = self.parse_expr_prefix(None);
         let (span, expr) = self.interpolated_or_expr_span(expr)?;
         Ok((lo.to(span), expr))
     }
 
-    fn parse_unary_expr(&mut self, lo: Span, op: UnOp) -> PResult<'a, (Span, ExprKind)> {
-        let (span, expr) = self.parse_prefix_expr_common(lo)?;
+    fn parse_expr_unary(&mut self, lo: Span, op: UnOp) -> PResult<'a, (Span, ExprKind)> {
+        let (span, expr) = self.parse_expr_prefix_common(lo)?;
         Ok((span, self.mk_unary(op, expr)))
     }
 
@@ -620,12 +621,12 @@ impl<'a> Parser<'a> {
     fn recover_tilde_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
         self.sess.emit_err(errors::TildeAsUnaryOperator(lo));
 
-        self.parse_unary_expr(lo, UnOp::Not)
+        self.parse_expr_unary(lo, UnOp::Not)
     }
 
     /// Parse `box expr`.
-    fn parse_box_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
-        let (span, expr) = self.parse_prefix_expr_common(lo)?;
+    fn parse_expr_box(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
+        let (span, expr) = self.parse_expr_prefix_common(lo)?;
         self.sess.gated_spans.gate(sym::box_syntax, span);
         Ok((span, ExprKind::Box(expr)))
     }
@@ -663,7 +664,7 @@ impl<'a> Parser<'a> {
             ),
         });
 
-        self.parse_unary_expr(lo, UnOp::Not)
+        self.parse_expr_unary(lo, UnOp::Not)
     }
 
     /// Returns the span of expr, if it was not interpolated or the span of the interpolated token.
@@ -721,7 +722,7 @@ impl<'a> Parser<'a> {
                                 segments[0].ident.span,
                             ),
                         };
-                        match self.parse_labeled_expr(label, false) {
+                        match self.parse_expr_labeled(label, false) {
                             Ok(expr) => {
                                 type_err.cancel();
                                 self.sess.emit_err(errors::MalformedLoopLabel {
@@ -815,7 +816,7 @@ impl<'a> Parser<'a> {
                 ("cast", None)
             };
 
-        let with_postfix = self.parse_dot_or_call_expr_with_(cast_expr, span)?;
+        let with_postfix = self.parse_expr_dot_or_call_with_(cast_expr, span)?;
 
         // Check if an illegal postfix operator has been added after the cast.
         // If the resulting expression is not a cast, it is an illegal postfix operator.
@@ -886,15 +887,15 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse `& mut? <expr>` or `& raw [ const | mut ] <expr>`.
-    fn parse_borrow_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
+    fn parse_expr_borrow(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
         self.expect_and()?;
         let has_lifetime = self.token.is_lifetime() && self.look_ahead(1, |t| t != &token::Colon);
         let lifetime = has_lifetime.then(|| self.expect_lifetime()); // For recovery, see below.
         let (borrow_kind, mutbl) = self.parse_borrow_modifiers(lo);
         let expr = if self.token.is_range_separator() {
-            self.parse_prefix_range_expr(None)
+            self.parse_expr_prefix_range(None)
         } else {
-            self.parse_prefix_expr(None)
+            self.parse_expr_prefix(None)
         };
         let (hi, expr) = self.interpolated_or_expr_span(expr)?;
         let span = lo.to(hi);
@@ -924,16 +925,16 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses `a.b` or `a(13)` or `a[4]` or just `a`.
-    fn parse_dot_or_call_expr(&mut self, attrs: Option<AttrWrapper>) -> PResult<'a, P<Expr>> {
+    fn parse_expr_dot_or_call(&mut self, attrs: Option<AttrWrapper>) -> PResult<'a, P<Expr>> {
         let attrs = self.parse_or_use_outer_attributes(attrs)?;
         self.collect_tokens_for_expr(attrs, |this, attrs| {
-            let base = this.parse_bottom_expr();
+            let base = this.parse_expr_bottom();
             let (span, base) = this.interpolated_or_expr_span(base)?;
-            this.parse_dot_or_call_expr_with(base, span, attrs)
+            this.parse_expr_dot_or_call_with(base, span, attrs)
         })
     }
 
-    pub(super) fn parse_dot_or_call_expr_with(
+    pub(super) fn parse_expr_dot_or_call_with(
         &mut self,
         e0: P<Expr>,
         lo: Span,
@@ -942,7 +943,7 @@ impl<'a> Parser<'a> {
         // Stitch the list of outer attributes onto the return value.
         // A little bit ugly, but the best way given the current code
         // structure
-        let res = self.parse_dot_or_call_expr_with_(e0, lo);
+        let res = self.parse_expr_dot_or_call_with_(e0, lo);
         if attrs.is_empty() {
             res
         } else {
@@ -956,7 +957,7 @@ impl<'a> Parser<'a> {
         }
     }
 
-    fn parse_dot_or_call_expr_with_(&mut self, mut e: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
+    fn parse_expr_dot_or_call_with_(&mut self, mut e: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
         loop {
             let has_question = if self.prev_token.kind == TokenKind::Ident(kw::Return, false) {
                 // we are using noexpect here because we don't expect a `?` directly after a `return`
@@ -979,15 +980,15 @@ impl<'a> Parser<'a> {
             };
             if has_dot {
                 // expr.f
-                e = self.parse_dot_suffix_expr(lo, e)?;
+                e = self.parse_expr_dot_suffix(lo, e)?;
                 continue;
             }
             if self.expr_is_complete(&e) {
                 return Ok(e);
             }
             e = match self.token.kind {
-                token::OpenDelim(Delimiter::Parenthesis) => self.parse_fn_call_expr(lo, e),
-                token::OpenDelim(Delimiter::Bracket) => self.parse_index_expr(lo, e)?,
+                token::OpenDelim(Delimiter::Parenthesis) => self.parse_expr_fn_call(lo, e),
+                token::OpenDelim(Delimiter::Bracket) => self.parse_expr_index(lo, e)?,
                 _ => return Ok(e),
             }
         }
@@ -999,14 +1000,14 @@ impl<'a> Parser<'a> {
             && self.look_ahead(3, |t| t.can_begin_expr())
     }
 
-    fn parse_dot_suffix_expr(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> {
+    fn parse_expr_dot_suffix(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> {
         match self.token.uninterpolate().kind {
             token::Ident(..) => self.parse_dot_suffix(base, lo),
             token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) => {
-                Ok(self.parse_tuple_field_access_expr(lo, base, symbol, suffix, None))
+                Ok(self.parse_expr_tuple_field_access(lo, base, symbol, suffix, None))
             }
             token::Literal(token::Lit { kind: token::Float, symbol, suffix }) => {
-                Ok(self.parse_tuple_field_access_expr_float(lo, base, symbol, suffix))
+                Ok(self.parse_expr_tuple_field_access_float(lo, base, symbol, suffix))
             }
             _ => {
                 self.error_unexpected_after_dot();
@@ -1028,7 +1029,7 @@ impl<'a> Parser<'a> {
     // support pushing "future tokens" (would be also helpful to `break_and_eat`), or
     // we should break everything including floats into more basic proc-macro style
     // tokens in the lexer (probably preferable).
-    fn parse_tuple_field_access_expr_float(
+    fn parse_expr_tuple_field_access_float(
         &mut self,
         lo: Span,
         base: P<Expr>,
@@ -1071,7 +1072,7 @@ impl<'a> Parser<'a> {
         match &*components {
             // 1e2
             [IdentLike(i)] => {
-                self.parse_tuple_field_access_expr(lo, base, Symbol::intern(&i), suffix, None)
+                self.parse_expr_tuple_field_access(lo, base, Symbol::intern(&i), suffix, None)
             }
             // 1.
             [IdentLike(i), Punct('.')] => {
@@ -1087,7 +1088,7 @@ impl<'a> Parser<'a> {
                 let symbol = Symbol::intern(&i);
                 self.token = Token::new(token::Ident(symbol, false), ident_span);
                 let next_token = (Token::new(token::Dot, dot_span), self.token_spacing);
-                self.parse_tuple_field_access_expr(lo, base, symbol, None, Some(next_token))
+                self.parse_expr_tuple_field_access(lo, base, symbol, None, Some(next_token))
             }
             // 1.2 | 1.2e3
             [IdentLike(i1), Punct('.'), IdentLike(i2)] => {
@@ -1108,11 +1109,11 @@ impl<'a> Parser<'a> {
                 // See issue #76399 and PR #76285 for more details
                 let next_token1 = (Token::new(token::Dot, dot_span), Spacing::Alone);
                 let base1 =
-                    self.parse_tuple_field_access_expr(lo, base, symbol1, None, Some(next_token1));
+                    self.parse_expr_tuple_field_access(lo, base, symbol1, None, Some(next_token1));
                 let symbol2 = Symbol::intern(&i2);
                 let next_token2 = Token::new(token::Ident(symbol2, false), ident2_span);
                 self.bump_with((next_token2, self.token_spacing)); // `.`
-                self.parse_tuple_field_access_expr(lo, base1, symbol2, suffix, None)
+                self.parse_expr_tuple_field_access(lo, base1, symbol2, suffix, None)
             }
             // 1e+ | 1e- (recovered)
             [IdentLike(_), Punct('+' | '-')] |
@@ -1130,7 +1131,7 @@ impl<'a> Parser<'a> {
         }
     }
 
-    fn parse_tuple_field_access_expr(
+    fn parse_expr_tuple_field_access(
         &mut self,
         lo: Span,
         base: P<Expr>,
@@ -1151,7 +1152,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse a function call expression, `expr(...)`.
-    fn parse_fn_call_expr(&mut self, lo: Span, fun: P<Expr>) -> P<Expr> {
+    fn parse_expr_fn_call(&mut self, lo: Span, fun: P<Expr>) -> P<Expr> {
         let snapshot = if self.token.kind == token::OpenDelim(Delimiter::Parenthesis)
             && self.look_ahead_type_ascription_as_field()
         {
@@ -1162,7 +1163,7 @@ impl<'a> Parser<'a> {
         let open_paren = self.token.span;
 
         let mut seq = self
-            .parse_paren_expr_seq()
+            .parse_expr_paren_seq()
             .map(|args| self.mk_expr(lo.to(self.prev_token.span), self.mk_call(fun, args)));
         if let Some(expr) =
             self.maybe_recover_struct_lit_bad_delims(lo, open_paren, &mut seq, snapshot)
@@ -1235,7 +1236,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse an indexing expression `expr[...]`.
-    fn parse_index_expr(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> {
+    fn parse_expr_index(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> {
         let prev_span = self.prev_token.span;
         let open_delim_span = self.token.span;
         self.bump(); // `[`
@@ -1258,7 +1259,7 @@ impl<'a> Parser<'a> {
 
         if self.check(&token::OpenDelim(Delimiter::Parenthesis)) {
             // Method call `expr.f()`
-            let args = self.parse_paren_expr_seq()?;
+            let args = self.parse_expr_paren_seq()?;
             let fn_span = fn_span_lo.to(self.prev_token.span);
             let span = lo.to(self.prev_token.span);
             Ok(self.mk_expr(
@@ -1286,7 +1287,7 @@ impl<'a> Parser<'a> {
     ///
     /// N.B., this does not parse outer attributes, and is private because it only works
     /// correctly if called from `parse_dot_or_call_expr()`.
-    fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_bottom(&mut self) -> PResult<'a, P<Expr>> {
         maybe_recover_from_interpolated_ty_qpath!(self, true);
         maybe_whole_expr!(self);
 
@@ -1299,13 +1300,13 @@ impl<'a> Parser<'a> {
             // This match arm is a special-case of the `_` match arm below and
             // could be removed without changing functionality, but it's faster
             // to have it here, especially for programs with large constants.
-            self.parse_lit_expr()
+            self.parse_expr_lit()
         } else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) {
-            self.parse_tuple_parens_expr()
+            self.parse_expr_tuple_parens()
         } else if self.check(&token::OpenDelim(Delimiter::Brace)) {
-            self.parse_block_expr(None, lo, BlockCheckMode::Default)
+            self.parse_expr_block(None, lo, BlockCheckMode::Default)
         } else if self.check(&token::BinOp(token::Or)) || self.check(&token::OrOr) {
-            self.parse_closure_expr().map_err(|mut err| {
+            self.parse_expr_closure().map_err(|mut err| {
                 // If the input is something like `if a { 1 } else { 2 } | if a { 3 } else { 4 }`
                 // then suggest parens around the lhs.
                 if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&lo) {
@@ -1314,42 +1315,42 @@ impl<'a> Parser<'a> {
                 err
             })
         } else if self.check(&token::OpenDelim(Delimiter::Bracket)) {
-            self.parse_array_or_repeat_expr(Delimiter::Bracket)
+            self.parse_expr_array_or_repeat(Delimiter::Bracket)
         } else if self.check_path() {
-            self.parse_path_start_expr()
+            self.parse_expr_path_start()
         } else if self.check_keyword(kw::Move)
             || self.check_keyword(kw::Static)
             || self.check_const_closure()
         {
-            self.parse_closure_expr()
+            self.parse_expr_closure()
         } else if self.eat_keyword(kw::If) {
-            self.parse_if_expr()
+            self.parse_expr_if()
         } else if self.check_keyword(kw::For) {
             if self.choose_generics_over_qpath(1) {
-                self.parse_closure_expr()
+                self.parse_expr_closure()
             } else {
                 assert!(self.eat_keyword(kw::For));
-                self.parse_for_expr(None, self.prev_token.span)
+                self.parse_expr_for(None, self.prev_token.span)
             }
         } else if self.eat_keyword(kw::While) {
-            self.parse_while_expr(None, self.prev_token.span)
+            self.parse_expr_while(None, self.prev_token.span)
         } else if let Some(label) = self.eat_label() {
-            self.parse_labeled_expr(label, true)
+            self.parse_expr_labeled(label, true)
         } else if self.eat_keyword(kw::Loop) {
             let sp = self.prev_token.span;
-            self.parse_loop_expr(None, self.prev_token.span).map_err(|mut err| {
+            self.parse_expr_loop(None, self.prev_token.span).map_err(|mut err| {
                 err.span_label(sp, "while parsing this `loop` expression");
                 err
             })
         } else if self.eat_keyword(kw::Match) {
             let match_sp = self.prev_token.span;
-            self.parse_match_expr().map_err(|mut err| {
+            self.parse_expr_match().map_err(|mut err| {
                 err.span_label(match_sp, "while parsing this `match` expression");
                 err
             })
         } else if self.eat_keyword(kw::Unsafe) {
             let sp = self.prev_token.span;
-            self.parse_block_expr(None, lo, BlockCheckMode::Unsafe(ast::UserProvided)).map_err(
+            self.parse_expr_block(None, lo, BlockCheckMode::Unsafe(ast::UserProvided)).map_err(
                 |mut err| {
                     err.span_label(sp, "while parsing this `unsafe` expression");
                     err
@@ -1363,17 +1364,17 @@ impl<'a> Parser<'a> {
             self.expect_keyword(kw::Try)?;
             self.parse_try_block(lo)
         } else if self.eat_keyword(kw::Return) {
-            self.parse_return_expr()
+            self.parse_expr_return()
         } else if self.eat_keyword(kw::Continue) {
-            self.parse_continue_expr(lo)
+            self.parse_expr_continue(lo)
         } else if self.eat_keyword(kw::Break) {
-            self.parse_break_expr()
+            self.parse_expr_break()
         } else if self.eat_keyword(kw::Yield) {
-            self.parse_yield_expr()
+            self.parse_expr_yield()
         } else if self.is_do_yeet() {
-            self.parse_yeet_expr()
+            self.parse_expr_yeet()
         } else if self.check_keyword(kw::Let) {
-            self.parse_let_expr()
+            self.parse_expr_let()
         } else if self.eat_keyword(kw::Underscore) {
             Ok(self.mk_expr(self.prev_token.span, ExprKind::Underscore))
         } else if !self.unclosed_delims.is_empty() && self.check(&token::Semi) {
@@ -1396,19 +1397,19 @@ impl<'a> Parser<'a> {
                     // Check for `async {` and `async move {`.
                     self.parse_async_block()
                 } else {
-                    self.parse_closure_expr()
+                    self.parse_expr_closure()
                 }
             } else if self.eat_keyword(kw::Await) {
                 self.recover_incorrect_await_syntax(lo, self.prev_token.span)
             } else {
-                self.parse_lit_expr()
+                self.parse_expr_lit()
             }
         } else {
-            self.parse_lit_expr()
+            self.parse_expr_lit()
         }
     }
 
-    fn parse_lit_expr(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_lit(&mut self) -> PResult<'a, P<Expr>> {
         let lo = self.token.span;
         match self.parse_opt_token_lit() {
             Some((token_lit, _)) => {
@@ -1419,7 +1420,7 @@ impl<'a> Parser<'a> {
         }
     }
 
-    fn parse_tuple_parens_expr(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_tuple_parens(&mut self) -> PResult<'a, P<Expr>> {
         let lo = self.token.span;
         self.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
         let (es, trailing_comma) = match self.parse_seq_to_end(
@@ -1443,20 +1444,20 @@ impl<'a> Parser<'a> {
         self.maybe_recover_from_bad_qpath(expr)
     }
 
-    fn parse_array_or_repeat_expr(&mut self, close_delim: Delimiter) -> PResult<'a, P<Expr>> {
+    fn parse_expr_array_or_repeat(&mut self, close_delim: Delimiter) -> PResult<'a, P<Expr>> {
         let lo = self.token.span;
         self.bump(); // `[` or other open delim
 
         let close = &token::CloseDelim(close_delim);
         let kind = if self.eat(close) {
             // Empty vector
-            ExprKind::Array(Vec::new())
+            ExprKind::Array(ThinVec::new())
         } else {
             // Non-empty vector
             let first_expr = self.parse_expr()?;
             if self.eat(&token::Semi) {
                 // Repeating array syntax: `[ 0; 512 ]`
-                let count = self.parse_anon_const_expr()?;
+                let count = self.parse_expr_anon_const()?;
                 self.expect(close)?;
                 ExprKind::Repeat(first_expr, count)
             } else if self.eat(&token::Comma) {
@@ -1468,14 +1469,14 @@ impl<'a> Parser<'a> {
             } else {
                 // Vector with one element
                 self.expect(close)?;
-                ExprKind::Array(vec![first_expr])
+                ExprKind::Array(thin_vec![first_expr])
             }
         };
         let expr = self.mk_expr(lo.to(self.prev_token.span), kind);
         self.maybe_recover_from_bad_qpath(expr)
     }
 
-    fn parse_path_start_expr(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_path_start(&mut self) -> PResult<'a, P<Expr>> {
         let (qself, path) = if self.eat_lt() {
             let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
             (Some(qself), path)
@@ -1512,7 +1513,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse `'label: $expr`. The label is already parsed.
-    fn parse_labeled_expr(
+    fn parse_expr_labeled(
         &mut self,
         label_: Label,
         mut consume_colon: bool,
@@ -1521,15 +1522,15 @@ impl<'a> Parser<'a> {
         let label = Some(label_);
         let ate_colon = self.eat(&token::Colon);
         let expr = if self.eat_keyword(kw::While) {
-            self.parse_while_expr(label, lo)
+            self.parse_expr_while(label, lo)
         } else if self.eat_keyword(kw::For) {
-            self.parse_for_expr(label, lo)
+            self.parse_expr_for(label, lo)
         } else if self.eat_keyword(kw::Loop) {
-            self.parse_loop_expr(label, lo)
+            self.parse_expr_loop(label, lo)
         } else if self.check_noexpect(&token::OpenDelim(Delimiter::Brace))
             || self.token.is_whole_block()
         {
-            self.parse_block_expr(label, lo, BlockCheckMode::Default)
+            self.parse_expr_block(label, lo, BlockCheckMode::Default)
         } else if !ate_colon
             && self.may_recover()
             && (matches!(self.token.kind, token::CloseDelim(_) | token::Comma)
@@ -1600,7 +1601,7 @@ impl<'a> Parser<'a> {
 
                 // Replace `'label: non_block_expr` with `'label: {non_block_expr}` in order to suppress future errors about `break 'label`.
                 let stmt = self.mk_stmt(span, StmtKind::Expr(expr));
-                let blk = self.mk_block(vec![stmt], BlockCheckMode::Default, span);
+                let blk = self.mk_block(thin_vec![stmt], BlockCheckMode::Default, span);
                 self.mk_expr(span, ExprKind::Block(blk, label))
             });
 
@@ -1669,7 +1670,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse `"return" expr?`.
-    fn parse_return_expr(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_return(&mut self) -> PResult<'a, P<Expr>> {
         let lo = self.prev_token.span;
         let kind = ExprKind::Ret(self.parse_expr_opt()?);
         let expr = self.mk_expr(lo.to(self.prev_token.span), kind);
@@ -1677,7 +1678,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse `"do" "yeet" expr?`.
-    fn parse_yeet_expr(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_yeet(&mut self) -> PResult<'a, P<Expr>> {
         let lo = self.token.span;
 
         self.bump(); // `do`
@@ -1699,13 +1700,13 @@ impl<'a> Parser<'a> {
     /// `break 'lbl: loop {}`); a labeled break with an unlabeled loop as its value
     /// expression only gets a warning for compatibility reasons; and a labeled break
     /// with a labeled loop does not even get a warning because there is no ambiguity.
-    fn parse_break_expr(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_break(&mut self) -> PResult<'a, P<Expr>> {
         let lo = self.prev_token.span;
         let mut label = self.eat_label();
         let kind = if self.token == token::Colon && let Some(label) = label.take() {
             // The value expression can be a labeled loop, see issue #86948, e.g.:
             // `loop { break 'label: loop { break 'label 42; }; }`
-            let lexpr = self.parse_labeled_expr(label, true)?;
+            let lexpr = self.parse_expr_labeled(label, true)?;
             self.sess.emit_err(errors::LabeledLoopInBreak {
                 span: lexpr.span,
                 sub: errors::WrapExpressionInParentheses {
@@ -1758,7 +1759,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse `"continue" label?`.
-    fn parse_continue_expr(&mut self, lo: Span) -> PResult<'a, P<Expr>> {
+    fn parse_expr_continue(&mut self, lo: Span) -> PResult<'a, P<Expr>> {
         let mut label = self.eat_label();
 
         // Recover `continue label` -> `continue 'label`
@@ -1775,7 +1776,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse `"yield" expr?`.
-    fn parse_yield_expr(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_yield(&mut self) -> PResult<'a, P<Expr>> {
         let lo = self.prev_token.span;
         let kind = ExprKind::Yield(self.parse_expr_opt()?);
         let span = lo.to(self.prev_token.span);
@@ -1992,7 +1993,7 @@ impl<'a> Parser<'a> {
     /// expression.
     fn maybe_suggest_brackets_instead_of_braces(&mut self, lo: Span) -> Option<P<Expr>> {
         let mut snapshot = self.create_snapshot_for_diagnostic();
-        match snapshot.parse_array_or_repeat_expr(Delimiter::Brace) {
+        match snapshot.parse_expr_array_or_repeat(Delimiter::Brace) {
             Ok(arr) => {
                 self.sess.emit_err(errors::ArrayBracketsInsteadOfSpaces {
                     span: arr.span,
@@ -2055,7 +2056,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a block or unsafe block.
-    pub(super) fn parse_block_expr(
+    pub(super) fn parse_expr_block(
         &mut self,
         opt_label: Option<Label>,
         lo: Span,
@@ -2085,7 +2086,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a closure expression (e.g., `move |args| expr`).
-    fn parse_closure_expr(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_closure(&mut self) -> PResult<'a, P<Expr>> {
         let lo = self.token.span;
 
         let binder = if self.check_keyword(kw::For) {
@@ -2095,7 +2096,7 @@ impl<'a> Parser<'a> {
 
             self.sess.gated_spans.gate(sym::closure_lifetime_binder, span);
 
-            ClosureBinder::For { span, generic_params: P::from_vec(lifetime_defs) }
+            ClosureBinder::For { span, generic_params: lifetime_defs }
         } else {
             ClosureBinder::NotPresent
         };
@@ -2122,7 +2123,7 @@ impl<'a> Parser<'a> {
             _ => {
                 // If an explicit return type is given, require a block to appear (RFC 968).
                 let body_lo = self.token.span;
-                self.parse_block_expr(None, body_lo, BlockCheckMode::Default)?
+                self.parse_expr_block(None, body_lo, BlockCheckMode::Default)?
             }
         };
 
@@ -2187,7 +2188,7 @@ impl<'a> Parser<'a> {
         let arg_start = self.token.span.lo();
 
         let inputs = if self.eat(&token::OrOr) {
-            Vec::new()
+            ThinVec::new()
         } else {
             self.expect(&token::BinOp(token::Or))?;
             let args = self
@@ -2235,9 +2236,9 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses an `if` expression (`if` token already eaten).
-    fn parse_if_expr(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_if(&mut self) -> PResult<'a, P<Expr>> {
         let lo = self.prev_token.span;
-        let cond = self.parse_cond_expr()?;
+        let cond = self.parse_expr_cond()?;
         self.parse_if_after_cond(lo, cond)
     }
 
@@ -2315,12 +2316,12 @@ impl<'a> Parser<'a> {
             self.error_on_if_block_attrs(lo, false, block.span, attrs);
             block
         };
-        let els = if self.eat_keyword(kw::Else) { Some(self.parse_else_expr()?) } else { None };
+        let els = if self.eat_keyword(kw::Else) { Some(self.parse_expr_else()?) } else { None };
         Ok(self.mk_expr(lo.to(self.prev_token.span), ExprKind::If(cond, thn, els)))
     }
 
     /// Parses the condition of a `if` or `while` expression.
-    fn parse_cond_expr(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_cond(&mut self) -> PResult<'a, P<Expr>> {
         let cond =
             self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL | Restrictions::ALLOW_LET, None)?;
 
@@ -2333,7 +2334,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a `let $pat = $expr` pseudo-expression.
-    fn parse_let_expr(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_let(&mut self) -> PResult<'a, P<Expr>> {
         // This is a *approximate* heuristic that detects if `let` chains are
         // being parsed in the right position. It's approximate because it
         // doesn't deny all invalid `let` expressions, just completely wrong usages.
@@ -2363,7 +2364,7 @@ impl<'a> Parser<'a> {
             self.expect(&token::Eq)?;
         }
         let expr = self.with_res(self.restrictions | Restrictions::NO_STRUCT_LITERAL, |this| {
-            this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into())
+            this.parse_expr_assoc_with(1 + prec_let_scrutinee_needs_par(), None.into())
         })?;
         let span = lo.to(expr.span);
         self.sess.gated_spans.gate(sym::let_chains, span);
@@ -2371,11 +2372,11 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses an `else { ... }` expression (`else` token already eaten).
-    fn parse_else_expr(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_else(&mut self) -> PResult<'a, P<Expr>> {
         let else_span = self.prev_token.span; // `else`
         let attrs = self.parse_outer_attributes()?; // For recovery.
         let expr = if self.eat_keyword(kw::If) {
-            self.parse_if_expr()?
+            self.parse_expr_if()?
         } else if self.check(&TokenKind::OpenDelim(Delimiter::Brace)) {
             self.parse_simple_block()?
         } else {
@@ -2449,7 +2450,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses `for <src_pat> in <src_expr> <src_loop_block>` (`for` token already eaten).
-    fn parse_for_expr(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
+    fn parse_expr_for(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
         // Record whether we are about to parse `for (`.
         // This is used below for recovery in case of `for ( $stuff ) $block`
         // in which case we will suggest `for $stuff $block`.
@@ -2480,7 +2481,7 @@ impl<'a> Parser<'a> {
             self.sess
                 .emit_err(errors::MissingExpressionInForLoop { span: expr.span.shrink_to_lo() });
             let err_expr = self.mk_expr(expr.span, ExprKind::Err);
-            let block = self.mk_block(vec![], BlockCheckMode::Default, self.prev_token.span);
+            let block = self.mk_block(thin_vec![], BlockCheckMode::Default, self.prev_token.span);
             return Ok(self.mk_expr(
                 lo.to(self.prev_token.span),
                 ExprKind::ForLoop(pat, err_expr, block, opt_label),
@@ -2507,8 +2508,8 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a `while` or `while let` expression (`while` token already eaten).
-    fn parse_while_expr(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
-        let cond = self.parse_cond_expr().map_err(|mut err| {
+    fn parse_expr_while(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
+        let cond = self.parse_expr_cond().map_err(|mut err| {
             err.span_label(lo, "while parsing the condition of this `while` expression");
             err
         })?;
@@ -2525,7 +2526,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses `loop { ... }` (`loop` token already eaten).
-    fn parse_loop_expr(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
+    fn parse_expr_loop(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
         let loop_span = self.prev_token.span;
         let (attrs, body) = self.parse_inner_attrs_and_block()?;
         Ok(self.mk_expr_with_attrs(
@@ -2543,7 +2544,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a `match ... { ... }` expression (`match` token already eaten).
-    fn parse_match_expr(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_expr_match(&mut self) -> PResult<'a, P<Expr>> {
         let match_span = self.prev_token.span;
         let lo = self.prev_token.span;
         let scrutinee = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
@@ -2565,7 +2566,7 @@ impl<'a> Parser<'a> {
         }
         let attrs = self.parse_inner_attributes()?;
 
-        let mut arms: Vec<Arm> = Vec::new();
+        let mut arms = ThinVec::new();
         while self.token != token::CloseDelim(Delimiter::Brace) {
             match self.parse_arm() {
                 Ok(arm) => arms.push(arm),
@@ -2913,7 +2914,7 @@ impl<'a> Parser<'a> {
             if let Err(err) = self.expect(&token::OpenDelim(Delimiter::Brace)) {
                 return Some(Err(err));
             }
-            let expr = self.parse_struct_expr(qself.clone(), path.clone(), true);
+            let expr = self.parse_expr_struct(qself.clone(), path.clone(), true);
             if let (Ok(expr), false) = (&expr, struct_allowed) {
                 // This is a struct literal, but we don't can't accept them here.
                 self.sess.emit_err(errors::StructLiteralNotAllowedHere {
@@ -2934,8 +2935,8 @@ impl<'a> Parser<'a> {
         pth: ast::Path,
         recover: bool,
         close_delim: Delimiter,
-    ) -> PResult<'a, (Vec<ExprField>, ast::StructRest, bool)> {
-        let mut fields = Vec::new();
+    ) -> PResult<'a, (ThinVec<ExprField>, ast::StructRest, bool)> {
+        let mut fields = ThinVec::new();
         let mut base = ast::StructRest::None;
         let mut recover_async = false;
 
@@ -3042,7 +3043,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Precondition: already parsed the '{'.
-    pub(super) fn parse_struct_expr(
+    pub(super) fn parse_expr_struct(
         &mut self,
         qself: Option<P<ast::QSelf>>,
         pth: ast::Path,
@@ -3211,7 +3212,7 @@ impl<'a> Parser<'a> {
         ExprKind::Index(expr, idx)
     }
 
-    fn mk_call(&self, f: P<Expr>, args: Vec<P<Expr>>) -> ExprKind {
+    fn mk_call(&self, f: P<Expr>, args: ThinVec<P<Expr>>) -> ExprKind {
         ExprKind::Call(f, args)
     }
 
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index 23f49ec55a1..8d0f168e09d 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -14,10 +14,11 @@ use rustc_ast::{
 use rustc_errors::{Applicability, PResult};
 use rustc_span::symbol::{kw, Ident};
 use rustc_span::Span;
+use thin_vec::ThinVec;
 
 enum PredicateOrStructBody {
     Predicate(ast::WherePredicate),
-    StructBody(Vec<ast::FieldDef>),
+    StructBody(ThinVec<ast::FieldDef>),
 }
 
 impl<'a> Parser<'a> {
@@ -121,8 +122,8 @@ impl<'a> Parser<'a> {
 
     /// Parses a (possibly empty) list of lifetime and type parameters, possibly including
     /// a trailing comma and erroneous trailing attributes.
-    pub(super) fn parse_generic_params(&mut self) -> PResult<'a, Vec<ast::GenericParam>> {
-        let mut params = Vec::new();
+    pub(super) fn parse_generic_params(&mut self) -> PResult<'a, ThinVec<ast::GenericParam>> {
+        let mut params = ThinVec::new();
         let mut done = false;
         while !done {
             let attrs = self.parse_outer_attributes()?;
@@ -251,13 +252,13 @@ impl<'a> Parser<'a> {
             self.expect_gt()?;
             (params, span_lo.to(self.prev_token.span))
         } else {
-            (vec![], self.prev_token.span.shrink_to_hi())
+            (ThinVec::new(), self.prev_token.span.shrink_to_hi())
         };
         Ok(ast::Generics {
             params,
             where_clause: WhereClause {
                 has_where_token: false,
-                predicates: Vec::new(),
+                predicates: ThinVec::new(),
                 span: self.prev_token.span.shrink_to_hi(),
             },
             span,
@@ -277,17 +278,17 @@ impl<'a> Parser<'a> {
         &mut self,
         struct_name: Ident,
         body_insertion_point: Span,
-    ) -> PResult<'a, (WhereClause, Option<Vec<ast::FieldDef>>)> {
+    ) -> PResult<'a, (WhereClause, Option<ThinVec<ast::FieldDef>>)> {
         self.parse_where_clause_common(Some((struct_name, body_insertion_point)))
     }
 
     fn parse_where_clause_common(
         &mut self,
         struct_: Option<(Ident, Span)>,
-    ) -> PResult<'a, (WhereClause, Option<Vec<ast::FieldDef>>)> {
+    ) -> PResult<'a, (WhereClause, Option<ThinVec<ast::FieldDef>>)> {
         let mut where_clause = WhereClause {
             has_where_token: false,
-            predicates: Vec::new(),
+            predicates: ThinVec::new(),
             span: self.prev_token.span.shrink_to_hi(),
         };
         let mut tuple_struct_body = None;
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index f164bb330f3..9d9ae154ad4 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -26,7 +26,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::DUMMY_SP;
 use std::fmt::Write;
 use std::mem;
-use thin_vec::ThinVec;
+use thin_vec::{thin_vec, ThinVec};
 
 impl<'a> Parser<'a> {
     /// Parses a source module as a crate. This is the main entry point for the parser.
@@ -56,12 +56,12 @@ impl<'a> Parser<'a> {
     pub fn parse_mod(
         &mut self,
         term: &TokenKind,
-    ) -> PResult<'a, (AttrVec, Vec<P<Item>>, ModSpans)> {
+    ) -> PResult<'a, (AttrVec, ThinVec<P<Item>>, ModSpans)> {
         let lo = self.token.span;
         let attrs = self.parse_inner_attributes()?;
 
         let post_attr_lo = self.token.span;
-        let mut items = vec![];
+        let mut items = ThinVec::new();
         while let Some(item) = self.parse_item(ForceCollect::No)? {
             items.push(item);
             self.maybe_consume_incorrect_semicolon(&items);
@@ -646,20 +646,20 @@ impl<'a> Parser<'a> {
         &mut self,
         attrs: &mut AttrVec,
         mut parse_item: impl FnMut(&mut Parser<'a>) -> PResult<'a, Option<Option<T>>>,
-    ) -> PResult<'a, Vec<T>> {
+    ) -> PResult<'a, ThinVec<T>> {
         let open_brace_span = self.token.span;
 
         // Recover `impl Ty;` instead of `impl Ty {}`
         if self.token == TokenKind::Semi {
             self.sess.emit_err(errors::UseEmptyBlockNotSemi { span: self.token.span });
             self.bump();
-            return Ok(vec![]);
+            return Ok(ThinVec::new());
         }
 
         self.expect(&token::OpenDelim(Delimiter::Brace))?;
         attrs.extend(self.parse_inner_attributes()?);
 
-        let mut items = Vec::new();
+        let mut items = ThinVec::new();
         while !self.eat(&token::CloseDelim(Delimiter::Brace)) {
             if self.recover_doc_comment_before_brace() {
                 continue;
@@ -997,7 +997,7 @@ impl<'a> Parser<'a> {
     /// ```text
     /// USE_TREE_LIST = Ø | (USE_TREE `,`)* USE_TREE [`,`]
     /// ```
-    fn parse_use_tree_list(&mut self) -> PResult<'a, Vec<(UseTree, ast::NodeId)>> {
+    fn parse_use_tree_list(&mut self) -> PResult<'a, ThinVec<(UseTree, ast::NodeId)>> {
         self.parse_delim_comma_seq(Delimiter::Brace, |p| {
             p.recover_diff_marker();
             Ok((p.parse_use_tree()?, DUMMY_NODE_ID))
@@ -1288,7 +1288,7 @@ impl<'a> Parser<'a> {
         let (variants, _) = if self.token == TokenKind::Semi {
             self.sess.emit_err(errors::UseEmptyBlockNotSemi { span: self.token.span });
             self.bump();
-            (vec![], false)
+            (thin_vec![], false)
         } else {
             self.parse_delim_comma_seq(Delimiter::Brace, |p| p.parse_enum_variant()).map_err(
                 |mut e| {
@@ -1331,7 +1331,7 @@ impl<'a> Parser<'a> {
                 };
 
                 let disr_expr =
-                    if this.eat(&token::Eq) { Some(this.parse_anon_const_expr()?) } else { None };
+                    if this.eat(&token::Eq) { Some(this.parse_expr_anon_const()?) } else { None };
 
                 let vr = ast::Variant {
                     ident,
@@ -1457,8 +1457,8 @@ impl<'a> Parser<'a> {
         adt_ty: &str,
         ident_span: Span,
         parsed_where: bool,
-    ) -> PResult<'a, (Vec<FieldDef>, /* recovered */ bool)> {
-        let mut fields = Vec::new();
+    ) -> PResult<'a, (ThinVec<FieldDef>, /* recovered */ bool)> {
+        let mut fields = ThinVec::new();
         let mut recovered = false;
         if self.eat(&token::OpenDelim(Delimiter::Brace)) {
             while self.token != token::CloseDelim(Delimiter::Brace) {
@@ -1498,7 +1498,7 @@ impl<'a> Parser<'a> {
         Ok((fields, recovered))
     }
 
-    pub(super) fn parse_tuple_struct_body(&mut self) -> PResult<'a, Vec<FieldDef>> {
+    pub(super) fn parse_tuple_struct_body(&mut self) -> PResult<'a, ThinVec<FieldDef>> {
         // This is the case where we find `struct Foo<T>(T) where T: Copy;`
         // Unit like structs are handled in parse_item_struct function
         self.parse_paren_comma_seq(|p| {
@@ -1722,7 +1722,7 @@ impl<'a> Parser<'a> {
         }
         if self.token.kind == token::Eq {
             self.bump();
-            let const_expr = self.parse_anon_const_expr()?;
+            let const_expr = self.parse_expr_anon_const()?;
             let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
             self.struct_span_err(sp, "default values on `struct` fields aren't supported")
                 .span_suggestion(
@@ -2374,7 +2374,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses the parameter list of a function, including the `(` and `)` delimiters.
-    pub(super) fn parse_fn_params(&mut self, req_name: ReqName) -> PResult<'a, Vec<Param>> {
+    pub(super) fn parse_fn_params(&mut self, req_name: ReqName) -> PResult<'a, ThinVec<Param>> {
         let mut first_param = true;
         // Parse the arguments, starting out with `self` being allowed...
         let (mut params, _) = self.parse_paren_comma_seq(|p| {
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index a74f408d774..fda9151478f 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -36,9 +36,10 @@ use rustc_errors::{
 use rustc_session::parse::ParseSess;
 use rustc_span::source_map::{Span, DUMMY_SP};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
-
 use std::ops::Range;
 use std::{cmp, mem, slice};
+use thin_vec::ThinVec;
+use tracing::debug;
 
 use crate::errors::{
     DocCommentDoesNotDocumentAnything, IncorrectVisibilityRestriction, MismatchedClosingDelimiter,
@@ -853,11 +854,11 @@ impl<'a> Parser<'a> {
         sep: SeqSep,
         expect: TokenExpectType,
         mut f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
-    ) -> PResult<'a, (Vec<T>, bool /* trailing */, bool /* recovered */)> {
+    ) -> PResult<'a, (ThinVec<T>, bool /* trailing */, bool /* recovered */)> {
         let mut first = true;
         let mut recovered = false;
         let mut trailing = false;
-        let mut v = vec![];
+        let mut v = ThinVec::new();
         let unclosed_delims = !self.unclosed_delims.is_empty();
 
         while !self.expect_any_with_type(kets, expect) {
@@ -981,7 +982,11 @@ impl<'a> Parser<'a> {
         let initial_semicolon = self.token.span;
 
         while self.eat(&TokenKind::Semi) {
-            let _ = self.parse_stmt(ForceCollect::Yes)?;
+            let _ =
+                self.parse_stmt_without_recovery(false, ForceCollect::Yes).unwrap_or_else(|e| {
+                    e.cancel();
+                    None
+                });
         }
 
         expect_err.set_primary_message(
@@ -1037,7 +1042,7 @@ impl<'a> Parser<'a> {
         ket: &TokenKind,
         sep: SeqSep,
         f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
-    ) -> PResult<'a, (Vec<T>, bool, bool)> {
+    ) -> PResult<'a, (ThinVec<T>, bool, bool)> {
         self.parse_seq_to_before_tokens(&[ket], sep, TokenExpectType::Expect, f)
     }
 
@@ -1049,7 +1054,7 @@ impl<'a> Parser<'a> {
         ket: &TokenKind,
         sep: SeqSep,
         f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
-    ) -> PResult<'a, (Vec<T>, bool /* trailing */)> {
+    ) -> PResult<'a, (ThinVec<T>, bool /* trailing */)> {
         let (val, trailing, recovered) = self.parse_seq_to_before_end(ket, sep, f)?;
         if !recovered {
             self.eat(ket);
@@ -1066,7 +1071,7 @@ impl<'a> Parser<'a> {
         ket: &TokenKind,
         sep: SeqSep,
         f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
-    ) -> PResult<'a, (Vec<T>, bool)> {
+    ) -> PResult<'a, (ThinVec<T>, bool)> {
         self.expect(bra)?;
         self.parse_seq_to_end(ket, sep, f)
     }
@@ -1075,7 +1080,7 @@ impl<'a> Parser<'a> {
         &mut self,
         delim: Delimiter,
         f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
-    ) -> PResult<'a, (Vec<T>, bool)> {
+    ) -> PResult<'a, (ThinVec<T>, bool)> {
         self.parse_unspanned_seq(
             &token::OpenDelim(delim),
             &token::CloseDelim(delim),
@@ -1087,7 +1092,7 @@ impl<'a> Parser<'a> {
     fn parse_paren_comma_seq<T>(
         &mut self,
         f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
-    ) -> PResult<'a, (Vec<T>, bool)> {
+    ) -> PResult<'a, (ThinVec<T>, bool)> {
         self.parse_delim_comma_seq(Delimiter::Parenthesis, f)
     }
 
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index b054dc59a0c..8e920f1c421 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -8,6 +8,7 @@ use crate::errors::{
     TrailingVertNotAllowed, UnexpectedLifetimeInPattern, UnexpectedVertVertBeforeFunctionParam,
     UnexpectedVertVertInPattern,
 };
+use crate::fluent_generated as fluent;
 use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
 use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor};
 use rustc_ast::ptr::P;
@@ -17,12 +18,11 @@ use rustc_ast::{
     PatField, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
 };
 use rustc_ast_pretty::pprust;
-use rustc_errors::{
-    fluent, Applicability, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, PResult,
-};
+use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, PResult};
 use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::source_map::{respan, Span, Spanned};
 use rustc_span::symbol::{kw, sym, Ident};
+use thin_vec::{thin_vec, ThinVec};
 
 #[derive(PartialEq, Copy, Clone)]
 pub enum Expected {
@@ -155,7 +155,7 @@ impl<'a> Parser<'a> {
                 // If there was a leading vert, treat this as an or-pattern. This improves
                 // diagnostics.
                 let span = leading_vert_span.to(self.prev_token.span);
-                return Ok((self.mk_pat(span, PatKind::Or(vec![first_pat])), trailing_vert));
+                return Ok((self.mk_pat(span, PatKind::Or(thin_vec![first_pat])), trailing_vert));
             }
 
             return Ok((first_pat, trailing_vert));
@@ -163,7 +163,7 @@ impl<'a> Parser<'a> {
 
         // Parse the patterns `p_1 | ... | p_n` where `n > 0`.
         let lo = leading_vert_span.unwrap_or(first_pat.span);
-        let mut pats = vec![first_pat];
+        let mut pats = thin_vec![first_pat];
         loop {
             match self.eat_or_separator(Some(lo)) {
                 EatOrResult::AteOr => {}
@@ -853,7 +853,7 @@ impl<'a> Parser<'a> {
             e.span_label(path.span, "while parsing the fields for this pattern");
             e.emit();
             self.recover_stmt();
-            (vec![], true)
+            (ThinVec::new(), true)
         });
         self.bump();
         Ok(PatKind::Struct(qself, path, fields, etc))
@@ -932,8 +932,8 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses the fields of a struct-like pattern.
-    fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<PatField>, bool)> {
-        let mut fields = Vec::new();
+    fn parse_pat_fields(&mut self) -> PResult<'a, (ThinVec<PatField>, bool)> {
+        let mut fields = ThinVec::new();
         let mut etc = false;
         let mut ate_comma = true;
         let mut delayed_err: Option<DiagnosticBuilder<'a, ErrorGuaranteed>> = None;
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 49959a8981c..b50d2984a4e 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -332,7 +332,7 @@ impl<'a> Parser<'a> {
         style: PathStyle,
         lo: Span,
         ty_generics: Option<&Generics>,
-    ) -> PResult<'a, Vec<AngleBracketedArg>> {
+    ) -> PResult<'a, ThinVec<AngleBracketedArg>> {
         // We need to detect whether there are extra leading left angle brackets and produce an
         // appropriate error and suggestion. This cannot be implemented by looking ahead at
         // upcoming tokens for a matching `>` character - if there are unmatched `<` tokens
@@ -472,8 +472,8 @@ impl<'a> Parser<'a> {
     pub(super) fn parse_angle_args(
         &mut self,
         ty_generics: Option<&Generics>,
-    ) -> PResult<'a, Vec<AngleBracketedArg>> {
-        let mut args = Vec::new();
+    ) -> PResult<'a, ThinVec<AngleBracketedArg>> {
+        let mut args = ThinVec::new();
         while let Some(arg) = self.parse_angle_arg(ty_generics)? {
             args.push(arg);
             if !self.eat(&token::Comma) {
@@ -653,7 +653,7 @@ impl<'a> Parser<'a> {
     pub(super) fn parse_const_arg(&mut self) -> PResult<'a, AnonConst> {
         // Parse const argument.
         let value = if let token::OpenDelim(Delimiter::Brace) = self.token.kind {
-            self.parse_block_expr(None, self.token.span, BlockCheckMode::Default)?
+            self.parse_expr_block(None, self.token.span, BlockCheckMode::Default)?
         } else {
             self.handle_unambiguous_unbraced_const_arg()?
         };
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 3afda5f69f0..92a22ffc2b0 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -20,8 +20,8 @@ use rustc_ast::{StmtKind, DUMMY_NODE_ID};
 use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult};
 use rustc_span::source_map::{BytePos, Span};
 use rustc_span::symbol::{kw, sym};
-
 use std::mem;
+use thin_vec::{thin_vec, ThinVec};
 
 impl<'a> Parser<'a> {
     /// Parses a statement. This stops just before trailing semicolons on everything but items.
@@ -146,14 +146,14 @@ impl<'a> Parser<'a> {
             }
 
             let expr = if this.eat(&token::OpenDelim(Delimiter::Brace)) {
-                this.parse_struct_expr(None, path, true)?
+                this.parse_expr_struct(None, path, true)?
             } else {
                 let hi = this.prev_token.span;
                 this.mk_expr(lo.to(hi), ExprKind::Path(None, path))
             };
 
             let expr = this.with_res(Restrictions::STMT_EXPR, |this| {
-                this.parse_dot_or_call_expr_with(expr, lo, attrs)
+                this.parse_expr_dot_or_call_with(expr, lo, attrs)
             })?;
             // `DUMMY_SP` will get overwritten later in this function
             Ok((this.mk_stmt(rustc_span::DUMMY_SP, StmtKind::Expr(expr)), TrailingToken::None))
@@ -163,7 +163,7 @@ impl<'a> Parser<'a> {
             // Perform this outside of the `collect_tokens_trailing_token` closure,
             // since our outer attributes do not apply to this part of the expression
             let expr = self.with_res(Restrictions::STMT_EXPR, |this| {
-                this.parse_assoc_expr_with(
+                this.parse_expr_assoc_with(
                     0,
                     LhsExpr::AlreadyParsed { expr, starts_statement: true },
                 )
@@ -199,8 +199,8 @@ impl<'a> Parser<'a> {
             // Since none of the above applied, this is an expression statement macro.
             let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac));
             let e = self.maybe_recover_from_bad_qpath(e)?;
-            let e = self.parse_dot_or_call_expr_with(e, lo, attrs)?;
-            let e = self.parse_assoc_expr_with(
+            let e = self.parse_expr_dot_or_call_with(e, lo, attrs)?;
+            let e = self.parse_expr_assoc_with(
                 0,
                 LhsExpr::AlreadyParsed { expr: e, starts_statement: false },
             )?;
@@ -544,7 +544,7 @@ impl<'a> Parser<'a> {
         s: BlockCheckMode,
         recover: AttemptLocalParseRecovery,
     ) -> PResult<'a, P<Block>> {
-        let mut stmts = vec![];
+        let mut stmts = ThinVec::new();
         let mut snapshot = None;
         while !self.eat(&token::CloseDelim(Delimiter::Brace)) {
             if self.token == token::Eof {
@@ -662,7 +662,12 @@ impl<'a> Parser<'a> {
         Ok(Some(stmt))
     }
 
-    pub(super) fn mk_block(&self, stmts: Vec<Stmt>, rules: BlockCheckMode, span: Span) -> P<Block> {
+    pub(super) fn mk_block(
+        &self,
+        stmts: ThinVec<Stmt>,
+        rules: BlockCheckMode,
+        span: Span,
+    ) -> P<Block> {
         P(Block {
             stmts,
             id: DUMMY_NODE_ID,
@@ -682,6 +687,6 @@ impl<'a> Parser<'a> {
     }
 
     pub(super) fn mk_block_err(&self, span: Span) -> P<Block> {
-        self.mk_block(vec![self.mk_stmt_err(span)], BlockCheckMode::Default, span)
+        self.mk_block(thin_vec![self.mk_stmt_err(span)], BlockCheckMode::Default, span)
     }
 }
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 4f4252b532e..6fe4da71f6b 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -21,7 +21,7 @@ use rustc_errors::{Applicability, PResult};
 use rustc_span::source_map::Span;
 use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::Symbol;
-use thin_vec::thin_vec;
+use thin_vec::{thin_vec, ThinVec};
 
 /// Any `?` or `~const` modifiers that appear at the start of a bound.
 struct BoundModifiers {
@@ -273,7 +273,7 @@ impl<'a> Parser<'a> {
             TyKind::Infer
         } else if self.check_fn_front_matter(false, Case::Sensitive) {
             // Function pointer type
-            self.parse_ty_bare_fn(lo, Vec::new(), None, recover_return_sign)?
+            self.parse_ty_bare_fn(lo, ThinVec::new(), None, recover_return_sign)?
         } else if self.check_keyword(kw::For) {
             // Function pointer type or bound list (trait object type) starting with a poly-trait.
             //   `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
@@ -352,7 +352,7 @@ impl<'a> Parser<'a> {
             match ty.kind {
                 // `(TY_BOUND_NOPAREN) + BOUND + ...`.
                 TyKind::Path(None, path) if maybe_bounds => {
-                    self.parse_remaining_bounds_path(Vec::new(), path, lo, true)
+                    self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true)
                 }
                 TyKind::TraitObject(bounds, TraitObjectSyntax::None)
                     if maybe_bounds && bounds.len() == 1 && !trailing_plus =>
@@ -378,7 +378,7 @@ impl<'a> Parser<'a> {
 
     fn parse_remaining_bounds_path(
         &mut self,
-        generic_params: Vec<GenericParam>,
+        generic_params: ThinVec<GenericParam>,
         path: ast::Path,
         lo: Span,
         parse_plus: bool,
@@ -433,7 +433,7 @@ impl<'a> Parser<'a> {
         };
 
         let ty = if self.eat(&token::Semi) {
-            let mut length = self.parse_anon_const_expr()?;
+            let mut length = self.parse_expr_anon_const()?;
             if let Err(e) = self.expect(&token::CloseDelim(Delimiter::Bracket)) {
                 // Try to recover from `X<Y, ...>` when `X::<Y, ...>` works
                 self.check_mistyped_turbofish_with_multiple_type_params(e, &mut length.value)?;
@@ -494,7 +494,7 @@ impl<'a> Parser<'a> {
     // To avoid ambiguity, the type is surrounded by parentheses.
     fn parse_typeof_ty(&mut self) -> PResult<'a, TyKind> {
         self.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
-        let expr = self.parse_anon_const_expr()?;
+        let expr = self.parse_expr_anon_const()?;
         self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
         Ok(TyKind::Typeof(expr))
     }
@@ -511,7 +511,7 @@ impl<'a> Parser<'a> {
     fn parse_ty_bare_fn(
         &mut self,
         lo: Span,
-        mut params: Vec<GenericParam>,
+        mut params: ThinVec<GenericParam>,
         param_insertion_point: Option<Span>,
         recover_return_sign: RecoverReturnSign,
     ) -> PResult<'a, TyKind> {
@@ -545,13 +545,13 @@ impl<'a> Parser<'a> {
     fn recover_fn_ptr_with_generics(
         &mut self,
         lo: Span,
-        params: &mut Vec<GenericParam>,
+        params: &mut ThinVec<GenericParam>,
         param_insertion_point: Option<Span>,
     ) -> PResult<'a, ()> {
         let generics = self.parse_generics()?;
         let arity = generics.params.len();
 
-        let mut lifetimes: Vec<_> = generics
+        let mut lifetimes: ThinVec<_> = generics
             .params
             .into_iter()
             .filter(|param| matches!(param.kind, ast::GenericParamKind::Lifetime))
@@ -662,7 +662,7 @@ impl<'a> Parser<'a> {
             })))
         } else if allow_plus == AllowPlus::Yes && self.check_plus() {
             // `Trait1 + Trait2 + 'a`
-            self.parse_remaining_bounds_path(Vec::new(), path, lo, true)
+            self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true)
         } else {
             // Just a type path.
             Ok(TyKind::Path(None, path))
@@ -993,7 +993,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Optionally parses `for<$generic_params>`.
-    pub(super) fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<GenericParam>> {
+    pub(super) fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, ThinVec<GenericParam>> {
         if self.eat_keyword(kw::For) {
             self.expect_lt()?;
             let params = self.parse_generic_params()?;
@@ -1002,7 +1002,7 @@ impl<'a> Parser<'a> {
             // parameters, and the lifetime parameters must not have bounds.
             Ok(params)
         } else {
-            Ok(Vec::new())
+            Ok(ThinVec::new())
         }
     }
 
@@ -1012,7 +1012,7 @@ impl<'a> Parser<'a> {
     fn recover_fn_trait_with_lifetime_params(
         &mut self,
         fn_path: &mut ast::Path,
-        lifetime_defs: &mut Vec<GenericParam>,
+        lifetime_defs: &mut ThinVec<GenericParam>,
     ) -> PResult<'a, ()> {
         let fn_path_segment = fn_path.segments.last_mut().unwrap();
         let generic_args = if let Some(p_args) = &fn_path_segment.args {
@@ -1046,7 +1046,7 @@ impl<'a> Parser<'a> {
 
         // Parse `(T, U) -> R`.
         let inputs_lo = self.token.span;
-        let inputs: Vec<_> =
+        let inputs: ThinVec<_> =
             self.parse_fn_params(|_| false)?.into_iter().map(|input| input.ty).collect();
         let inputs_span = inputs_lo.to(self.prev_token.span);
         let output = self.parse_ret_ty(AllowPlus::No, RecoverQPath::No, RecoverReturnSign::No)?;
@@ -1072,7 +1072,7 @@ impl<'a> Parser<'a> {
                 kind: ast::GenericParamKind::Lifetime,
                 colon_span: None,
             })
-            .collect::<Vec<GenericParam>>();
+            .collect::<ThinVec<GenericParam>>();
         lifetime_defs.append(&mut generic_params);
 
         let generic_args_span = generic_args.span();
diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_passes/locales/en-US.ftl
index 0c7e02912d4..0ed29ce0d47 100644
--- a/compiler/rustc_error_messages/locales/en-US/passes.ftl
+++ b/compiler/rustc_passes/locales/en-US.ftl
@@ -407,10 +407,10 @@ passes_duplicate_diagnostic_item =
 
 passes_duplicate_diagnostic_item_in_crate =
     duplicate diagnostic item in crate `{$crate_name}`: `{$name}`.
+    .note = the diagnostic item is first defined in crate `{$orig_crate_name}`.
 
 passes_diagnostic_item_first_defined =
     the diagnostic item is first defined here
-    .note = the diagnostic item is first defined in crate `{$orig_crate_name}`.
 
 passes_abi =
     abi: {$abi}
@@ -745,3 +745,7 @@ passes_proc_macro_invalid_abi = proc macro functions may not be `extern "{$abi}"
 passes_proc_macro_unsafe = proc macro functions may not be `unsafe`
 
 passes_skipping_const_checks = skipping const checks
+
+passes_invalid_macro_export_arguments = `{$name}` isn't a valid `#[macro_export]` argument
+
+passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 8ad4a5ef958..5ef3e13eff8 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -4,10 +4,10 @@
 //! conflicts between multiple such attributes attached to the same
 //! item.
 
-use crate::errors;
+use crate::{errors, fluent_generated as fluent};
 use rustc_ast::{ast, AttrStyle, Attribute, LitKind, MetaItemKind, MetaItemLit, NestedMetaItem};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{fluent, Applicability, IntoDiagnosticArg, MultiSpan};
+use rustc_errors::{Applicability, IntoDiagnosticArg, MultiSpan};
 use rustc_expand::base::resolve_path;
 use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
 use rustc_hir as hir;
@@ -23,7 +23,8 @@ use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{ParamEnv, TyCtxt};
 use rustc_session::lint::builtin::{
-    CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, UNUSED_ATTRIBUTES,
+    CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS,
+    UNUSED_ATTRIBUTES,
 };
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::{kw, sym, Symbol};
@@ -935,15 +936,15 @@ impl CheckAttrVisitor<'_> {
                             src.insert(1, '!');
                             err.span_suggestion_verbose(
                                 attr.span,
-                                fluent::suggestion,
+                                fluent::passes_suggestion,
                                 src,
                                 Applicability::MaybeIncorrect,
                             );
                         } else {
-                            err.span_help(attr.span, fluent::help);
+                            err.span_help(attr.span, fluent::passes_help);
                         }
                     }
-                    err.note(fluent::note);
+                    err.note(fluent::passes_note);
                     err
                 },
             );
@@ -2102,7 +2103,33 @@ impl CheckAttrVisitor<'_> {
 
     fn check_macro_export(&self, hir_id: HirId, attr: &Attribute, target: Target) {
         if target != Target::MacroDef {
-            self.tcx.emit_spanned_lint(UNUSED_ATTRIBUTES, hir_id, attr.span, errors::MacroExport);
+            self.tcx.emit_spanned_lint(
+                UNUSED_ATTRIBUTES,
+                hir_id,
+                attr.span,
+                errors::MacroExport::Normal,
+            );
+        } else if let Some(meta_item_list) = attr.meta_item_list() &&
+        !meta_item_list.is_empty() {
+            if meta_item_list.len() > 1 {
+                self.tcx.emit_spanned_lint(
+                    INVALID_MACRO_EXPORT_ARGUMENTS,
+                    hir_id,
+                    attr.span,
+                    errors::MacroExport::TooManyItems,
+                );
+            } else {
+                if meta_item_list[0].name_or_empty() != sym::local_inner_macros {
+                    self.tcx.emit_spanned_lint(
+                        INVALID_MACRO_EXPORT_ARGUMENTS,
+                        hir_id,
+                        meta_item_list[0].span(),
+                        errors::MacroExport::UnknownItem {
+                            name: meta_item_list[0].name_or_empty(),
+                        },
+                    );
+                }
+            }
         }
     }
 
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 668c159f3cc..e2f858a34b6 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -395,6 +395,9 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
                     self.mark_as_used_if_union(*adt, fields);
                 }
             }
+            hir::ExprKind::Closure(cls) => {
+                self.insert_def_id(cls.def_id.to_def_id());
+            }
             _ => (),
         }
 
@@ -691,7 +694,7 @@ impl<'tcx> DeadVisitor<'tcx> {
             })
             .collect();
 
-        let descr = tcx.def_kind(first_id).descr(first_id.to_def_id());
+        let descr = tcx.def_descr(first_id.to_def_id());
         let num = dead_codes.len();
         let multiple = num > 6;
         let name_list = names.into();
@@ -703,7 +706,7 @@ impl<'tcx> DeadVisitor<'tcx> {
         };
 
         let parent_info = if let Some(parent_item) = parent_item {
-            let parent_descr = tcx.def_kind(parent_item).descr(parent_item.to_def_id());
+            let parent_descr = tcx.def_descr(parent_item.to_def_id());
             Some(ParentInfo {
                 num,
                 descr,
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 68b098e3457..2c0d21b4798 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -3,6 +3,7 @@ use std::{
     path::{Path, PathBuf},
 };
 
+use crate::fluent_generated as fluent;
 use rustc_ast::Label;
 use rustc_errors::{
     error_code, Applicability, DiagnosticSymbolList, ErrorGuaranteed, IntoDiagnostic, MultiSpan,
@@ -261,7 +262,7 @@ pub struct DocKeywordConflict {
 pub struct DocInlineOnlyUse {
     #[label]
     pub attr_span: Span,
-    #[label(not_a_use_item_label)]
+    #[label(passes_not_a_use_item_label)]
     pub item_span: Option<Span>,
 }
 
@@ -300,7 +301,7 @@ pub struct DocTestUnknownAny {
 #[derive(LintDiagnostic)]
 #[diag(passes_doc_test_unknown_spotlight)]
 #[note]
-#[note(no_op_note)]
+#[note(passes_no_op_note)]
 pub struct DocTestUnknownSpotlight {
     pub path: String,
     #[suggestion(style = "short", applicability = "machine-applicable", code = "notable_trait")]
@@ -573,9 +574,9 @@ pub struct DebugVisualizerPlacement {
 
 #[derive(Diagnostic)]
 #[diag(passes_debug_visualizer_invalid)]
-#[note(note_1)]
-#[note(note_2)]
-#[note(note_3)]
+#[note(passes_note_1)]
+#[note(passes_note_2)]
+#[note(passes_note_3)]
 pub struct DebugVisualizerInvalid {
     #[primary_span]
     pub span: Span,
@@ -640,8 +641,16 @@ pub struct MacroUse {
 }
 
 #[derive(LintDiagnostic)]
-#[diag(passes_macro_export)]
-pub struct MacroExport;
+pub enum MacroExport {
+    #[diag(passes_macro_export)]
+    Normal,
+
+    #[diag(passes_invalid_macro_export_arguments)]
+    UnknownItem { name: Symbol },
+
+    #[diag(passes_invalid_macro_export_arguments_too_many_items)]
+    TooManyItems,
+}
 
 #[derive(LintDiagnostic)]
 #[diag(passes_plugin_registrar)]
@@ -782,7 +791,7 @@ impl IntoDiagnostic<'_> for InvalidAttrAtCrateLevel {
         self,
         handler: &'_ rustc_errors::Handler,
     ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
-        let mut diag = handler.struct_err(rustc_errors::fluent::passes_invalid_attr_at_crate_level);
+        let mut diag = handler.struct_err(fluent::passes_invalid_attr_at_crate_level);
         diag.set_span(self.span);
         diag.set_arg("name", self.name);
         // Only emit an error with a suggestion if we can create a string out
@@ -791,7 +800,7 @@ impl IntoDiagnostic<'_> for InvalidAttrAtCrateLevel {
             let replacement = src.replace("#!", "#");
             diag.span_suggestion_verbose(
                 self.span,
-                rustc_errors::fluent::suggestion,
+                fluent::passes_suggestion,
                 replacement,
                 rustc_errors::Applicability::MachineApplicable,
             );
@@ -917,17 +926,17 @@ impl<'a> IntoDiagnostic<'_> for BreakNonLoop<'a> {
     ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
         let mut diag = handler.struct_span_err_with_code(
             self.span,
-            rustc_errors::fluent::passes_break_non_loop,
+            fluent::passes_break_non_loop,
             error_code!(E0571),
         );
         diag.set_arg("kind", self.kind);
-        diag.span_label(self.span, rustc_errors::fluent::label);
+        diag.span_label(self.span, fluent::passes_label);
         if let Some(head) = self.head {
-            diag.span_label(head, rustc_errors::fluent::label2);
+            diag.span_label(head, fluent::passes_label2);
         }
         diag.span_suggestion(
             self.span,
-            rustc_errors::fluent::suggestion,
+            fluent::passes_suggestion,
             self.suggestion,
             Applicability::MaybeIncorrect,
         );
@@ -945,7 +954,7 @@ impl<'a> IntoDiagnostic<'_> for BreakNonLoop<'a> {
                 _ => {
                     diag.span_suggestion(
                         self.break_expr_span,
-                        rustc_errors::fluent::break_expr_suggestion,
+                        fluent::passes_break_expr_suggestion,
                         label.ident,
                         Applicability::MaybeIncorrect,
                     );
@@ -962,7 +971,7 @@ pub struct ContinueLabeledBlock {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(block_label)]
+    #[label(passes_block_label)]
     pub block_span: Span,
 }
 
@@ -972,7 +981,7 @@ pub struct BreakInsideClosure<'a> {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(closure_label)]
+    #[label(passes_closure_label)]
     pub closure_span: Span,
     pub name: &'a str,
 }
@@ -983,7 +992,7 @@ pub struct BreakInsideAsyncBlock<'a> {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(async_block_label)]
+    #[label(passes_async_block_label)]
     pub closure_span: Span,
     pub name: &'a str,
 }
@@ -1056,14 +1065,14 @@ impl IntoDiagnostic<'_> for NakedFunctionsAsmBlock {
     ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
         let mut diag = handler.struct_span_err_with_code(
             self.span,
-            rustc_errors::fluent::passes_naked_functions_asm_block,
+            fluent::passes_naked_functions_asm_block,
             error_code!(E0787),
         );
         for span in self.multiple_asms.iter() {
-            diag.span_label(*span, rustc_errors::fluent::label_multiple_asm);
+            diag.span_label(*span, fluent::passes_label_multiple_asm);
         }
         for span in self.non_asms.iter() {
-            diag.span_label(*span, rustc_errors::fluent::label_non_asm);
+            diag.span_label(*span, fluent::passes_label_non_asm);
         }
         diag
     }
@@ -1122,9 +1131,9 @@ pub struct AttrOnlyInFunctions {
 pub struct MultipleRustcMain {
     #[primary_span]
     pub span: Span,
-    #[label(first)]
+    #[label(passes_first)]
     pub first: Span,
-    #[label(additional)]
+    #[label(passes_additional)]
     pub additional: Span,
 }
 
@@ -1135,7 +1144,7 @@ pub struct MultipleStartFunctions {
     pub span: Span,
     #[label]
     pub labeled: Span,
-    #[label(previous)]
+    #[label(passes_previous)]
     pub previous: Span,
 }
 
@@ -1180,7 +1189,7 @@ impl<'a> IntoDiagnostic<'a> for NoMainErr {
     ) -> rustc_errors::DiagnosticBuilder<'a, ErrorGuaranteed> {
         let mut diag = handler.struct_span_err_with_code(
             DUMMY_SP,
-            rustc_errors::fluent::passes_no_main_function,
+            fluent::passes_no_main_function,
             error_code!(E0601),
         );
         diag.set_arg("crate_name", self.crate_name);
@@ -1188,16 +1197,16 @@ impl<'a> IntoDiagnostic<'a> for NoMainErr {
         diag.set_arg("has_filename", self.has_filename);
         let note = if !self.non_main_fns.is_empty() {
             for &span in &self.non_main_fns {
-                diag.span_note(span, rustc_errors::fluent::here_is_main);
+                diag.span_note(span, fluent::passes_here_is_main);
             }
-            diag.note(rustc_errors::fluent::one_or_more_possible_main);
-            diag.help(rustc_errors::fluent::consider_moving_main);
+            diag.note(fluent::passes_one_or_more_possible_main);
+            diag.help(fluent::passes_consider_moving_main);
             // There were some functions named `main` though. Try to give the user a hint.
-            rustc_errors::fluent::main_must_be_defined_at_crate
+            fluent::passes_main_must_be_defined_at_crate
         } else if self.has_filename {
-            rustc_errors::fluent::consider_adding_main_to_file
+            fluent::passes_consider_adding_main_to_file
         } else {
-            rustc_errors::fluent::consider_adding_main_at_crate
+            fluent::passes_consider_adding_main_at_crate
         };
         if self.file_empty {
             diag.note(note);
@@ -1208,11 +1217,11 @@ impl<'a> IntoDiagnostic<'a> for NoMainErr {
 
         if let Some(main_def) = self.main_def_opt && main_def.opt_fn_def_id().is_none(){
             // There is something at `crate::main`, but it is not a function definition.
-            diag.span_label(main_def.span, rustc_errors::fluent::non_function_main);
+            diag.span_label(main_def.span, fluent::passes_non_function_main);
         }
 
         if self.add_teach_note {
-            diag.note(rustc_errors::fluent::teach_note);
+            diag.note(fluent::passes_teach_note);
         }
         diag
     }
@@ -1241,12 +1250,9 @@ impl IntoDiagnostic<'_> for DuplicateLangItem {
     ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
         let mut diag = handler.struct_err_with_code(
             match self.duplicate {
-                Duplicate::Plain => rustc_errors::fluent::passes_duplicate_lang_item,
-
-                Duplicate::Crate => rustc_errors::fluent::passes_duplicate_lang_item_crate,
-                Duplicate::CrateDepends => {
-                    rustc_errors::fluent::passes_duplicate_lang_item_crate_depends
-                }
+                Duplicate::Plain => fluent::passes_duplicate_lang_item,
+                Duplicate::Crate => fluent::passes_duplicate_lang_item_crate,
+                Duplicate::CrateDepends => fluent::passes_duplicate_lang_item_crate_depends,
             },
             error_code!(E0152),
         );
@@ -1261,24 +1267,24 @@ impl IntoDiagnostic<'_> for DuplicateLangItem {
             diag.set_span(span);
         }
         if let Some(span) = self.first_defined_span {
-            diag.span_note(span, rustc_errors::fluent::first_defined_span);
+            diag.span_note(span, fluent::passes_first_defined_span);
         } else {
             if self.orig_dependency_of.is_empty() {
-                diag.note(rustc_errors::fluent::first_defined_crate);
+                diag.note(fluent::passes_first_defined_crate);
             } else {
-                diag.note(rustc_errors::fluent::first_defined_crate_depends);
+                diag.note(fluent::passes_first_defined_crate_depends);
             }
 
             if self.orig_is_local {
-                diag.note(rustc_errors::fluent::first_definition_local);
+                diag.note(fluent::passes_first_definition_local);
             } else {
-                diag.note(rustc_errors::fluent::first_definition_path);
+                diag.note(fluent::passes_first_definition_path);
             }
 
             if self.is_local {
-                diag.note(rustc_errors::fluent::second_definition_local);
+                diag.note(fluent::passes_second_definition_local);
             } else {
-                diag.note(rustc_errors::fluent::second_definition_path);
+                diag.note(fluent::passes_second_definition_path);
             }
         }
         diag
@@ -1389,7 +1395,7 @@ pub struct UselessStability {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(item)]
+    #[label(passes_item)]
     pub item_sp: Span,
 }
 
@@ -1399,7 +1405,7 @@ pub struct InvalidStability {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(item)]
+    #[label(passes_item)]
     pub item_sp: Span,
 }
 
@@ -1409,7 +1415,7 @@ pub struct CannotStabilizeDeprecated {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(item)]
+    #[label(passes_item)]
     pub item_sp: Span,
 }
 
@@ -1419,7 +1425,7 @@ pub struct InvalidDeprecationVersion {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(item)]
+    #[label(passes_item)]
     pub item_sp: Span,
 }
 
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index 6e621b7eb5e..0cb8424082c 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -18,6 +18,8 @@ extern crate rustc_middle;
 #[macro_use]
 extern crate tracing;
 
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_macros::fluent_messages;
 use rustc_middle::ty::query::Providers;
 
 mod check_attr;
@@ -40,6 +42,8 @@ pub mod stability;
 mod upvars;
 mod weak_lang_items;
 
+fluent_messages! { "../locales/en-US.ftl" }
+
 pub fn provide(providers: &mut Providers) {
     check_attr::provide(providers);
     check_const::provide(providers);
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index 678f1815d01..df5c8f53ec1 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -475,7 +475,7 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
             | hir::ExprKind::InlineAsm(..)
             | hir::ExprKind::Box(..)
             | hir::ExprKind::Type(..)
-            | hir::ExprKind::Err
+            | hir::ExprKind::Err(_)
             | hir::ExprKind::Path(hir::QPath::TypeRelative(..))
             | hir::ExprKind::Path(hir::QPath::LangItem(..)) => {
                 intravisit::walk_expr(self, expr);
@@ -1129,7 +1129,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
 
             hir::ExprKind::Lit(..)
             | hir::ExprKind::ConstBlock(..)
-            | hir::ExprKind::Err
+            | hir::ExprKind::Err(_)
             | hir::ExprKind::Path(hir::QPath::TypeRelative(..))
             | hir::ExprKind::Path(hir::QPath::LangItem(..)) => succ,
 
@@ -1427,7 +1427,7 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr<'tcx>) {
         | hir::ExprKind::Yield(..)
         | hir::ExprKind::Box(..)
         | hir::ExprKind::Type(..)
-        | hir::ExprKind::Err => {}
+        | hir::ExprKind::Err(_) => {}
     }
 }
 
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs
index acc54e7e110..c5b5cf7f5a9 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_passes/src/naked_functions.rs
@@ -219,7 +219,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
                 hir::intravisit::walk_expr(self, expr);
             }
 
-            ExprKind::Err => {
+            ExprKind::Err(_) => {
                 self.items.push((ItemKind::Err, span));
             }
         }
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 2e736039fb5..16194a6f196 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -523,7 +523,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
             && stab.is_none()
             && self.effective_visibilities.is_reachable(def_id)
         {
-            let descr = self.tcx.def_kind(def_id).descr(def_id.to_def_id());
+            let descr = self.tcx.def_descr(def_id.to_def_id());
             self.tcx.sess.emit_err(errors::MissingStabilityAttr { span, descr });
         }
     }
@@ -551,7 +551,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
         let is_reachable = self.effective_visibilities.is_reachable(def_id);
 
         if is_const && is_stable && missing_const_stability_attribute && is_reachable {
-            let descr = self.tcx.def_kind(def_id).descr(def_id.to_def_id());
+            let descr = self.tcx.def_descr(def_id.to_def_id());
             self.tcx.sess.emit_err(errors::MissingConstStabAttr { span, descr });
         }
     }
@@ -748,7 +748,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
                         let mut c = CheckTraitImplStable { tcx: self.tcx, fully_stable: true };
                         c.visit_ty(self_ty);
                         c.visit_trait_ref(t);
-                        if c.fully_stable {
+
+                        // do not lint when the trait isn't resolved, since resolution error should
+                        // be fixed first
+                        if t.path.res != Res::Err && c.fully_stable {
                             self.tcx.struct_span_lint_hir(
                                 INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
                                 item.hir_id(),
diff --git a/compiler/rustc_error_messages/locales/en-US/plugin_impl.ftl b/compiler/rustc_plugin_impl/locales/en-US.ftl
index 8db32a42c1d..8db32a42c1d 100644
--- a/compiler/rustc_error_messages/locales/en-US/plugin_impl.ftl
+++ b/compiler/rustc_plugin_impl/locales/en-US.ftl
diff --git a/compiler/rustc_plugin_impl/src/lib.rs b/compiler/rustc_plugin_impl/src/lib.rs
index 9ac27c65da8..3f03eef9ee3 100644
--- a/compiler/rustc_plugin_impl/src/lib.rs
+++ b/compiler/rustc_plugin_impl/src/lib.rs
@@ -11,11 +11,15 @@
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
 use rustc_lint::LintStore;
+use rustc_macros::fluent_messages;
 
 mod errors;
 pub mod load;
 
+fluent_messages! { "../locales/en-US.ftl" }
+
 /// Structure used to register plugins.
 ///
 /// A plugin registrar function takes an `&mut Registry` and should call
diff --git a/compiler/rustc_error_messages/locales/en-US/privacy.ftl b/compiler/rustc_privacy/locales/en-US.ftl
index a26d1b2b381..a26d1b2b381 100644
--- a/compiler/rustc_error_messages/locales/en-US/privacy.ftl
+++ b/compiler/rustc_privacy/locales/en-US.ftl
diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs
index a6c95f1a815..72b53eefa08 100644
--- a/compiler/rustc_privacy/src/errors.rs
+++ b/compiler/rustc_privacy/src/errors.rs
@@ -57,7 +57,7 @@ pub struct InPublicInterfaceTraits<'a> {
     pub vis_descr: &'static str,
     pub kind: &'a str,
     pub descr: DiagnosticArgFromDisplay<'a>,
-    #[label(visibility_label)]
+    #[label(privacy_visibility_label)]
     pub vis_span: Span,
 }
 
@@ -71,7 +71,7 @@ pub struct InPublicInterface<'a> {
     pub vis_descr: &'static str,
     pub kind: &'a str,
     pub descr: DiagnosticArgFromDisplay<'a>,
-    #[label(visibility_label)]
+    #[label(privacy_visibility_label)]
     pub vis_span: Span,
 }
 
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 58dfca75c65..50176c80232 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -16,11 +16,13 @@ use rustc_ast::MacroDef;
 use rustc_attr as attr;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::intern::Interned;
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{AssocItemKind, HirIdSet, ItemId, Node, PatKind};
+use rustc_macros::fluent_messages;
 use rustc_middle::bug;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::privacy::{EffectiveVisibilities, Level};
@@ -28,7 +30,7 @@ use rustc_middle::span_bug;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::subst::InternalSubsts;
 use rustc_middle::ty::{self, Const, DefIdTree, GenericParamDefKind};
-use rustc_middle::ty::{ir::TypeVisitor, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable};
+use rustc_middle::ty::{TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
 use rustc_session::lint;
 use rustc_span::hygiene::Transparency;
 use rustc_span::symbol::{kw, sym, Ident};
@@ -44,6 +46,8 @@ use errors::{
     UnnamedItemIsPrivate,
 };
 
+fluent_messages! { "../locales/en-US.ftl" }
+
 ////////////////////////////////////////////////////////////////////////////////
 /// Generic infrastructure used to implement specific visitors below.
 ////////////////////////////////////////////////////////////////////////////////
@@ -81,7 +85,10 @@ trait DefIdVisitor<'tcx> {
             dummy: Default::default(),
         }
     }
-    fn visit(&mut self, ty_fragment: impl TypeVisitable<'tcx>) -> ControlFlow<Self::BreakTy> {
+    fn visit(
+        &mut self,
+        ty_fragment: impl TypeVisitable<TyCtxt<'tcx>>,
+    ) -> ControlFlow<Self::BreakTy> {
         ty_fragment.visit_with(&mut self.skeleton())
     }
     fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> ControlFlow<Self::BreakTy> {
@@ -1329,7 +1336,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
                     hir::QPath::Resolved(_, path) => Some(self.tcx.def_path_str(path.res.def_id())),
                     hir::QPath::TypeRelative(_, segment) => Some(segment.ident.to_string()),
                 };
-                let kind = kind.descr(def_id);
+                let kind = self.tcx.def_descr(def_id);
                 let sess = self.tcx.sess;
                 let _ = match name {
                     Some(name) => {
diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml
index 21732d26035..3e8a88c7e81 100644
--- a/compiler/rustc_query_impl/Cargo.toml
+++ b/compiler/rustc_query_impl/Cargo.toml
@@ -20,7 +20,7 @@ rustc-rayon-core = { version = "0.4.0", optional = true }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
-thin-vec = "0.2.9"
+thin-vec = "0.2.12"
 tracing = "0.1"
 
 [features]
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index e2884f2026e..a8592bd7086 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -124,9 +124,7 @@ impl QueryContext for QueryCtxt<'_> {
             };
 
             // Use the `ImplicitCtxt` while we execute the query.
-            tls::enter_context(&new_icx, || {
-                rustc_data_structures::stack::ensure_sufficient_stack(compute)
-            })
+            tls::enter_context(&new_icx, compute)
         })
     }
 
diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml
index 028756b5a0a..7d8f75e2566 100644
--- a/compiler/rustc_query_system/Cargo.toml
+++ b/compiler/rustc_query_system/Cargo.toml
@@ -22,7 +22,7 @@ rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 rustc_type_ir = { path = "../rustc_type_ir" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-thin-vec = "0.2.9"
+thin-vec = "0.2.12"
 tracing = "0.1"
 
 [features]
diff --git a/compiler/rustc_error_messages/locales/en-US/query_system.ftl b/compiler/rustc_query_system/locales/en-US.ftl
index 870e824039c..870e824039c 100644
--- a/compiler/rustc_error_messages/locales/en-US/query_system.ftl
+++ b/compiler/rustc_query_system/locales/en-US.ftl
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 9443ded704d..59e0c359745 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -6,6 +6,7 @@ use rustc_data_structures::sharded::{self, Sharded};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::steal::Steal;
 use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering};
+use rustc_data_structures::OnDrop;
 use rustc_index::vec::IndexVec;
 use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
 use smallvec::{smallvec, SmallVec};
@@ -278,6 +279,7 @@ impl<K: DepKind> DepGraph<K> {
     ///   `arg` parameter.
     ///
     /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/incremental-compilation.html
+    #[inline(always)]
     pub fn with_task<Ctxt: HasDepContext<DepKind = K>, A: Debug, R>(
         &self,
         key: DepNode<K>,
@@ -297,6 +299,7 @@ impl<K: DepKind> DepGraph<K> {
         }
     }
 
+    #[inline(always)]
     fn with_task_impl<Ctxt: HasDepContext<DepKind = K>, A: Debug, R>(
         &self,
         key: DepNode<K>,
@@ -597,6 +600,7 @@ impl<K: DepKind> DepGraph<K> {
         self.data.is_some() && self.dep_node_index_of_opt(dep_node).is_some()
     }
 
+    #[inline]
     pub fn prev_fingerprint_of(&self, dep_node: &DepNode<K>) -> Option<Fingerprint> {
         self.data.as_ref().unwrap().previous.fingerprint_of(dep_node)
     }
@@ -671,17 +675,24 @@ impl<K: DepKind> DepGraph<K> {
         let prev_index = data.previous.node_to_index_opt(dep_node)?;
 
         match data.colors.get(prev_index) {
-            Some(DepNodeColor::Green(dep_node_index)) => Some((prev_index, dep_node_index)),
-            Some(DepNodeColor::Red) => None,
-            None => {
-                // This DepNode and the corresponding query invocation existed
-                // in the previous compilation session too, so we can try to
-                // mark it as green by recursively marking all of its
-                // dependencies green.
-                self.try_mark_previous_green(qcx, data, prev_index, &dep_node)
-                    .map(|dep_node_index| (prev_index, dep_node_index))
-            }
+            Some(DepNodeColor::Green(dep_node_index)) => return Some((prev_index, dep_node_index)),
+            Some(DepNodeColor::Red) => return None,
+            None => {}
         }
+
+        let backtrace = backtrace_printer(qcx.dep_context().sess(), data, prev_index);
+
+        // This DepNode and the corresponding query invocation existed
+        // in the previous compilation session too, so we can try to
+        // mark it as green by recursively marking all of its
+        // dependencies green.
+        let ret = self
+            .try_mark_previous_green(qcx, data, prev_index, &dep_node)
+            .map(|dep_node_index| (prev_index, dep_node_index));
+
+        // We succeeded, no backtrace.
+        backtrace.disable();
+        return ret;
     }
 
     #[instrument(skip(self, qcx, data, parent_dep_node_index), level = "debug")]
@@ -794,7 +805,10 @@ impl<K: DepKind> DepGraph<K> {
         let prev_deps = data.previous.edge_targets_from(prev_dep_node_index);
 
         for &dep_dep_node_index in prev_deps {
-            self.try_mark_parent_green(qcx, data, dep_dep_node_index, dep_node)?
+            let backtrace = backtrace_printer(qcx.dep_context().sess(), data, dep_dep_node_index);
+            let success = self.try_mark_parent_green(qcx, data, dep_dep_node_index, dep_node);
+            backtrace.disable();
+            success?;
         }
 
         // If we got here without hitting a `return` that means that all
@@ -1116,6 +1130,7 @@ impl<K: DepKind> CurrentDepGraph<K> {
 
     /// Writes the node to the current dep-graph and allocates a `DepNodeIndex` for it.
     /// Assumes that this is a node that has no equivalent in the previous dep-graph.
+    #[inline(always)]
     fn intern_new_node(
         &self,
         profiler: &SelfProfilerRef,
@@ -1354,6 +1369,7 @@ impl DepNodeColorMap {
         }
     }
 
+    #[inline]
     fn insert(&self, index: SerializedDepNodeIndex, color: DepNodeColor) {
         self.values[index].store(
             match color {
@@ -1364,3 +1380,26 @@ impl DepNodeColorMap {
         )
     }
 }
+
+fn backtrace_printer<'a, K: DepKind>(
+    sess: &'a rustc_session::Session,
+    graph: &'a DepGraphData<K>,
+    node: SerializedDepNodeIndex,
+) -> OnDrop<impl Fn() + 'a> {
+    OnDrop(
+        #[inline(never)]
+        #[cold]
+        move || {
+            let node = graph.previous.index_to_node(node);
+            // Do not try to rely on DepNode's Debug implementation, since it may panic.
+            let diag = rustc_errors::Diagnostic::new(
+                rustc_errors::Level::FailureNote,
+                &format!(
+                    "encountered while trying to mark dependency green: {:?}({})",
+                    node.kind, node.hash
+                ),
+            );
+            sess.diagnostic().force_print_diagnostic(diag);
+        },
+    )
+}
diff --git a/compiler/rustc_query_system/src/ich/hcx.rs b/compiler/rustc_query_system/src/ich/hcx.rs
index 8db8ee9428b..5593a15412f 100644
--- a/compiler/rustc_query_system/src/ich/hcx.rs
+++ b/compiler/rustc_query_system/src/ich/hcx.rs
@@ -146,7 +146,7 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> {
 
     #[inline]
     fn def_span(&self, def_id: LocalDefId) -> Span {
-        *self.untracked.source_span.read().get(def_id).unwrap_or(&DUMMY_SP)
+        self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
     }
 
     #[inline]
diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs
index 623be668464..6cc4c9a7e1e 100644
--- a/compiler/rustc_query_system/src/lib.rs
+++ b/compiler/rustc_query_system/src/lib.rs
@@ -15,6 +15,9 @@ extern crate rustc_data_structures;
 #[macro_use]
 extern crate rustc_macros;
 
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_macros::fluent_messages;
+
 pub mod cache;
 pub mod dep_graph;
 mod error;
@@ -26,3 +29,5 @@ pub use error::HandleCycleError;
 pub use error::LayoutOfDepth;
 pub use error::QueryOverflow;
 pub use values::Value;
+
+fluent_messages! { "../locales/en-US.ftl" }
diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs
index e840108bdd8..4b3cd16c29f 100644
--- a/compiler/rustc_query_system/src/query/caches.rs
+++ b/compiler/rustc_query_system/src/query/caches.rs
@@ -21,7 +21,7 @@ pub trait QueryStorage {
 }
 
 pub trait QueryCache: QueryStorage + Sized {
-    type Key: Hash + Eq + Clone + Debug;
+    type Key: Hash + Eq + Copy + Debug;
 
     /// Checks if the query is already computed and in the cache.
     /// It returns the shard index and a lock guard to the shard,
@@ -61,7 +61,7 @@ impl<K: Eq + Hash, V: Copy + Debug> QueryStorage for DefaultCache<K, V> {
 
 impl<K, V> QueryCache for DefaultCache<K, V>
 where
-    K: Eq + Hash + Clone + Debug,
+    K: Eq + Hash + Copy + Debug,
     V: Copy + Debug,
 {
     type Key = K;
@@ -179,7 +179,7 @@ impl<K: Eq + Idx, V: Copy + Debug> QueryStorage for VecCache<K, V> {
 
 impl<K, V> QueryCache for VecCache<K, V>
 where
-    K: Eq + Idx + Clone + Debug,
+    K: Eq + Idx + Copy + Debug,
     V: Copy + Debug,
 {
     type Key = K;
diff --git a/compiler/rustc_query_system/src/query/config.rs b/compiler/rustc_query_system/src/query/config.rs
index 56247e827a2..d5637387346 100644
--- a/compiler/rustc_query_system/src/query/config.rs
+++ b/compiler/rustc_query_system/src/query/config.rs
@@ -19,7 +19,9 @@ pub type TryLoadFromDisk<Qcx, Q> =
 pub trait QueryConfig<Qcx: QueryContext> {
     const NAME: &'static str;
 
-    type Key: DepNodeParams<Qcx::DepContext> + Eq + Hash + Clone + Debug;
+    // `Key` and `Value` are `Copy` instead of `Clone` to ensure copying them stays cheap,
+    // but it isn't necessary.
+    type Key: DepNodeParams<Qcx::DepContext> + Eq + Hash + Copy + Debug;
     type Value: Debug + Copy;
 
     type Cache: QueryCache<Key = Self::Key, Value = Self::Value>;
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index 21a0c73d720..586bd38fbb8 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -15,6 +15,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::profiling::TimingGuard;
 #[cfg(parallel_compiler)]
 use rustc_data_structures::sharded::Sharded;
+use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_data_structures::sync::Lock;
 use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, FatalError};
 use rustc_session::Session;
@@ -48,7 +49,7 @@ enum QueryResult<D: DepKind> {
 
 impl<K, D> QueryState<K, D>
 where
-    K: Eq + Hash + Clone + Debug,
+    K: Eq + Hash + Copy + Debug,
     D: DepKind,
 {
     pub fn all_inactive(&self) -> bool {
@@ -77,7 +78,7 @@ where
             for shard in shards.iter() {
                 for (k, v) in shard.iter() {
                     if let QueryResult::Started(ref job) = *v {
-                        let query = make_query(qcx, k.clone());
+                        let query = make_query(qcx, *k);
                         jobs.insert(job.id, QueryJobInfo { query, job: job.clone() });
                     }
                 }
@@ -91,7 +92,7 @@ where
             // really hurt much.)
             for (k, v) in self.active.try_lock()?.iter() {
                 if let QueryResult::Started(ref job) = *v {
-                    let query = make_query(qcx, k.clone());
+                    let query = make_query(qcx, *k);
                     jobs.insert(job.id, QueryJobInfo { query, job: job.clone() });
                 }
             }
@@ -111,7 +112,7 @@ impl<K, D: DepKind> Default for QueryState<K, D> {
 /// This will poison the relevant query if dropped.
 struct JobOwner<'tcx, K, D: DepKind>
 where
-    K: Eq + Hash + Clone,
+    K: Eq + Hash + Copy,
 {
     state: &'tcx QueryState<K, D>,
     key: K,
@@ -163,7 +164,7 @@ where
 
 impl<'tcx, K, D: DepKind> JobOwner<'tcx, K, D>
 where
-    K: Eq + Hash + Clone,
+    K: Eq + Hash + Copy,
 {
     /// Either gets a `JobOwner` corresponding the query, allowing us to
     /// start executing the query, or returns with the result of the query.
@@ -188,14 +189,14 @@ where
         #[cfg(not(parallel_compiler))]
         let mut state_lock = state.active.lock();
         let lock = &mut *state_lock;
+        let current_job_id = qcx.current_query_job();
 
         match lock.entry(key) {
             Entry::Vacant(entry) => {
                 let id = qcx.next_job_id();
-                let job = qcx.current_query_job();
-                let job = QueryJob::new(id, span, job);
+                let job = QueryJob::new(id, span, current_job_id);
 
-                let key = entry.key().clone();
+                let key = *entry.key();
                 entry.insert(QueryResult::Started(job));
 
                 let owner = JobOwner { state, id, key };
@@ -212,7 +213,7 @@ where
                         // so we just return the error.
                         return TryGetJob::Cycle(id.find_cycle_in_stack(
                             qcx.try_collect_active_jobs().unwrap(),
-                            &qcx.current_query_job(),
+                            &current_job_id,
                             span,
                         ));
                     }
@@ -230,7 +231,7 @@ where
 
                         // With parallel queries we might just have to wait on some other
                         // thread.
-                        let result = latch.wait_on(qcx.current_query_job(), span);
+                        let result = latch.wait_on(current_job_id, span);
 
                         match result {
                             Ok(()) => TryGetJob::JobCompleted(query_blocked_prof_timer),
@@ -274,7 +275,7 @@ where
 
 impl<'tcx, K, D> Drop for JobOwner<'tcx, K, D>
 where
-    K: Eq + Hash + Clone,
+    K: Eq + Hash + Copy,
     D: DepKind,
 {
     #[inline(never)]
@@ -291,7 +292,7 @@ where
                 QueryResult::Started(job) => job,
                 QueryResult::Poisoned => panic!(),
             };
-            shard.insert(self.key.clone(), QueryResult::Poisoned);
+            shard.insert(self.key, QueryResult::Poisoned);
             job
         };
         // Also signal the completion of the job, so waiters
@@ -310,7 +311,7 @@ pub(crate) struct CycleError<D: DepKind> {
 /// The result of `try_start`.
 enum TryGetJob<'tcx, K, D>
 where
-    K: Eq + Hash + Clone,
+    K: Eq + Hash + Copy,
     D: DepKind,
 {
     /// The query is not yet started. Contains a guard to the cache eventually used to start it.
@@ -346,10 +347,9 @@ where
     }
 }
 
+#[inline(never)]
 fn try_execute_query<Q, Qcx>(
     qcx: Qcx,
-    state: &QueryState<Q::Key, Qcx::DepKind>,
-    cache: &Q::Cache,
     span: Span,
     key: Q::Key,
     dep_node: Option<DepNode<Qcx::DepKind>>,
@@ -358,10 +358,11 @@ where
     Q: QueryConfig<Qcx>,
     Qcx: QueryContext,
 {
-    match JobOwner::<'_, Q::Key, Qcx::DepKind>::try_start(&qcx, state, span, key.clone()) {
+    let state = Q::query_state(qcx);
+    match JobOwner::<'_, Q::Key, Qcx::DepKind>::try_start(&qcx, state, span, key) {
         TryGetJob::NotYetStarted(job) => {
-            let (result, dep_node_index) =
-                execute_job::<Q, Qcx>(qcx, key.clone(), dep_node, job.id);
+            let (result, dep_node_index) = execute_job::<Q, Qcx>(qcx, key, dep_node, job.id);
+            let cache = Q::query_cache(qcx);
             if Q::FEEDABLE {
                 // We should not compute queries that also got a value via feeding.
                 // This can't happen, as query feeding adds the very dependencies to the fed query
@@ -382,7 +383,7 @@ where
         }
         #[cfg(parallel_compiler)]
         TryGetJob::JobCompleted(query_blocked_prof_timer) => {
-            let Some((v, index)) = cache.lookup(&key) else {
+            let Some((v, index)) = Q::query_cache(qcx).lookup(&key) else {
                 panic!("value must be in cache after waiting")
             };
 
@@ -394,6 +395,7 @@ where
     }
 }
 
+#[inline(always)]
 fn execute_job<Q, Qcx>(
     qcx: Qcx,
     key: Q::Key,
@@ -479,6 +481,7 @@ where
     (result, dep_node_index)
 }
 
+#[inline(always)]
 fn try_load_from_disk_and_cache_in_memory<Q, Qcx>(
     qcx: Qcx,
     key: &Q::Key,
@@ -551,7 +554,7 @@ where
     let prof_timer = qcx.dep_context().profiler().query_provider();
 
     // The dep-graph for this computation is already in-place.
-    let result = dep_graph.with_ignore(|| Q::compute(qcx, key.clone()));
+    let result = dep_graph.with_ignore(|| Q::compute(qcx, *key));
 
     prof_timer.finish_with_query_invocation_id(dep_node_index.into());
 
@@ -569,6 +572,7 @@ where
     Some((result, dep_node_index))
 }
 
+#[inline]
 #[instrument(skip(tcx, result, hash_result), level = "debug")]
 pub(crate) fn incremental_verify_ich<Tcx, V: Debug>(
     tcx: Tcx,
@@ -723,6 +727,7 @@ pub enum QueryMode {
     Ensure,
 }
 
+#[inline(always)]
 pub fn get_query<Q, Qcx, D>(qcx: Qcx, span: Span, key: Q::Key, mode: QueryMode) -> Option<Q::Value>
 where
     D: DepKind,
@@ -740,14 +745,8 @@ where
         None
     };
 
-    let (result, dep_node_index) = try_execute_query::<Q, Qcx>(
-        qcx,
-        Q::query_state(qcx),
-        Q::query_cache(qcx),
-        span,
-        key,
-        dep_node,
-    );
+    let (result, dep_node_index) =
+        ensure_sufficient_stack(|| try_execute_query::<Q, Qcx>(qcx, span, key, dep_node));
     if let Some(dep_node_index) = dep_node_index {
         qcx.dep_context().dep_graph().read_index(dep_node_index)
     }
@@ -763,14 +762,12 @@ where
 {
     // We may be concurrently trying both execute and force a query.
     // Ensure that only one of them runs the query.
-    let cache = Q::query_cache(qcx);
-    if let Some((_, index)) = cache.lookup(&key) {
+    if let Some((_, index)) = Q::query_cache(qcx).lookup(&key) {
         qcx.dep_context().profiler().query_cache_hit(index.into());
         return;
     }
 
-    let state = Q::query_state(qcx);
     debug_assert!(!Q::ANON);
 
-    try_execute_query::<Q, _>(qcx, state, cache, DUMMY_SP, key, Some(dep_node));
+    ensure_sufficient_stack(|| try_execute_query::<Q, _>(qcx, DUMMY_SP, key, Some(dep_node)));
 }
diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml
index d4935b52b10..5c4ec44d2b8 100644
--- a/compiler/rustc_resolve/Cargo.toml
+++ b/compiler/rustc_resolve/Cargo.toml
@@ -25,5 +25,5 @@ rustc_query_system = { path = "../rustc_query_system" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-thin-vec = "0.2.8"
+thin-vec = "0.2.12"
 tracing = "0.1"
diff --git a/compiler/rustc_error_messages/locales/en-US/resolve.ftl b/compiler/rustc_resolve/locales/en-US.ftl
index 817bb83ed78..817bb83ed78 100644
--- a/compiler/rustc_error_messages/locales/en-US/resolve.ftl
+++ b/compiler/rustc_resolve/locales/en-US.ftl
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 9aec25fff0b..ee2d2301399 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -12,11 +12,10 @@ use rustc_errors::{struct_span_err, SuggestionStyle};
 use rustc_feature::BUILTIN_ATTRIBUTES;
 use rustc_hir::def::Namespace::{self, *};
 use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind, PerNS};
-use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
+use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::PrimTy;
-use rustc_index::vec::IndexVec;
 use rustc_middle::bug;
-use rustc_middle::ty::DefIdTree;
+use rustc_middle::ty::{DefIdTree, TyCtxt};
 use rustc_session::lint::builtin::ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE;
 use rustc_session::lint::builtin::MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS;
 use rustc_session::lint::BuiltinLintDiagnostics;
@@ -30,7 +29,7 @@ use rustc_span::{BytePos, Span, SyntaxContext};
 use thin_vec::ThinVec;
 
 use crate::errors as errs;
-use crate::imports::{Import, ImportKind, ImportResolver};
+use crate::imports::{Import, ImportKind};
 use crate::late::{PatternSource, Rib};
 use crate::path_names_to_string;
 use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingError, Finalize};
@@ -154,8 +153,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
             if !candidates.is_empty() {
                 show_candidates(
-                    &self.tcx.sess,
-                    &self.tcx.untracked().source_span.read(),
+                    self.tcx,
                     &mut err,
                     span,
                     &candidates,
@@ -191,7 +189,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
 
         let container = match parent.kind {
-            ModuleKind::Def(kind, _, _) => kind.descr(parent.def_id()),
+            ModuleKind::Def(kind, _, _) => self.tcx.def_kind_descr(kind, parent.def_id()),
             ModuleKind::Block => "block",
         };
 
@@ -687,8 +685,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         err.span_help(span, &help_msg);
                     }
                     show_candidates(
-                        &self.tcx.sess,
-                        &self.tcx.untracked().source_span.read(),
+                        self.tcx,
                         &mut err,
                         Some(span),
                         &import_suggestions,
@@ -1352,8 +1349,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let import_suggestions =
             self.lookup_import_candidates(ident, Namespace::MacroNS, parent_scope, is_expected);
         show_candidates(
-            &self.tcx.sess,
-            &self.tcx.untracked().source_span.read(),
+            self.tcx,
             err,
             None,
             &import_suggestions,
@@ -1808,7 +1804,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         found("module")
                     } else {
                         match binding.res() {
-                            Res::Def(kind, id) => found(kind.descr(id)),
+                            Res::Def(kind, id) => found(self.tcx.def_kind_descr(kind, id)),
                             _ => found(ns_to_try.descr()),
                         }
                     }
@@ -1892,15 +1888,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             (format!("use of undeclared crate or module `{}`", ident), suggestion)
         }
     }
-}
 
-impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
     /// Adds suggestions for a path that cannot be resolved.
     pub(crate) fn make_path_suggestion(
         &mut self,
         span: Span,
         mut path: Vec<Segment>,
-        parent_scope: &ParentScope<'b>,
+        parent_scope: &ParentScope<'a>,
     ) -> Option<(Vec<Segment>, Option<String>)> {
         debug!("make_path_suggestion: span={:?} path={:?}", span, path);
 
@@ -1935,11 +1929,11 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
     fn make_missing_self_suggestion(
         &mut self,
         mut path: Vec<Segment>,
-        parent_scope: &ParentScope<'b>,
+        parent_scope: &ParentScope<'a>,
     ) -> Option<(Vec<Segment>, Option<String>)> {
         // Replace first ident with `self` and check if that is valid.
         path[0].ident.name = kw::SelfLower;
-        let result = self.r.maybe_resolve_path(&path, None, parent_scope);
+        let result = self.maybe_resolve_path(&path, None, parent_scope);
         debug!("make_missing_self_suggestion: path={:?} result={:?}", path, result);
         if let PathResult::Module(..) = result { Some((path, None)) } else { None }
     }
@@ -1954,11 +1948,11 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
     fn make_missing_crate_suggestion(
         &mut self,
         mut path: Vec<Segment>,
-        parent_scope: &ParentScope<'b>,
+        parent_scope: &ParentScope<'a>,
     ) -> Option<(Vec<Segment>, Option<String>)> {
         // Replace first ident with `crate` and check if that is valid.
         path[0].ident.name = kw::Crate;
-        let result = self.r.maybe_resolve_path(&path, None, parent_scope);
+        let result = self.maybe_resolve_path(&path, None, parent_scope);
         debug!("make_missing_crate_suggestion:  path={:?} result={:?}", path, result);
         if let PathResult::Module(..) = result {
             Some((
@@ -1985,11 +1979,11 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
     fn make_missing_super_suggestion(
         &mut self,
         mut path: Vec<Segment>,
-        parent_scope: &ParentScope<'b>,
+        parent_scope: &ParentScope<'a>,
     ) -> Option<(Vec<Segment>, Option<String>)> {
         // Replace first ident with `crate` and check if that is valid.
         path[0].ident.name = kw::Super;
-        let result = self.r.maybe_resolve_path(&path, None, parent_scope);
+        let result = self.maybe_resolve_path(&path, None, parent_scope);
         debug!("make_missing_super_suggestion:  path={:?} result={:?}", path, result);
         if let PathResult::Module(..) = result { Some((path, None)) } else { None }
     }
@@ -2007,7 +2001,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
     fn make_external_crate_suggestion(
         &mut self,
         mut path: Vec<Segment>,
-        parent_scope: &ParentScope<'b>,
+        parent_scope: &ParentScope<'a>,
     ) -> Option<(Vec<Segment>, Option<String>)> {
         if path[1].ident.span.is_rust_2015() {
             return None;
@@ -2017,13 +2011,13 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
         // 1) some consistent ordering for emitted diagnostics, and
         // 2) `std` suggestions before `core` suggestions.
         let mut extern_crate_names =
-            self.r.extern_prelude.iter().map(|(ident, _)| ident.name).collect::<Vec<_>>();
+            self.extern_prelude.iter().map(|(ident, _)| ident.name).collect::<Vec<_>>();
         extern_crate_names.sort_by(|a, b| b.as_str().partial_cmp(a.as_str()).unwrap());
 
         for name in extern_crate_names.into_iter() {
             // Replace first ident with a crate name and check if that is valid.
             path[0].ident.name = name;
-            let result = self.r.maybe_resolve_path(&path, None, parent_scope);
+            let result = self.maybe_resolve_path(&path, None, parent_scope);
             debug!(
                 "make_external_crate_suggestion: name={:?} path={:?} result={:?}",
                 name, path, result
@@ -2050,8 +2044,8 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
     /// ```
     pub(crate) fn check_for_module_export_macro(
         &mut self,
-        import: &'b Import<'b>,
-        module: ModuleOrUniformRoot<'b>,
+        import: &'a Import<'a>,
+        module: ModuleOrUniformRoot<'a>,
         ident: Ident,
     ) -> Option<(Option<Suggestion>, Option<String>)> {
         let ModuleOrUniformRoot::Module(mut crate_module) = module else {
@@ -2068,8 +2062,8 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
             return None;
         }
 
-        let resolutions = self.r.resolutions(crate_module).borrow();
-        let resolution = resolutions.get(&self.r.new_key(ident, MacroNS))?;
+        let resolutions = self.resolutions(crate_module).borrow();
+        let resolution = resolutions.get(&self.new_key(ident, MacroNS))?;
         let binding = resolution.borrow().binding()?;
         if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() {
             let module_name = crate_module.kind.name().unwrap();
@@ -2090,7 +2084,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
                 //   ie. `use a::b::{c, d, e};`
                 //                      ^^^
                 let (found_closing_brace, binding_span) = find_span_of_binding_until_next_binding(
-                    self.r.tcx.sess,
+                    self.tcx.sess,
                     import.span,
                     import.use_span,
                 );
@@ -2109,7 +2103,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
                     //   ie. `use a::b::{c, d};`
                     //                    ^^^
                     if let Some(previous_span) =
-                        extend_span_to_previous_binding(self.r.tcx.sess, binding_span)
+                        extend_span_to_previous_binding(self.tcx.sess, binding_span)
                     {
                         debug!("check_for_module_export_macro: previous_span={:?}", previous_span);
                         removal_span = removal_span.with_lo(previous_span.lo());
@@ -2127,7 +2121,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
                 //   or  `use a::{b, c, d}};`
                 //               ^^^^^^^^^^^
                 let (has_nested, after_crate_name) = find_span_immediately_after_crate_name(
-                    self.r.tcx.sess,
+                    self.tcx.sess,
                     module_name,
                     import.use_span,
                 );
@@ -2136,7 +2130,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
                     has_nested, after_crate_name
                 );
 
-                let source_map = self.r.tcx.sess.source_map();
+                let source_map = self.tcx.sess.source_map();
 
                 // Make sure this is actually crate-relative.
                 let is_definitely_crate = import
@@ -2358,8 +2352,7 @@ pub(crate) enum DiagnosticMode {
 }
 
 pub(crate) fn import_candidates(
-    session: &Session,
-    source_span: &IndexVec<LocalDefId, Span>,
+    tcx: TyCtxt<'_>,
     err: &mut Diagnostic,
     // This is `None` if all placement locations are inside expansions
     use_placement_span: Option<Span>,
@@ -2368,8 +2361,7 @@ pub(crate) fn import_candidates(
     append: &str,
 ) {
     show_candidates(
-        session,
-        source_span,
+        tcx,
         err,
         use_placement_span,
         candidates,
@@ -2385,8 +2377,7 @@ pub(crate) fn import_candidates(
 /// entities with that name in all crates. This method allows outputting the
 /// results of this search in a programmer-friendly way
 fn show_candidates(
-    session: &Session,
-    source_span: &IndexVec<LocalDefId, Span>,
+    tcx: TyCtxt<'_>,
     err: &mut Diagnostic,
     // This is `None` if all placement locations are inside expansions
     use_placement_span: Option<Span>,
@@ -2511,8 +2502,8 @@ fn show_candidates(
             );
 
             if let Some(local_def_id) = def_id.and_then(|did| did.as_local()) {
-                let span = source_span[local_def_id];
-                let span = session.source_map().guess_head_span(span);
+                let span = tcx.source_span(local_def_id);
+                let span = tcx.sess.source_map().guess_head_span(span);
                 let mut multi_span = MultiSpan::from_span(span);
                 multi_span.push_span_label(span, "not accessible");
                 err.span_note(multi_span, &msg);
@@ -2542,8 +2533,8 @@ fn show_candidates(
             let mut spans = Vec::new();
             for (name, _, def_id, _) in &inaccessible_path_strings {
                 if let Some(local_def_id) = def_id.and_then(|did| did.as_local()) {
-                    let span = source_span[local_def_id];
-                    let span = session.source_map().guess_head_span(span);
+                    let span = tcx.source_span(local_def_id);
+                    let span = tcx.sess.source_map().guess_head_span(span);
                     spans.push((name, span));
                 } else {
                     if !has_colon {
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index 2c442774667..867363f4246 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -38,7 +38,7 @@ pub(crate) struct NameAlreadyUsedInParameterList {
     #[primary_span]
     #[label]
     pub(crate) span: Span,
-    #[label(first_use_of_name)]
+    #[label(resolve_first_use_of_name)]
     pub(crate) first_use_span: Span,
     pub(crate) name: Symbol,
 }
@@ -121,7 +121,7 @@ pub(crate) struct VariableBoundWithDifferentMode {
     #[primary_span]
     #[label]
     pub(crate) span: Span,
-    #[label(first_binding_span)]
+    #[label(resolve_first_binding_span)]
     pub(crate) first_binding_span: Span,
     pub(crate) variable_name: Symbol,
 }
@@ -293,7 +293,7 @@ pub(crate) struct BindingShadowsSomethingUnacceptable<'a> {
     pub(crate) article: &'a str,
     #[subdiagnostic]
     pub(crate) sub_suggestion: Option<BindingShadowsSomethingUnacceptableSuggestion>,
-    #[label(label_shadowed_binding)]
+    #[label(resolve_label_shadowed_binding)]
     pub(crate) shadowed_binding_span: Span,
     pub(crate) participle: &'a str,
     pub(crate) name: Symbol,
@@ -369,7 +369,7 @@ pub(crate) struct UnreachableLabel {
     #[label]
     pub(crate) span: Span,
     pub(crate) name: Symbol,
-    #[label(label_definition_span)]
+    #[label(resolve_label_definition_span)]
     pub(crate) definition_span: Span,
     #[subdiagnostic]
     pub(crate) sub_suggestion: Option<UnreachableLabelSubSuggestion>,
@@ -413,7 +413,7 @@ pub(crate) struct TraitImplMismatch {
     pub(crate) span: Span,
     pub(crate) name: Symbol,
     pub(crate) kind: String,
-    #[label(label_trait_item)]
+    #[label(resolve_label_trait_item)]
     pub(crate) trait_item_span: Span,
     pub(crate) trait_path: String,
     pub(crate) code: String,
@@ -434,9 +434,9 @@ pub(crate) struct TraitImplDuplicate {
     #[primary_span]
     #[label]
     pub(crate) span: Span,
-    #[label(old_span_label)]
+    #[label(resolve_old_span_label)]
     pub(crate) old_span: Span,
-    #[label(trait_item_span)]
+    #[label(resolve_trait_item_span)]
     pub(crate) trait_item_span: Span,
     pub(crate) name: Symbol,
 }
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 449d8094bd6..4dab0836d28 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -210,6 +210,17 @@ impl<'a> NameResolution<'a> {
     }
 }
 
+/// An error that may be transformed into a diagnostic later. Used to combine multiple unresolved
+/// import errors within the same use tree into a single diagnostic.
+#[derive(Debug, Clone)]
+struct UnresolvedImportError {
+    span: Span,
+    label: Option<String>,
+    note: Option<String>,
+    suggestion: Option<Suggestion>,
+    candidates: Option<Vec<ImportSuggestion>>,
+}
+
 // Reexports of the form `pub use foo as bar;` where `foo` is `extern crate foo;`
 // are permitted for backward-compatibility under a deprecation lint.
 fn pub_use_of_private_extern_crate_hack(import: &Import<'_>, binding: &NameBinding<'_>) -> bool {
@@ -392,24 +403,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             }
         }
     }
-}
-
-/// An error that may be transformed into a diagnostic later. Used to combine multiple unresolved
-/// import errors within the same use tree into a single diagnostic.
-#[derive(Debug, Clone)]
-struct UnresolvedImportError {
-    span: Span,
-    label: Option<String>,
-    note: Option<String>,
-    suggestion: Option<Suggestion>,
-    candidates: Option<Vec<ImportSuggestion>>,
-}
-
-pub(crate) struct ImportResolver<'a, 'b, 'tcx> {
-    pub r: &'a mut Resolver<'b, 'tcx>,
-}
 
-impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
     // Import resolution
     //
     // This is a fixed-point algorithm. We resolve imports until our efforts
@@ -421,28 +415,28 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
     /// Resolves all imports for the crate. This method performs the fixed-
     /// point iteration.
     pub(crate) fn resolve_imports(&mut self) {
-        let mut prev_num_indeterminates = self.r.indeterminate_imports.len() + 1;
-        while self.r.indeterminate_imports.len() < prev_num_indeterminates {
-            prev_num_indeterminates = self.r.indeterminate_imports.len();
-            for import in mem::take(&mut self.r.indeterminate_imports) {
+        let mut prev_num_indeterminates = self.indeterminate_imports.len() + 1;
+        while self.indeterminate_imports.len() < prev_num_indeterminates {
+            prev_num_indeterminates = self.indeterminate_imports.len();
+            for import in mem::take(&mut self.indeterminate_imports) {
                 match self.resolve_import(&import) {
-                    true => self.r.determined_imports.push(import),
-                    false => self.r.indeterminate_imports.push(import),
+                    true => self.determined_imports.push(import),
+                    false => self.indeterminate_imports.push(import),
                 }
             }
         }
     }
 
     pub(crate) fn finalize_imports(&mut self) {
-        for module in self.r.arenas.local_modules().iter() {
+        for module in self.arenas.local_modules().iter() {
             self.finalize_resolutions_in(module);
         }
 
         let mut seen_spans = FxHashSet::default();
         let mut errors = vec![];
         let mut prev_root_id: NodeId = NodeId::from_u32(0);
-        let determined_imports = mem::take(&mut self.r.determined_imports);
-        let indeterminate_imports = mem::take(&mut self.r.indeterminate_imports);
+        let determined_imports = mem::take(&mut self.determined_imports);
+        let indeterminate_imports = mem::take(&mut self.indeterminate_imports);
 
         for (is_indeterminate, import) in determined_imports
             .into_iter()
@@ -453,7 +447,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
 
             // If this import is unresolved then create a dummy import
             // resolution for it so that later resolve stages won't complain.
-            self.r.import_dummy_binding(import);
+            self.import_dummy_binding(import);
 
             if let Some(err) = unresolved_import_error {
                 if let ImportKind::Single { source, ref source_bindings, .. } = import.kind {
@@ -526,7 +520,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
             .collect::<Vec<_>>();
         let msg = format!("unresolved import{} {}", pluralize!(paths.len()), paths.join(", "),);
 
-        let mut diag = struct_span_err!(self.r.tcx.sess, span, E0432, "{}", &msg);
+        let mut diag = struct_span_err!(self.tcx.sess, span, E0432, "{}", &msg);
 
         if let Some((_, UnresolvedImportError { note: Some(note), .. })) = errors.iter().last() {
             diag.note(note);
@@ -548,8 +542,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
             if let Some(candidates) = &err.candidates {
                 match &import.kind {
                     ImportKind::Single { nested: false, source, target, .. } => import_candidates(
-                        self.r.tcx.sess,
-                        &self.r.tcx.untracked().source_span.read(),
+                        self.tcx,
                         &mut diag,
                         Some(err.span),
                         &candidates,
@@ -561,8 +554,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
                     ),
                     ImportKind::Single { nested: true, source, target, .. } => {
                         import_candidates(
-                            self.r.tcx.sess,
-                            &self.r.tcx.untracked().source_span.read(),
+                            self.tcx,
                             &mut diag,
                             None,
                             &candidates,
@@ -583,7 +575,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
 
     /// Attempts to resolve the given import, returning true if its resolution is determined.
     /// If successful, the resolved bindings are written into the module.
-    fn resolve_import(&mut self, import: &'b Import<'b>) -> bool {
+    fn resolve_import(&mut self, import: &'a Import<'a>) -> bool {
         debug!(
             "(resolving import for module) resolving import `{}::...` in `{}`",
             Segment::names_to_string(&import.module_path),
@@ -596,8 +588,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
             // For better failure detection, pretend that the import will
             // not define any names while resolving its module path.
             let orig_vis = import.vis.take();
-            let path_res =
-                self.r.maybe_resolve_path(&import.module_path, None, &import.parent_scope);
+            let path_res = self.maybe_resolve_path(&import.module_path, None, &import.parent_scope);
             import.vis.set(orig_vis);
 
             match path_res {
@@ -625,7 +616,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
         };
 
         let mut indeterminate = false;
-        self.r.per_ns(|this, ns| {
+        self.per_ns(|this, ns| {
             if !type_ns_only || ns == TypeNS {
                 if let Err(Undetermined) = source_bindings[ns].get() {
                     // For better failure detection, pretend that the import will
@@ -678,15 +669,15 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
     ///
     /// Optionally returns an unresolved import error. This error is buffered and used to
     /// consolidate multiple unresolved import errors into a single diagnostic.
-    fn finalize_import(&mut self, import: &'b Import<'b>) -> Option<UnresolvedImportError> {
+    fn finalize_import(&mut self, import: &'a Import<'a>) -> Option<UnresolvedImportError> {
         let orig_vis = import.vis.take();
         let ignore_binding = match &import.kind {
             ImportKind::Single { target_bindings, .. } => target_bindings[TypeNS].get(),
             _ => None,
         };
-        let prev_ambiguity_errors_len = self.r.ambiguity_errors.len();
+        let prev_ambiguity_errors_len = self.ambiguity_errors.len();
         let finalize = Finalize::with_root_span(import.root_id, import.span, import.root_span);
-        let path_res = self.r.resolve_path(
+        let path_res = self.resolve_path(
             &import.module_path,
             None,
             &import.parent_scope,
@@ -694,7 +685,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
             ignore_binding,
         );
 
-        let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len;
+        let no_ambiguity = self.ambiguity_errors.len() == prev_ambiguity_errors_len;
         import.vis.set(orig_vis);
         let module = match path_res {
             PathResult::Module(module) => {
@@ -703,10 +694,10 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
                     if !ModuleOrUniformRoot::same_def(module, initial_module) && no_ambiguity {
                         span_bug!(import.span, "inconsistent resolution for an import");
                     }
-                } else if self.r.privacy_errors.is_empty() {
+                } else if self.privacy_errors.is_empty() {
                     let msg = "cannot determine resolution for the import";
                     let msg_note = "import resolution is stuck, try simplifying other imports";
-                    self.r.tcx.sess.struct_span_err(import.span, msg).note(msg_note).emit();
+                    self.tcx.sess.struct_span_err(import.span, msg).note(msg_note).emit();
                 }
 
                 module
@@ -714,8 +705,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
             PathResult::Failed { is_error_from_last_segment: false, span, label, suggestion } => {
                 if no_ambiguity {
                     assert!(import.imported_module.get().is_none());
-                    self.r
-                        .report_error(span, ResolutionError::FailedToResolve { label, suggestion });
+                    self.report_error(span, ResolutionError::FailedToResolve { label, suggestion });
                 }
                 return None;
             }
@@ -777,7 +767,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
                         // 2 segments, so the `resolve_path` above won't trigger it.
                         let mut full_path = import.module_path.clone();
                         full_path.push(Segment::from_ident(Ident::empty()));
-                        self.r.lint_if_path_starts_with_module(Some(finalize), &full_path, None);
+                        self.lint_if_path_starts_with_module(Some(finalize), &full_path, None);
                     }
 
                     if let ModuleOrUniformRoot::Module(module) = module {
@@ -796,10 +786,10 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
                     }
                     if !is_prelude
                     && let Some(max_vis) = max_vis.get()
-                    && !max_vis.is_at_least(import.expect_vis(), &*self.r)
+                    && !max_vis.is_at_least(import.expect_vis(), &*self)
                 {
                     let msg = "glob import doesn't reexport anything because no candidate is public enough";
-                    self.r.lint_buffer.buffer_lint(UNUSED_IMPORTS, id, import.span, msg);
+                    self.lint_buffer.buffer_lint(UNUSED_IMPORTS, id, import.span, msg);
                 }
                     return None;
                 }
@@ -807,7 +797,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
             };
 
         let mut all_ns_err = true;
-        self.r.per_ns(|this, ns| {
+        self.per_ns(|this, ns| {
             if !type_ns_only || ns == TypeNS {
                 let orig_vis = import.vis.take();
                 let binding = this.resolve_ident_in_module(
@@ -876,7 +866,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
 
         if all_ns_err {
             let mut all_ns_failed = true;
-            self.r.per_ns(|this, ns| {
+            self.per_ns(|this, ns| {
                 if !type_ns_only || ns == TypeNS {
                     let binding = this.resolve_ident_in_module(
                         module,
@@ -894,9 +884,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
 
             return if all_ns_failed {
                 let resolutions = match module {
-                    ModuleOrUniformRoot::Module(module) => {
-                        Some(self.r.resolutions(module).borrow())
-                    }
+                    ModuleOrUniformRoot::Module(module) => Some(self.resolutions(module).borrow()),
                     _ => None,
                 };
                 let resolutions = resolutions.as_ref().into_iter().flat_map(|r| r.iter());
@@ -965,7 +953,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
                 };
 
                 let parent_suggestion =
-                    self.r.lookup_import_candidates(ident, TypeNS, &import.parent_scope, |_| true);
+                    self.lookup_import_candidates(ident, TypeNS, &import.parent_scope, |_| true);
 
                 Some(UnresolvedImportError {
                     span: import.span,
@@ -987,7 +975,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
         let mut reexport_error = None;
         let mut any_successful_reexport = false;
         let mut crate_private_reexport = false;
-        self.r.per_ns(|this, ns| {
+        self.per_ns(|this, ns| {
             if let Ok(binding) = source_bindings[ns].get() {
                 if !binding.vis.is_at_least(import.expect_vis(), &*this) {
                     reexport_error = Some((ns, binding));
@@ -1012,7 +1000,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
                                    `pub`",
                     ident
                 );
-                self.r.lint_buffer.buffer_lint(
+                self.lint_buffer.buffer_lint(
                     PUB_USE_OF_PRIVATE_EXTERN_CRATE,
                     import_id,
                     import.span,
@@ -1035,17 +1023,17 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
                         format!("re-export of private `{}`", ident)
                     };
 
-                    struct_span_err!(self.r.tcx.sess, import.span, E0365, "{}", error_msg)
+                    struct_span_err!(self.tcx.sess, import.span, E0365, "{}", error_msg)
                         .span_label(import.span, label_msg)
                         .note(&format!("consider declaring type or module `{}` with `pub`", ident))
                         .emit();
                 } else {
                     let mut err =
-                        struct_span_err!(self.r.tcx.sess, import.span, E0364, "{error_msg}");
+                        struct_span_err!(self.tcx.sess, import.span, E0364, "{error_msg}");
                     match binding.kind {
                         NameBindingKind::Res(Res::Def(DefKind::Macro(_), def_id))
                             // exclude decl_macro
-                            if self.r.get_macro_by_def_id(def_id).macro_rules =>
+                            if self.get_macro_by_def_id(def_id).macro_rules =>
                         {
                             err.span_help(
                                 binding.span,
@@ -1071,7 +1059,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
             // 2 segments, so the `resolve_path` above won't trigger it.
             let mut full_path = import.module_path.clone();
             full_path.push(Segment::from_ident(ident));
-            self.r.per_ns(|this, ns| {
+            self.per_ns(|this, ns| {
                 if let Ok(binding) = source_bindings[ns].get() {
                     this.lint_if_path_starts_with_module(Some(finalize), &full_path, Some(binding));
                 }
@@ -1081,7 +1069,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
         // Record what this import resolves to for later uses in documentation,
         // this may resolve to either a value or a type, but for documentation
         // purposes it's good enough to just favor one over the other.
-        self.r.per_ns(|this, ns| {
+        self.per_ns(|this, ns| {
             if let Ok(binding) = source_bindings[ns].get() {
                 this.import_res_map.entry(import_id).or_default()[ns] = Some(binding.res());
             }
@@ -1096,9 +1084,9 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
     fn check_for_redundant_imports(
         &mut self,
         ident: Ident,
-        import: &'b Import<'b>,
-        source_bindings: &PerNS<Cell<Result<&'b NameBinding<'b>, Determinacy>>>,
-        target_bindings: &PerNS<Cell<Option<&'b NameBinding<'b>>>>,
+        import: &'a Import<'a>,
+        source_bindings: &PerNS<Cell<Result<&'a NameBinding<'a>, Determinacy>>>,
+        target_bindings: &PerNS<Cell<Option<&'a NameBinding<'a>>>>,
         target: Ident,
     ) {
         // This function is only called for single imports.
@@ -1119,7 +1107,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
 
         let mut redundant_span = PerNS { value_ns: None, type_ns: None, macro_ns: None };
 
-        self.r.per_ns(|this, ns| {
+        self.per_ns(|this, ns| {
             if let Ok(binding) = source_bindings[ns].get() {
                 if binding.res() == Res::Err {
                     return;
@@ -1149,7 +1137,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
             let mut redundant_spans: Vec<_> = redundant_span.present_items().collect();
             redundant_spans.sort();
             redundant_spans.dedup();
-            self.r.lint_buffer.buffer_lint_with_diagnostic(
+            self.lint_buffer.buffer_lint_with_diagnostic(
                 UNUSED_IMPORTS,
                 id,
                 import.span,
@@ -1159,22 +1147,22 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
         }
     }
 
-    fn resolve_glob_import(&mut self, import: &'b Import<'b>) {
+    fn resolve_glob_import(&mut self, import: &'a Import<'a>) {
         // This function is only called for glob imports.
         let ImportKind::Glob { id, is_prelude, .. } = import.kind else { unreachable!() };
 
         let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() else {
-            self.r.tcx.sess.span_err(import.span, "cannot glob-import all possible crates");
+            self.tcx.sess.span_err(import.span, "cannot glob-import all possible crates");
             return;
         };
 
         if module.is_trait() {
-            self.r.tcx.sess.span_err(import.span, "items in traits are not importable");
+            self.tcx.sess.span_err(import.span, "items in traits are not importable");
             return;
         } else if ptr::eq(module, import.parent_scope.module) {
             return;
         } else if is_prelude {
-            self.r.prelude = Some(module);
+            self.prelude = Some(module);
             return;
         }
 
@@ -1184,7 +1172,6 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
         // Ensure that `resolutions` isn't borrowed during `try_define`,
         // since it might get updated via a glob cycle.
         let bindings = self
-            .r
             .resolutions(module)
             .borrow()
             .iter()
@@ -1194,30 +1181,30 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
             .collect::<Vec<_>>();
         for (mut key, binding) in bindings {
             let scope = match key.ident.span.reverse_glob_adjust(module.expansion, import.span) {
-                Some(Some(def)) => self.r.expn_def_scope(def),
+                Some(Some(def)) => self.expn_def_scope(def),
                 Some(None) => import.parent_scope.module,
                 None => continue,
             };
-            if self.r.is_accessible_from(binding.vis, scope) {
-                let imported_binding = self.r.import(binding, import);
-                let _ = self.r.try_define(import.parent_scope.module, key, imported_binding);
+            if self.is_accessible_from(binding.vis, scope) {
+                let imported_binding = self.import(binding, import);
+                let _ = self.try_define(import.parent_scope.module, key, imported_binding);
             }
         }
 
         // Record the destination of this import
-        self.r.record_partial_res(id, PartialRes::new(module.res().unwrap()));
+        self.record_partial_res(id, PartialRes::new(module.res().unwrap()));
     }
 
     // Miscellaneous post-processing, including recording re-exports,
     // reporting conflicts, and reporting unresolved imports.
-    fn finalize_resolutions_in(&mut self, module: Module<'b>) {
+    fn finalize_resolutions_in(&mut self, module: Module<'a>) {
         // Since import resolution is finished, globs will not define any more names.
         *module.globs.borrow_mut() = Vec::new();
 
         if let Some(def_id) = module.opt_def_id() {
             let mut reexports = Vec::new();
 
-            module.for_each_child(self.r, |this, ident, _, binding| {
+            module.for_each_child(self, |this, ident, _, binding| {
                 if let Some(res) = this.is_reexport(binding) {
                     reexports.push(ModChild {
                         ident,
@@ -1232,7 +1219,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> {
             if !reexports.is_empty() {
                 // Call to `expect_local` should be fine because current
                 // code is only called for local modules.
-                self.r.reexport_map.insert(def_id.expect_local(), reexports);
+                self.reexport_map.insert(def_id.expect_local(), reexports);
             }
         }
     }
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 66034baaa0b..7a1f14f71f2 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -28,7 +28,9 @@ use rustc_ast::{AngleBracketedArg, Crate, Expr, ExprKind, GenericArg, GenericArg
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_data_structures::intern::Interned;
 use rustc_data_structures::sync::{Lrc, MappedReadGuard};
-use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed};
+use rustc_errors::{
+    Applicability, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, SubdiagnosticMessage,
+};
 use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind};
 use rustc_hir::def::Namespace::{self, *};
 use rustc_hir::def::{self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, PartialRes, PerNS};
@@ -37,6 +39,7 @@ use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::definitions::DefPathData;
 use rustc_hir::TraitCandidate;
 use rustc_index::vec::IndexVec;
+use rustc_macros::fluent_messages;
 use rustc_metadata::creader::{CStore, CrateLoader};
 use rustc_middle::metadata::ModChild;
 use rustc_middle::middle::privacy::EffectiveVisibilities;
@@ -57,7 +60,7 @@ use std::collections::BTreeSet;
 use std::{fmt, ptr};
 
 use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
-use imports::{Import, ImportKind, ImportResolver, NameResolution};
+use imports::{Import, ImportKind, NameResolution};
 use late::{HasGenericParams, PathSource, PatternSource};
 use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
 
@@ -77,6 +80,8 @@ mod late;
 mod macros;
 pub mod rustdoc;
 
+fluent_messages! { "../locales/en-US.ftl" }
+
 enum Weak {
     Yes,
     No,
@@ -1156,7 +1161,7 @@ impl<'tcx> Resolver<'_, 'tcx> {
 
         // A relative span's parent must be an absolute span.
         debug_assert_eq!(span.data_untracked().parent, None);
-        let _id = self.tcx.untracked().source_span.write().push(span);
+        let _id = self.tcx.untracked().source_span.push(span);
         debug_assert_eq!(_id, def_id);
 
         // Some things for which we allocate `LocalDefId`s don't correspond to
@@ -1486,9 +1491,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     /// Entry point to crate resolution.
     pub fn resolve_crate(&mut self, krate: &Crate) {
         self.tcx.sess.time("resolve_crate", || {
-            self.tcx
-                .sess
-                .time("finalize_imports", || ImportResolver { r: self }.finalize_imports());
+            self.tcx.sess.time("finalize_imports", || self.finalize_imports());
             self.tcx.sess.time("compute_effective_visibilities", || {
                 EffectiveVisibilitiesVisitor::compute_effective_visibilities(self, krate)
             });
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 341db774b4d..b38c11e8bb8 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -1,7 +1,6 @@
 //! A bunch of methods and structures more or less related to resolving macros and
 //! interface provided by `Resolver` to macro expander.
 
-use crate::imports::ImportResolver;
 use crate::Namespace::*;
 use crate::{BuiltinMacroState, Determinacy};
 use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet};
@@ -233,7 +232,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
     }
 
     fn resolve_imports(&mut self) {
-        ImportResolver { r: self }.resolve_imports()
+        self.resolve_imports()
     }
 
     fn resolve_macro_invocation(
diff --git a/compiler/rustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml
index db0ef73544f..c0446571905 100644
--- a/compiler/rustc_serialize/Cargo.toml
+++ b/compiler/rustc_serialize/Cargo.toml
@@ -6,7 +6,7 @@ edition = "2021"
 [dependencies]
 indexmap = "1.9.1"
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-thin-vec = "0.2.9"
+thin-vec = "0.2.12"
 
 [dev-dependencies]
 rustc_macros = { path = "../rustc_macros" }
diff --git a/compiler/rustc_error_messages/locales/en-US/session.ftl b/compiler/rustc_session/locales/en-US.ftl
index fe553edab42..fe553edab42 100644
--- a/compiler/rustc_error_messages/locales/en-US/session.ftl
+++ b/compiler/rustc_session/locales/en-US.ftl
diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs
index 97aa930b5ec..868ffdf0f1d 100644
--- a/compiler/rustc_session/src/cstore.rs
+++ b/compiler/rustc_session/src/cstore.rs
@@ -6,10 +6,9 @@ use crate::search_paths::PathKind;
 use crate::utils::NativeLibKind;
 use crate::Session;
 use rustc_ast as ast;
-use rustc_data_structures::sync::{self, MetadataRef, RwLock};
+use rustc_data_structures::sync::{self, AppendOnlyVec, MetadataRef, RwLock};
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, StableCrateId, LOCAL_CRATE};
 use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions};
-use rustc_index::vec::IndexVec;
 use rustc_span::hygiene::{ExpnHash, ExpnId};
 use rustc_span::symbol::Symbol;
 use rustc_span::Span;
@@ -252,10 +251,9 @@ pub trait CrateStore: std::fmt::Debug {
 
 pub type CrateStoreDyn = dyn CrateStore + sync::Sync + sync::Send;
 
-#[derive(Debug)]
 pub struct Untracked {
     pub cstore: RwLock<Box<CrateStoreDyn>>,
     /// Reference span for definitions.
-    pub source_span: RwLock<IndexVec<LocalDefId, Span>>,
+    pub source_span: AppendOnlyVec<LocalDefId, Span>,
     pub definitions: RwLock<Definitions>,
 }
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index 39e871f532c..e1f1a5f6d2e 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -18,6 +18,9 @@ pub mod errors;
 #[macro_use]
 extern crate tracing;
 
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_macros::fluent_messages;
+
 pub mod cgu_reuse_tracker;
 pub mod utils;
 pub use lint::{declare_lint, declare_lint_pass, declare_tool_lint, impl_lint_pass};
@@ -39,6 +42,8 @@ pub mod output;
 
 pub use getopts;
 
+fluent_messages! { "../locales/en-US.ftl" }
+
 /// Requirements for a `StableHashingContext` to be used in this crate.
 /// This is a hack to allow using the `HashStable_Generic` derive macro
 /// instead of implementing everything in `rustc_middle`.
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 0d5818bd39c..4beac931632 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1489,6 +1489,8 @@ options! {
         "keep hygiene data after analysis (default: no)"),
     layout_seed: Option<u64> = (None, parse_opt_number, [TRACKED],
         "seed layout randomization"),
+    link_directives: bool = (true, parse_bool, [TRACKED],
+        "honor #[link] directives in the compiled crate (default: yes)"),
     link_native_libraries: bool = (true, parse_bool, [UNTRACKED],
         "link native libraries in the linker invocation (default: yes)"),
     link_only: bool = (false, parse_bool, [TRACKED],
@@ -1567,8 +1569,6 @@ options! {
         "parse only; do not compile, assemble, or link (default: no)"),
     perf_stats: bool = (false, parse_bool, [UNTRACKED],
         "print some performance-related statistics (default: no)"),
-    pick_stable_methods_before_any_unstable: bool = (true, parse_bool, [TRACKED],
-        "try to pick stable methods first before picking any unstable methods (default: yes)"),
     plt: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "whether to use the PLT when calling into shared libraries;
         only has effect for PIC code on systems with ELF binaries
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index cbdcc5581e5..4e8c3f73e29 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -226,8 +226,8 @@ pub struct ParseSess {
 
 impl ParseSess {
     /// Used for testing.
-    pub fn new(file_path_mapping: FilePathMapping) -> Self {
-        let fallback_bundle = fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
+    pub fn new(locale_resources: Vec<&'static str>, file_path_mapping: FilePathMapping) -> Self {
+        let fallback_bundle = fallback_fluent_bundle(locale_resources, false);
         let sm = Lrc::new(SourceMap::new(file_path_mapping));
         let handler = Handler::with_tty_emitter(
             ColorConfig::Auto,
@@ -265,7 +265,7 @@ impl ParseSess {
     }
 
     pub fn with_silent_emitter(fatal_note: Option<String>) -> Self {
-        let fallback_bundle = fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
+        let fallback_bundle = fallback_fluent_bundle(Vec::new(), false);
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let fatal_handler =
             Handler::with_tty_emitter(ColorConfig::Auto, false, None, None, None, fallback_bundle);
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 3dc09854b3c..446ba63ed1c 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -1341,6 +1341,7 @@ pub fn build_session(
     io: CompilerIO,
     bundle: Option<Lrc<rustc_errors::FluentBundle>>,
     registry: rustc_errors::registry::Registry,
+    fluent_resources: Vec<&'static str>,
     driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
     file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
     target_override: Option<Target>,
@@ -1385,7 +1386,7 @@ pub fn build_session(
     ));
 
     let fallback_bundle = fallback_fluent_bundle(
-        rustc_errors::DEFAULT_LOCALE_RESOURCES,
+        fluent_resources,
         sopts.unstable_opts.translate_directionality_markers,
     );
     let emitter = default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle);
@@ -1630,7 +1631,10 @@ pub enum IncrCompSession {
 }
 
 fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler {
-    let fallback_bundle = fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
+    // FIXME(#100717): early errors aren't translated at the moment, so this is fine, but it will
+    // need to reference every crate that might emit an early error for translation to work.
+    let fallback_bundle =
+        fallback_fluent_bundle(vec![rustc_errors::DEFAULT_LOCALE_RESOURCE], false);
     let emitter: Box<dyn Emitter + sync::Send> = match output {
         config::ErrorOutputType::HumanReadable(kind) => {
             let (short, color_config) = kind.unzip();
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index e112100aa5f..873cd33f6a4 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -2149,3 +2149,17 @@ where
         Hash::hash(&len, hasher);
     }
 }
+
+/// Useful type to use with `Result<>` indicate that an error has already
+/// been reported to the user, so no need to continue checking.
+#[derive(Clone, Copy, Debug, Encodable, Decodable, Hash, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(HashStable_Generic)]
+pub struct ErrorGuaranteed(());
+
+impl ErrorGuaranteed {
+    /// To be used only if you really know what you are doing... ideally, we would find a way to
+    /// eliminate all calls to this method.
+    pub fn unchecked_claim_error_was_emitted() -> Self {
+        ErrorGuaranteed(())
+    }
+}
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 37d2aea42ad..fb579e4ff77 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -740,6 +740,7 @@ symbols! {
         frem_fast,
         from,
         from_desugaring,
+        from_fn,
         from_iter,
         from_method,
         from_output,
diff --git a/compiler/rustc_error_messages/locales/en-US/symbol_mangling.ftl b/compiler/rustc_symbol_mangling/locales/en-US.ftl
index b7d48280f46..b7d48280f46 100644
--- a/compiler/rustc_error_messages/locales/en-US/symbol_mangling.ftl
+++ b/compiler/rustc_symbol_mangling/locales/en-US.ftl
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index 744e8a4320e..2368468c891 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -3,7 +3,7 @@ use rustc_hir::def_id::CrateNum;
 use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
 use rustc_middle::ty::print::{PrettyPrinter, Print, Printer};
 use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
-use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeVisitableExt};
 use rustc_middle::util::common::record_time;
 
 use std::fmt::{self, Write};
diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs
index d81722e59a6..d9ce7373483 100644
--- a/compiler/rustc_symbol_mangling/src/lib.rs
+++ b/compiler/rustc_symbol_mangling/src/lib.rs
@@ -100,8 +100,10 @@ extern crate rustc_middle;
 #[macro_use]
 extern crate tracing;
 
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
+use rustc_macros::fluent_messages;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
 use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
@@ -117,6 +119,8 @@ pub mod errors;
 pub mod test;
 pub mod typeid;
 
+fluent_messages! { "../locales/en-US.ftl" }
+
 /// This function computes the symbol name for the given `instance` and the
 /// given instantiating crate. That is, if you know that instance X is
 /// instantiated in crate Y, this is the symbol name this instance would have.
diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
index 59a2227cd36..1a679f32ca5 100644
--- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
+++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
@@ -396,6 +396,7 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String {
             hir::definitions::DefPathData::CrateRoot
             | hir::definitions::DefPathData::Use
             | hir::definitions::DefPathData::GlobalAsm
+            | hir::definitions::DefPathData::ImplTraitAssocTy
             | hir::definitions::DefPathData::MacroNs(..)
             | hir::definitions::DefPathData::LifetimeNs(..) => {
                 bug!("encode_ty_name: unexpected `{:?}`", disambiguated_data.data);
@@ -674,7 +675,7 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
         _ if ty.is_unit() => {}
 
         ty::Tuple(tys) => {
-            ty = tcx.mk_tup(tys.iter().map(|ty| transform_ty(tcx, ty, options)));
+            ty = tcx.mk_tup_from_iter(tys.iter().map(|ty| transform_ty(tcx, ty, options)));
         }
 
         ty::Array(ty0, len) => {
@@ -824,7 +825,7 @@ fn transform_substs<'tcx>(
             subst
         }
     });
-    tcx.mk_substs(substs)
+    tcx.mk_substs_from_iter(substs)
 }
 
 /// Returns a type metadata identifier for the specified FnAbi using the Itanium C++ ABI with vendor
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index c58b6a24ab5..2f20d42139c 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -8,7 +8,8 @@ use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
 use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::print::{Print, Printer};
 use rustc_middle::ty::{
-    self, EarlyBinder, FloatTy, Instance, IntTy, Ty, TyCtxt, TypeVisitable, UintTy,
+    self, EarlyBinder, FloatTy, Instance, IntTy, Ty, TyCtxt, TypeVisitable, TypeVisitableExt,
+    UintTy,
 };
 use rustc_middle::ty::{GenericArg, GenericArgKind};
 use rustc_span::symbol::kw;
@@ -204,7 +205,7 @@ impl<'tcx> SymbolMangler<'tcx> {
         print_value: impl FnOnce(&'a mut Self, &T) -> Result<&'a mut Self, !>,
     ) -> Result<&'a mut Self, !>
     where
-        T: TypeVisitable<'tcx>,
+        T: TypeVisitable<TyCtxt<'tcx>>,
     {
         // FIXME(non-lifetime-binders): What to do here?
         let regions = if value.has_late_bound_regions() {
@@ -791,6 +792,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
             | DefPathData::Use
             | DefPathData::GlobalAsm
             | DefPathData::Impl
+            | DefPathData::ImplTraitAssocTy
             | DefPathData::MacroNs(_)
             | DefPathData::LifetimeNs(_) => {
                 bug!("symbol_names: unexpected DefPathData: {:?}", disambiguated_data.data)
diff --git a/compiler/rustc_error_messages/locales/en-US/trait_selection.ftl b/compiler/rustc_trait_selection/locales/en-US.ftl
index 14eb4a5502d..14eb4a5502d 100644
--- a/compiler/rustc_error_messages/locales/en-US/trait_selection.ftl
+++ b/compiler/rustc_trait_selection/locales/en-US.ftl
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index 4405537c645..df7c4df1868 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -1,4 +1,5 @@
-use rustc_errors::{fluent, ErrorGuaranteed, Handler, IntoDiagnostic};
+use crate::fluent_generated as fluent;
+use rustc_errors::{ErrorGuaranteed, Handler, IntoDiagnostic};
 use rustc_macros::Diagnostic;
 use rustc_middle::ty::{self, PolyTraitRef, Ty};
 use rustc_span::{Span, Symbol};
@@ -69,19 +70,19 @@ impl IntoDiagnostic<'_> for NegativePositiveConflict<'_> {
         diag.code(rustc_errors::error_code!(E0751));
         match self.negative_impl_span {
             Ok(span) => {
-                diag.span_label(span, fluent::negative_implementation_here);
+                diag.span_label(span, fluent::trait_selection_negative_implementation_here);
             }
             Err(cname) => {
-                diag.note(fluent::negative_implementation_in_crate);
+                diag.note(fluent::trait_selection_negative_implementation_in_crate);
                 diag.set_arg("negative_impl_cname", cname.to_string());
             }
         }
         match self.positive_impl_span {
             Ok(span) => {
-                diag.span_label(span, fluent::positive_implementation_here);
+                diag.span_label(span, fluent::trait_selection_positive_implementation_here);
             }
             Err(cname) => {
-                diag.note(fluent::positive_implementation_in_crate);
+                diag.note(fluent::trait_selection_positive_implementation_in_crate);
                 diag.set_arg("positive_impl_cname", cname.to_string());
             }
         }
diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs
index c0bfe152a1e..9b47c7299bb 100644
--- a/compiler/rustc_trait_selection/src/infer.rs
+++ b/compiler/rustc_trait_selection/src/infer.rs
@@ -6,7 +6,7 @@ use rustc_hir::lang_items::LangItem;
 use rustc_middle::arena::ArenaAllocatable;
 use rustc_middle::infer::canonical::{Canonical, CanonicalQueryResponse, QueryResponse};
 use rustc_middle::traits::query::Fallible;
-use rustc_middle::ty::{self, Ty, TypeFoldable};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
 use rustc_middle::ty::{GenericArg, ToPredicate};
 use rustc_span::{Span, DUMMY_SP};
 
@@ -42,7 +42,7 @@ pub trait InferCtxtExt<'tcx> {
     fn type_implements_trait(
         &self,
         trait_def_id: DefId,
-        params: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
+        params: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
         param_env: ty::ParamEnv<'tcx>,
     ) -> traits::EvaluationResult;
 }
@@ -82,7 +82,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
     fn type_implements_trait(
         &self,
         trait_def_id: DefId,
-        params: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
+        params: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
         param_env: ty::ParamEnv<'tcx>,
     ) -> traits::EvaluationResult {
         let trait_ref = self.tcx.mk_trait_ref(trait_def_id, params);
@@ -104,8 +104,8 @@ pub trait InferCtxtBuilderExt<'tcx> {
         operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Fallible<R>,
     ) -> Fallible<CanonicalQueryResponse<'tcx, R>>
     where
-        K: TypeFoldable<'tcx>,
-        R: Debug + TypeFoldable<'tcx>,
+        K: TypeFoldable<TyCtxt<'tcx>>,
+        R: Debug + TypeFoldable<TyCtxt<'tcx>>,
         Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>;
 }
 
@@ -125,15 +125,15 @@ impl<'tcx> InferCtxtBuilderExt<'tcx> for InferCtxtBuilder<'tcx> {
     /// In part because we would need a `for<'tcx>` sort of
     /// bound for the closure and in part because it is convenient to
     /// have `'tcx` be free on this function so that we can talk about
-    /// `K: TypeFoldable<'tcx>`.)
+    /// `K: TypeFoldable<TyCtxt<'tcx>>`.)
     fn enter_canonical_trait_query<K, R>(
         &mut self,
         canonical_key: &Canonical<'tcx, K>,
         operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Fallible<R>,
     ) -> Fallible<CanonicalQueryResponse<'tcx, R>>
     where
-        K: TypeFoldable<'tcx>,
-        R: Debug + TypeFoldable<'tcx>,
+        K: TypeFoldable<TyCtxt<'tcx>>,
+        R: Debug + TypeFoldable<TyCtxt<'tcx>>,
         Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>,
     {
         let (infcx, key, canonical_inference_vars) =
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index 6fa09410363..548b42cef43 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -36,7 +36,12 @@ extern crate rustc_middle;
 #[macro_use]
 extern crate smallvec;
 
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_macros::fluent_messages;
+
 pub mod errors;
 pub mod infer;
 pub mod solve;
 pub mod traits;
+
+fluent_messages! { "../locales/en-US.ftl" }
diff --git a/compiler/rustc_trait_selection/src/solve/assembly.rs b/compiler/rustc_trait_selection/src/solve/assembly.rs
index 841169ac78d..dec9f8016b0 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly.rs
@@ -1,6 +1,5 @@
 //! Code shared by trait and projection goals for candidate assembly.
 
-use super::infcx_ext::InferCtxtExt;
 #[cfg(doc)]
 use super::trait_goals::structural_traits::*;
 use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, MaybeCause, QueryResult};
@@ -83,7 +82,7 @@ pub(super) enum CandidateSource {
 }
 
 /// Methods used to assemble candidates for either trait or projection goals.
-pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy + Eq {
+pub(super) trait GoalKind<'tcx>: TypeFoldable<TyCtxt<'tcx>> + Copy + Eq {
     fn self_ty(self) -> Ty<'tcx>;
 
     fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self;
@@ -100,6 +99,15 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy + Eq {
         requirements: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
     ) -> QueryResult<'tcx>;
 
+    // Consider a clause specifically for a `dyn Trait` self type. This requires
+    // additionally checking all of the supertraits and object bounds to hold,
+    // since they're not implied by the well-formedness of the object type.
+    fn consider_object_bound_candidate(
+        ecx: &mut EvalCtxt<'_, 'tcx>,
+        goal: Goal<'tcx, Self>,
+        assumption: ty::Predicate<'tcx>,
+    ) -> QueryResult<'tcx>;
+
     fn consider_impl_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
@@ -206,7 +214,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         &mut self,
         goal: Goal<'tcx, G>,
     ) -> Vec<Candidate<'tcx>> {
-        debug_assert_eq!(goal, self.infcx.resolve_vars_if_possible(goal));
+        debug_assert_eq!(goal, self.resolve_vars_if_possible(goal));
 
         // HACK: `_: Trait` is ambiguous, because it may be satisfied via a builtin rule,
         // object bound, alias bound, etc. We are unable to determine this until we can at
@@ -250,8 +258,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         let &ty::Alias(ty::Projection, projection_ty) = goal.predicate.self_ty().kind() else {
             return
         };
-        self.infcx.probe(|_| {
-            let normalized_ty = self.infcx.next_ty_infer();
+        self.probe(|this| {
+            let normalized_ty = this.next_ty_infer();
             let normalizes_to_goal = goal.with(
                 tcx,
                 ty::Binder::dummy(ty::ProjectionPredicate {
@@ -259,16 +267,16 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                     term: normalized_ty.into(),
                 }),
             );
-            let normalization_certainty = match self.evaluate_goal(normalizes_to_goal) {
+            let normalization_certainty = match this.evaluate_goal(normalizes_to_goal) {
                 Ok((_, certainty)) => certainty,
                 Err(NoSolution) => return,
             };
-            let normalized_ty = self.infcx.resolve_vars_if_possible(normalized_ty);
+            let normalized_ty = this.resolve_vars_if_possible(normalized_ty);
 
             // NOTE: Alternatively we could call `evaluate_goal` here and only have a `Normalized` candidate.
             // This doesn't work as long as we use `CandidateSource` in winnowing.
             let goal = goal.with(tcx, goal.predicate.with_self_ty(tcx, normalized_ty));
-            let normalized_candidates = self.assemble_and_evaluate_candidates(goal);
+            let normalized_candidates = this.assemble_and_evaluate_candidates(goal);
             for mut normalized_candidate in normalized_candidates {
                 normalized_candidate.result =
                     normalized_candidate.result.unchecked_map(|mut response| {
@@ -456,7 +464,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         for assumption in
             elaborate_predicates(tcx, bounds.iter().map(|bound| bound.with_self_ty(tcx, self_ty)))
         {
-            match G::consider_implied_clause(self, goal, assumption.predicate, []) {
+            match G::consider_object_bound_candidate(self, goal, assumption.predicate) {
                 Ok(result) => {
                     candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
                 }
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
new file mode 100644
index 00000000000..c8097e81953
--- /dev/null
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
@@ -0,0 +1,175 @@
+use rustc_hir::def_id::DefId;
+use rustc_infer::infer::at::ToTrace;
+use rustc_infer::infer::canonical::CanonicalVarValues;
+use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use rustc_infer::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
+use rustc_infer::traits::query::NoSolution;
+use rustc_infer::traits::ObligationCause;
+use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
+use rustc_middle::ty::{
+    self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
+    TypeVisitor,
+};
+use rustc_span::DUMMY_SP;
+use std::ops::ControlFlow;
+
+use super::search_graph::SearchGraph;
+use super::Goal;
+
+pub struct EvalCtxt<'a, 'tcx> {
+    // FIXME: should be private.
+    pub(super) infcx: &'a InferCtxt<'tcx>,
+
+    pub(super) var_values: CanonicalVarValues<'tcx>,
+
+    pub(super) search_graph: &'a mut SearchGraph<'tcx>,
+
+    /// This field is used by a debug assertion in [`EvalCtxt::evaluate_goal`],
+    /// see the comment in that method for more details.
+    pub in_projection_eq_hack: bool,
+}
+
+impl<'tcx> EvalCtxt<'_, 'tcx> {
+    pub(super) fn probe<T>(&mut self, f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> T) -> T {
+        self.infcx.probe(|_| f(self))
+    }
+
+    pub(super) fn tcx(&self) -> TyCtxt<'tcx> {
+        self.infcx.tcx
+    }
+
+    pub(super) fn next_ty_infer(&self) -> Ty<'tcx> {
+        self.infcx.next_ty_var(TypeVariableOrigin {
+            kind: TypeVariableOriginKind::MiscVariable,
+            span: DUMMY_SP,
+        })
+    }
+
+    pub(super) fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx> {
+        self.infcx.next_const_var(
+            ty,
+            ConstVariableOrigin { kind: ConstVariableOriginKind::MiscVariable, span: DUMMY_SP },
+        )
+    }
+
+    /// Is the projection predicate is of the form `exists<T> <Ty as Trait>::Assoc = T`.
+    ///
+    /// This is the case if the `term` is an inference variable in the innermost universe
+    /// and does not occur in any other part of the predicate.
+    pub(super) fn term_is_fully_unconstrained(
+        &self,
+        goal: Goal<'tcx, ty::ProjectionPredicate<'tcx>>,
+    ) -> bool {
+        let term_is_infer = match goal.predicate.term.unpack() {
+            ty::TermKind::Ty(ty) => {
+                if let &ty::Infer(ty::TyVar(vid)) = ty.kind() {
+                    match self.infcx.probe_ty_var(vid) {
+                        Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
+                        Err(universe) => universe == self.universe(),
+                    }
+                } else {
+                    false
+                }
+            }
+            ty::TermKind::Const(ct) => {
+                if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() {
+                    match self.infcx.probe_const_var(vid) {
+                        Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
+                        Err(universe) => universe == self.universe(),
+                    }
+                } else {
+                    false
+                }
+            }
+        };
+
+        // Guard against `<T as Trait<?0>>::Assoc = ?0>`.
+        struct ContainsTerm<'tcx> {
+            term: ty::Term<'tcx>,
+        }
+        impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTerm<'tcx> {
+            type BreakTy = ();
+            fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
+                if t.needs_infer() {
+                    if ty::Term::from(t) == self.term {
+                        ControlFlow::Break(())
+                    } else {
+                        t.super_visit_with(self)
+                    }
+                } else {
+                    ControlFlow::Continue(())
+                }
+            }
+
+            fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
+                if c.needs_infer() {
+                    if ty::Term::from(c) == self.term {
+                        ControlFlow::Break(())
+                    } else {
+                        c.super_visit_with(self)
+                    }
+                } else {
+                    ControlFlow::Continue(())
+                }
+            }
+        }
+
+        let mut visitor = ContainsTerm { term: goal.predicate.term };
+
+        term_is_infer
+            && goal.predicate.projection_ty.visit_with(&mut visitor).is_continue()
+            && goal.param_env.visit_with(&mut visitor).is_continue()
+    }
+
+    #[instrument(level = "debug", skip(self, param_env), ret)]
+    pub(super) fn eq<T: ToTrace<'tcx>>(
+        &self,
+        param_env: ty::ParamEnv<'tcx>,
+        lhs: T,
+        rhs: T,
+    ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
+        self.infcx
+            .at(&ObligationCause::dummy(), param_env)
+            .eq(lhs, rhs)
+            .map(|InferOk { value: (), obligations }| {
+                obligations.into_iter().map(|o| o.into()).collect()
+            })
+            .map_err(|e| {
+                debug!(?e, "failed to equate");
+                NoSolution
+            })
+    }
+
+    pub(super) fn instantiate_binder_with_infer<T: TypeFoldable<TyCtxt<'tcx>> + Copy>(
+        &self,
+        value: ty::Binder<'tcx, T>,
+    ) -> T {
+        self.infcx.instantiate_binder_with_fresh_vars(
+            DUMMY_SP,
+            LateBoundRegionConversionTime::HigherRankedType,
+            value,
+        )
+    }
+
+    pub(super) fn instantiate_binder_with_placeholders<T: TypeFoldable<TyCtxt<'tcx>> + Copy>(
+        &self,
+        value: ty::Binder<'tcx, T>,
+    ) -> T {
+        self.infcx.instantiate_binder_with_placeholders(value)
+    }
+
+    pub(super) fn resolve_vars_if_possible<T>(&self, value: T) -> T
+    where
+        T: TypeFoldable<TyCtxt<'tcx>>,
+    {
+        self.infcx.resolve_vars_if_possible(value)
+    }
+
+    pub(super) fn fresh_substs_for_item(&self, def_id: DefId) -> ty::SubstsRef<'tcx> {
+        self.infcx.fresh_substs_for_item(DUMMY_SP, def_id)
+    }
+
+    pub(super) fn universe(&self) -> ty::UniverseIndex {
+        self.infcx.universe()
+    }
+}
diff --git a/compiler/rustc_trait_selection/src/solve/infcx_ext.rs b/compiler/rustc_trait_selection/src/solve/infcx_ext.rs
deleted file mode 100644
index 36f987c9f9c..00000000000
--- a/compiler/rustc_trait_selection/src/solve/infcx_ext.rs
+++ /dev/null
@@ -1,78 +0,0 @@
-use rustc_infer::infer::at::ToTrace;
-use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
-use rustc_infer::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
-use rustc_infer::traits::query::NoSolution;
-use rustc_infer::traits::ObligationCause;
-use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
-use rustc_middle::ty::{self, Ty, TypeFoldable};
-use rustc_span::DUMMY_SP;
-
-use super::Goal;
-
-/// Methods used inside of the canonical queries of the solver.
-///
-/// Most notably these do not care about diagnostics information.
-/// If you find this while looking for methods to use outside of the
-/// solver, you may look at the implementation of these method for
-/// help.
-pub(super) trait InferCtxtExt<'tcx> {
-    fn next_ty_infer(&self) -> Ty<'tcx>;
-    fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx>;
-
-    fn eq<T: ToTrace<'tcx>>(
-        &self,
-        param_env: ty::ParamEnv<'tcx>,
-        lhs: T,
-        rhs: T,
-    ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution>;
-
-    fn instantiate_binder_with_infer<T: TypeFoldable<'tcx> + Copy>(
-        &self,
-        value: ty::Binder<'tcx, T>,
-    ) -> T;
-}
-
-impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
-    fn next_ty_infer(&self) -> Ty<'tcx> {
-        self.next_ty_var(TypeVariableOrigin {
-            kind: TypeVariableOriginKind::MiscVariable,
-            span: DUMMY_SP,
-        })
-    }
-    fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx> {
-        self.next_const_var(
-            ty,
-            ConstVariableOrigin { kind: ConstVariableOriginKind::MiscVariable, span: DUMMY_SP },
-        )
-    }
-
-    #[instrument(level = "debug", skip(self, param_env), ret)]
-    fn eq<T: ToTrace<'tcx>>(
-        &self,
-        param_env: ty::ParamEnv<'tcx>,
-        lhs: T,
-        rhs: T,
-    ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
-        self.at(&ObligationCause::dummy(), param_env)
-            .define_opaque_types(false)
-            .eq(lhs, rhs)
-            .map(|InferOk { value: (), obligations }| {
-                obligations.into_iter().map(|o| o.into()).collect()
-            })
-            .map_err(|e| {
-                debug!(?e, "failed to equate");
-                NoSolution
-            })
-    }
-
-    fn instantiate_binder_with_infer<T: TypeFoldable<'tcx> + Copy>(
-        &self,
-        value: ty::Binder<'tcx, T>,
-    ) -> T {
-        self.instantiate_binder_with_fresh_vars(
-            DUMMY_SP,
-            LateBoundRegionConversionTime::HigherRankedType,
-            value,
-        )
-    }
-}
diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs
index 6890811fd04..71f536dd3cb 100644
--- a/compiler/rustc_trait_selection/src/solve/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/mod.rs
@@ -35,16 +35,15 @@ use crate::solve::search_graph::OverflowHandler;
 use crate::traits::ObligationCause;
 
 mod assembly;
+mod eval_ctxt;
 mod fulfill;
-mod infcx_ext;
 mod project_goals;
 mod search_graph;
 mod trait_goals;
 
+pub use eval_ctxt::EvalCtxt;
 pub use fulfill::FulfillmentCtxt;
 
-use self::infcx_ext::InferCtxtExt;
-
 /// A goal is a statement, i.e. `predicate`, we want to prove
 /// given some assumptions, i.e. `param_env`.
 ///
@@ -180,22 +179,7 @@ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> {
     }
 }
 
-struct EvalCtxt<'a, 'tcx> {
-    infcx: &'a InferCtxt<'tcx>,
-    var_values: CanonicalVarValues<'tcx>,
-
-    search_graph: &'a mut search_graph::SearchGraph<'tcx>,
-
-    /// This field is used by a debug assertion in [`EvalCtxt::evaluate_goal`],
-    /// see the comment in that method for more details.
-    in_projection_eq_hack: bool,
-}
-
 impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        self.infcx.tcx
-    }
-
     /// The entry point of the solver.
     ///
     /// This function deals with (coinductive) cycles, overflow, and caching
@@ -427,7 +411,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
 
         let evaluate_normalizes_to = |ecx: &mut EvalCtxt<'_, 'tcx>, alias, other| {
             debug!("evaluate_normalizes_to(alias={:?}, other={:?})", alias, other);
-            let r = ecx.infcx.probe(|_| {
+            let r = ecx.probe(|ecx| {
                 let (_, certainty) = ecx.evaluate_goal(goal.with(
                     tcx,
                     ty::Binder::dummy(ty::ProjectionPredicate {
@@ -462,10 +446,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
                 // Evaluate all 3 potential candidates for the alias' being equal
                 candidates.push(evaluate_normalizes_to(self, alias_lhs, goal.predicate.1));
                 candidates.push(evaluate_normalizes_to(self, alias_rhs, goal.predicate.0));
-                candidates.push(self.infcx.probe(|_| {
+                candidates.push(self.probe(|this| {
                     debug!("compute_alias_eq_goal: alias defids are equal, equating substs");
-                    let nested_goals = self.infcx.eq(goal.param_env, alias_lhs, alias_rhs)?;
-                    self.evaluate_all_and_make_canonical_response(nested_goals)
+                    let nested_goals = this.eq(goal.param_env, alias_lhs, alias_rhs)?;
+                    this.evaluate_all_and_make_canonical_response(nested_goals)
                 }));
 
                 debug!(?candidates);
@@ -481,7 +465,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         goal: Goal<'tcx, (ty::Const<'tcx>, Ty<'tcx>)>,
     ) -> QueryResult<'tcx> {
         let (ct, ty) = goal.predicate;
-        let nested_goals = self.infcx.eq(goal.param_env, ct.ty(), ty)?;
+        let nested_goals = self.eq(goal.param_env, ct.ty(), ty)?;
         self.evaluate_all_and_make_canonical_response(nested_goals)
     }
 }
@@ -583,7 +567,7 @@ fn compute_external_query_constraints<'tcx>(
 ) -> Result<ExternalConstraints<'tcx>, NoSolution> {
     let region_obligations = infcx.take_registered_region_obligations();
     let opaque_types = infcx.take_opaque_types_for_query_response();
-    Ok(infcx.tcx.intern_external_constraints(ExternalConstraintsData {
+    Ok(infcx.tcx.mk_external_constraints(ExternalConstraintsData {
         // FIXME: Now that's definitely wrong :)
         //
         // Should also do the leak check here I think
@@ -632,8 +616,7 @@ pub(super) fn response_no_constraints<'tcx>(
             var_values: CanonicalVarValues::make_identity(tcx, goal.variables),
             // FIXME: maybe we should store the "no response" version in tcx, like
             // we do for tcx.types and stuff.
-            external_constraints: tcx
-                .intern_external_constraints(ExternalConstraintsData::default()),
+            external_constraints: tcx.mk_external_constraints(ExternalConstraintsData::default()),
             certainty,
         },
     })
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs
index 48153b465b7..88fd8bb8bd0 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs
@@ -1,7 +1,6 @@
 use crate::traits::{specialization_graph, translate_substs};
 
 use super::assembly;
-use super::infcx_ext::InferCtxtExt;
 use super::trait_goals::structural_traits;
 use super::{Certainty, EvalCtxt, Goal, QueryResult};
 use rustc_errors::ErrorGuaranteed;
@@ -13,12 +12,11 @@ use rustc_infer::traits::query::NoSolution;
 use rustc_infer::traits::specialization_graph::LeafDef;
 use rustc_infer::traits::Reveal;
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
+use rustc_middle::ty::ProjectionPredicate;
 use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_middle::ty::{ir::TypeVisitor, ProjectionPredicate, TypeSuperVisitable};
-use rustc_middle::ty::{ToPredicate, TypeVisitable};
+use rustc_middle::ty::{ToPredicate, TypeVisitableExt};
 use rustc_span::{sym, DUMMY_SP};
 use std::iter;
-use std::ops::ControlFlow;
 
 impl<'tcx> EvalCtxt<'_, 'tcx> {
     pub(super) fn compute_projection_goal(
@@ -38,8 +36,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         } else {
             let predicate = goal.predicate;
             let unconstrained_rhs = match predicate.term.unpack() {
-                ty::TermKind::Ty(_) => self.infcx.next_ty_infer().into(),
-                ty::TermKind::Const(ct) => self.infcx.next_const_infer(ct.ty()).into(),
+                ty::TermKind::Ty(_) => self.next_ty_infer().into(),
+                ty::TermKind::Const(ct) => self.next_const_infer(ct.ty()).into(),
             };
             let unconstrained_predicate = ty::Clause::Projection(ProjectionPredicate {
                 projection_ty: goal.predicate.projection_ty,
@@ -49,8 +47,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                 this.evaluate_goal(goal.with(this.tcx(), unconstrained_predicate))
             })?;
 
-            let nested_eq_goals =
-                self.infcx.eq(goal.param_env, unconstrained_rhs, predicate.term)?;
+            let nested_eq_goals = self.eq(goal.param_env, unconstrained_rhs, predicate.term)?;
             let eval_certainty = self.evaluate_all(nested_eq_goals)?;
             self.make_canonical_response(normalize_certainty.unify_and(eval_certainty))
         }
@@ -65,73 +62,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         result
     }
 
-    /// Is the projection predicate is of the form `exists<T> <Ty as Trait>::Assoc = T`.
-    ///
-    /// This is the case if the `term` is an inference variable in the innermost universe
-    /// and does not occur in any other part of the predicate.
-    fn term_is_fully_unconstrained(&self, goal: Goal<'tcx, ProjectionPredicate<'tcx>>) -> bool {
-        let infcx = self.infcx;
-        let term_is_infer = match goal.predicate.term.unpack() {
-            ty::TermKind::Ty(ty) => {
-                if let &ty::Infer(ty::TyVar(vid)) = ty.kind() {
-                    match infcx.probe_ty_var(vid) {
-                        Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
-                        Err(universe) => universe == infcx.universe(),
-                    }
-                } else {
-                    false
-                }
-            }
-            ty::TermKind::Const(ct) => {
-                if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() {
-                    match self.infcx.probe_const_var(vid) {
-                        Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
-                        Err(universe) => universe == infcx.universe(),
-                    }
-                } else {
-                    false
-                }
-            }
-        };
-
-        // Guard against `<T as Trait<?0>>::Assoc = ?0>`.
-        struct ContainsTerm<'tcx> {
-            term: ty::Term<'tcx>,
-        }
-        impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTerm<'tcx> {
-            type BreakTy = ();
-            fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
-                if t.needs_infer() {
-                    if ty::Term::from(t) == self.term {
-                        ControlFlow::Break(())
-                    } else {
-                        t.super_visit_with(self)
-                    }
-                } else {
-                    ControlFlow::Continue(())
-                }
-            }
-
-            fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
-                if c.needs_infer() {
-                    if ty::Term::from(c) == self.term {
-                        ControlFlow::Break(())
-                    } else {
-                        c.super_visit_with(self)
-                    }
-                } else {
-                    ControlFlow::Continue(())
-                }
-            }
-        }
-
-        let mut visitor = ContainsTerm { term: goal.predicate.term };
-
-        term_is_infer
-            && goal.predicate.projection_ty.visit_with(&mut visitor).is_continue()
-            && goal.param_env.visit_with(&mut visitor).is_continue()
-    }
-
     /// After normalizing the projection to `normalized_alias` with the given
     /// `normalization_certainty`, constrain the inference variable `term` to it
     /// and return a query response.
@@ -145,7 +75,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         //
         // It can however be ambiguous when the `normalized_alias` contains a projection.
         let nested_goals = self
-            .infcx
             .eq(goal.param_env, goal.predicate.term, normalized_alias.into())
             .expect("failed to unify with unconstrained term");
         let rhs_certainty =
@@ -177,10 +106,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
         if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred()
             && poly_projection_pred.projection_def_id() == goal.predicate.def_id()
         {
-            ecx.infcx.probe(|_| {
+            ecx.probe(|ecx| {
                 let assumption_projection_pred =
-                    ecx.infcx.instantiate_binder_with_infer(poly_projection_pred);
-                let mut nested_goals = ecx.infcx.eq(
+                    ecx.instantiate_binder_with_infer(poly_projection_pred);
+                let mut nested_goals = ecx.eq(
                     goal.param_env,
                     goal.predicate.projection_ty,
                     assumption_projection_pred.projection_ty,
@@ -199,6 +128,51 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
         }
     }
 
+    fn consider_object_bound_candidate(
+        ecx: &mut EvalCtxt<'_, 'tcx>,
+        goal: Goal<'tcx, Self>,
+        assumption: ty::Predicate<'tcx>,
+    ) -> QueryResult<'tcx> {
+        if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred()
+            && poly_projection_pred.projection_def_id() == goal.predicate.def_id()
+        {
+            ecx.probe(|ecx| {
+                let assumption_projection_pred =
+                    ecx.instantiate_binder_with_infer(poly_projection_pred);
+                let mut nested_goals = ecx.eq(
+                    goal.param_env,
+                    goal.predicate.projection_ty,
+                    assumption_projection_pred.projection_ty,
+                )?;
+
+                let tcx = ecx.tcx();
+                let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else {
+                    bug!("expected object type in `consider_object_bound_candidate`");
+                };
+                nested_goals.extend(
+                    structural_traits::predicates_for_object_candidate(
+                        ecx,
+                        goal.param_env,
+                        goal.predicate.projection_ty.trait_ref(tcx),
+                        bounds,
+                    )
+                    .into_iter()
+                    .map(|pred| goal.with(tcx, pred)),
+                );
+
+                let subst_certainty = ecx.evaluate_all(nested_goals)?;
+
+                ecx.eq_term_and_make_canonical_response(
+                    goal,
+                    subst_certainty,
+                    assumption_projection_pred.term,
+                )
+            })
+        } else {
+            Err(NoSolution)
+        }
+    }
+
     fn consider_impl_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, ProjectionPredicate<'tcx>>,
@@ -215,11 +189,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
             return Err(NoSolution);
         }
 
-        ecx.infcx.probe(|_| {
-            let impl_substs = ecx.infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
+        ecx.probe(|ecx| {
+            let impl_substs = ecx.fresh_substs_for_item(impl_def_id);
             let impl_trait_ref = impl_trait_ref.subst(tcx, impl_substs);
 
-            let mut nested_goals = ecx.infcx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?;
+            let mut nested_goals = ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?;
             let where_clause_bounds = tcx
                 .predicates_of(impl_def_id)
                 .instantiate(tcx, impl_substs)
@@ -367,7 +341,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
         goal: Goal<'tcx, Self>,
     ) -> QueryResult<'tcx> {
         let tcx = ecx.tcx();
-        ecx.infcx.probe(|_| {
+        ecx.probe(|ecx| {
             let metadata_ty = match goal.predicate.self_ty().kind() {
                 ty::Bool
                 | ty::Char
@@ -387,7 +361,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
                 | ty::Never
                 | ty::Foreign(..) => tcx.types.unit,
 
-                ty::Error(e) => tcx.ty_error_with_guaranteed(*e),
+                ty::Error(e) => tcx.ty_error(*e),
 
                 ty::Str | ty::Slice(_) => tcx.types.usize,
 
@@ -546,8 +520,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
         goal: Goal<'tcx, Self>,
     ) -> QueryResult<'tcx> {
         let discriminant = goal.predicate.self_ty().discriminant_ty(ecx.tcx());
-        ecx.infcx
-            .probe(|_| ecx.eq_term_and_make_canonical_response(goal, Certainty::Yes, discriminant))
+        ecx.probe(|ecx| ecx.eq_term_and_make_canonical_response(goal, Certainty::Yes, discriminant))
     }
 }
 
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index f2f25ef850a..5c499c36e9b 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -3,16 +3,14 @@
 use std::iter;
 
 use super::assembly;
-use super::infcx_ext::InferCtxtExt;
 use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, QueryResult};
 use rustc_hir::def_id::DefId;
 use rustc_hir::LangItem;
-use rustc_infer::infer::InferCtxt;
 use rustc_infer::traits::query::NoSolution;
 use rustc_infer::traits::util::supertraits;
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
 use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
-use rustc_middle::ty::{TraitPredicate, TypeVisitable};
+use rustc_middle::ty::{TraitPredicate, TypeVisitableExt};
 use rustc_span::DUMMY_SP;
 
 pub mod structural_traits;
@@ -45,12 +43,12 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
             return Err(NoSolution);
         }
 
-        ecx.infcx.probe(|_| {
-            let impl_substs = ecx.infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
+        ecx.probe(|ecx| {
+            let impl_substs = ecx.fresh_substs_for_item(impl_def_id);
             let impl_trait_ref = impl_trait_ref.subst(tcx, impl_substs);
 
             let mut nested_goals =
-                ecx.infcx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?;
+                ecx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?;
             let where_clause_bounds = tcx
                 .predicates_of(impl_def_id)
                 .instantiate(tcx, impl_substs)
@@ -72,10 +70,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
             && poly_trait_pred.def_id() == goal.predicate.def_id()
         {
             // FIXME: Constness and polarity
-            ecx.infcx.probe(|_| {
+            ecx.probe(|ecx| {
                 let assumption_trait_pred =
-                    ecx.infcx.instantiate_binder_with_infer(poly_trait_pred);
-                let mut nested_goals = ecx.infcx.eq(
+                    ecx.instantiate_binder_with_infer(poly_trait_pred);
+                let mut nested_goals = ecx.eq(
                     goal.param_env,
                     goal.predicate.trait_ref,
                     assumption_trait_pred.trait_ref,
@@ -88,6 +86,46 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
         }
     }
 
+    fn consider_object_bound_candidate(
+        ecx: &mut EvalCtxt<'_, 'tcx>,
+        goal: Goal<'tcx, Self>,
+        assumption: ty::Predicate<'tcx>,
+    ) -> QueryResult<'tcx> {
+        if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred()
+            && poly_trait_pred.def_id() == goal.predicate.def_id()
+        {
+            // FIXME: Constness and polarity
+            ecx.probe(|ecx| {
+                let assumption_trait_pred =
+                    ecx.instantiate_binder_with_infer(poly_trait_pred);
+                let mut nested_goals = ecx.eq(
+                    goal.param_env,
+                    goal.predicate.trait_ref,
+                    assumption_trait_pred.trait_ref,
+                )?;
+
+                let tcx = ecx.tcx();
+                let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else {
+                    bug!("expected object type in `consider_object_bound_candidate`");
+                };
+                nested_goals.extend(
+                    structural_traits::predicates_for_object_candidate(
+                        ecx,
+                        goal.param_env,
+                        goal.predicate.trait_ref,
+                        bounds,
+                    )
+                    .into_iter()
+                    .map(|pred| goal.with(tcx, pred)),
+                );
+
+                ecx.evaluate_all_and_make_canonical_response(nested_goals)
+            })
+        } else {
+            Err(NoSolution)
+        }
+    }
+
     fn consider_auto_trait_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
@@ -118,7 +156,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
     ) -> QueryResult<'tcx> {
         let tcx = ecx.tcx();
 
-        ecx.infcx.probe(|_| {
+        ecx.probe(|ecx| {
             let nested_obligations = tcx
                 .predicates_of(goal.predicate.def_id())
                 .instantiate(tcx, goal.predicate.trait_ref.substs);
@@ -275,7 +313,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
         if b_ty.is_ty_var() {
             return ecx.make_canonical_response(Certainty::AMBIGUOUS);
         }
-        ecx.infcx.probe(|_| {
+        ecx.probe(|ecx| {
             match (a_ty.kind(), b_ty.kind()) {
                 // Trait upcasting, or `dyn Trait + Auto + 'a` -> `dyn Trait + 'b`
                 (&ty::Dynamic(_, _, ty::Dyn), &ty::Dynamic(_, _, ty::Dyn)) => {
@@ -318,7 +356,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
                 // `[T; n]` -> `[T]` unsizing
                 (&ty::Array(a_elem_ty, ..), &ty::Slice(b_elem_ty)) => {
                     // We just require that the element type stays the same
-                    let nested_goals = ecx.infcx.eq(goal.param_env, a_elem_ty, b_elem_ty)?;
+                    let nested_goals = ecx.eq(goal.param_env, a_elem_ty, b_elem_ty)?;
                     ecx.evaluate_all_and_make_canonical_response(nested_goals)
                 }
                 // Struct unsizing `Struct<T>` -> `Struct<U>` where `T: Unsize<U>`
@@ -345,14 +383,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
                     // Substitute just the unsizing params from B into A. The type after
                     // this substitution must be equal to B. This is so we don't unsize
                     // unrelated type parameters.
-                    let new_a_substs = tcx.mk_substs(a_substs.iter().enumerate().map(|(i, a)| {
-                        if unsizing_params.contains(i as u32) { b_substs[i] } else { a }
-                    }));
+                    let new_a_substs =
+                        tcx.mk_substs_from_iter(a_substs.iter().enumerate().map(|(i, a)| {
+                            if unsizing_params.contains(i as u32) { b_substs[i] } else { a }
+                        }));
                     let unsized_a_ty = tcx.mk_adt(a_def, new_a_substs);
 
                     // Finally, we require that `TailA: Unsize<TailB>` for the tail field
                     // types.
-                    let mut nested_goals = ecx.infcx.eq(goal.param_env, unsized_a_ty, b_ty)?;
+                    let mut nested_goals = ecx.eq(goal.param_env, unsized_a_ty, b_ty)?;
                     nested_goals.push(goal.with(
                         tcx,
                         ty::Binder::dummy(
@@ -370,8 +409,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
                     let b_last_ty = b_tys.last().unwrap();
 
                     // Substitute just the tail field of B., and require that they're equal.
-                    let unsized_a_ty = tcx.mk_tup(a_rest_tys.iter().chain([b_last_ty]).copied());
-                    let mut nested_goals = ecx.infcx.eq(goal.param_env, unsized_a_ty, b_ty)?;
+                    let unsized_a_ty =
+                        tcx.mk_tup_from_iter(a_rest_tys.iter().chain([b_last_ty]).copied());
+                    let mut nested_goals = ecx.eq(goal.param_env, unsized_a_ty, b_ty)?;
 
                     // Similar to ADTs, require that the rest of the fields are equal.
                     nested_goals.push(goal.with(
@@ -411,7 +451,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
         }
 
         let mut unsize_dyn_to_principal = |principal: Option<ty::PolyExistentialTraitRef<'tcx>>| {
-            ecx.infcx.probe(|_| -> Result<_, NoSolution> {
+            ecx.probe(|ecx| -> Result<_, NoSolution> {
                 // Require that all of the trait predicates from A match B, except for
                 // the auto traits. We do this by constructing a new A type with B's
                 // auto traits, and equating these types.
@@ -427,11 +467,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
                             .map(ty::ExistentialPredicate::AutoTrait)
                             .map(ty::Binder::dummy),
                     );
-                let new_a_data = tcx.mk_poly_existential_predicates(new_a_data);
+                let new_a_data = tcx.mk_poly_existential_predicates_from_iter(new_a_data);
                 let new_a_ty = tcx.mk_dynamic(new_a_data, b_region, ty::Dyn);
 
                 // We also require that A's lifetime outlives B's lifetime.
-                let mut nested_obligations = ecx.infcx.eq(goal.param_env, new_a_ty, b_ty)?;
+                let mut nested_obligations = ecx.eq(goal.param_env, new_a_ty, b_ty)?;
                 nested_obligations.push(
                     goal.with(tcx, ty::Binder::dummy(ty::OutlivesPredicate(a_region, b_region))),
                 );
@@ -482,16 +522,16 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     fn probe_and_evaluate_goal_for_constituent_tys(
         &mut self,
         goal: Goal<'tcx, TraitPredicate<'tcx>>,
-        constituent_tys: impl Fn(&InferCtxt<'tcx>, Ty<'tcx>) -> Result<Vec<Ty<'tcx>>, NoSolution>,
+        constituent_tys: impl Fn(&EvalCtxt<'_, 'tcx>, Ty<'tcx>) -> Result<Vec<Ty<'tcx>>, NoSolution>,
     ) -> QueryResult<'tcx> {
-        self.infcx.probe(|_| {
-            self.evaluate_all_and_make_canonical_response(
-                constituent_tys(self.infcx, goal.predicate.self_ty())?
+        self.probe(|this| {
+            this.evaluate_all_and_make_canonical_response(
+                constituent_tys(this, goal.predicate.self_ty())?
                     .into_iter()
                     .map(|ty| {
                         goal.with(
-                            self.tcx(),
-                            ty::Binder::dummy(goal.predicate.with_self_ty(self.tcx(), ty)),
+                            this.tcx(),
+                            ty::Binder::dummy(goal.predicate.with_self_ty(this.tcx(), ty)),
                         )
                     })
                     .collect(),
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs
index 3662463178f..d7d93377cf1 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs
@@ -1,16 +1,19 @@
-use rustc_hir::{Movability, Mutability};
-use rustc_infer::{infer::InferCtxt, traits::query::NoSolution};
-use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_data_structures::fx::FxHashMap;
+use rustc_hir::{def_id::DefId, Movability, Mutability};
+use rustc_infer::traits::query::NoSolution;
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable};
+
+use crate::solve::EvalCtxt;
 
 // Calculates the constituent types of a type for `auto trait` purposes.
 //
 // For types with an "existential" binder, i.e. generator witnesses, we also
 // instantiate the binder with placeholders eagerly.
 pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
-    infcx: &InferCtxt<'tcx>,
+    ecx: &EvalCtxt<'_, 'tcx>,
     ty: Ty<'tcx>,
 ) -> Result<Vec<Ty<'tcx>>, NoSolution> {
-    let tcx = infcx.tcx;
+    let tcx = ecx.tcx();
     match *ty.kind() {
         ty::Uint(_)
         | ty::Int(_)
@@ -18,12 +21,14 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
         | ty::Float(_)
         | ty::FnDef(..)
         | ty::FnPtr(_)
-        | ty::Str
         | ty::Error(_)
         | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
         | ty::Never
         | ty::Char => Ok(vec![]),
 
+        // Treat this like `struct str([u8]);`
+        ty::Str => Ok(vec![tcx.mk_slice(tcx.types.u8)]),
+
         ty::Dynamic(..)
         | ty::Param(..)
         | ty::Foreign(..)
@@ -53,9 +58,7 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
             Ok(vec![generator_substs.tupled_upvars_ty(), generator_substs.witness()])
         }
 
-        ty::GeneratorWitness(types) => {
-            Ok(infcx.instantiate_binder_with_placeholders(types).to_vec())
-        }
+        ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()),
 
         ty::GeneratorWitnessMIR(..) => todo!(),
 
@@ -74,7 +77,7 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
 }
 
 pub(super) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
-    infcx: &InferCtxt<'tcx>,
+    ecx: &EvalCtxt<'_, 'tcx>,
     ty: Ty<'tcx>,
 ) -> Result<Vec<Ty<'tcx>>, NoSolution> {
     match *ty.kind() {
@@ -113,18 +116,18 @@ pub(super) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
         ty::Tuple(tys) => Ok(tys.to_vec()),
 
         ty::Adt(def, substs) => {
-            let sized_crit = def.sized_constraint(infcx.tcx);
+            let sized_crit = def.sized_constraint(ecx.tcx());
             Ok(sized_crit
                 .0
                 .iter()
-                .map(|ty| sized_crit.rebind(*ty).subst(infcx.tcx, substs))
+                .map(|ty| sized_crit.rebind(*ty).subst(ecx.tcx(), substs))
                 .collect())
         }
     }
 }
 
 pub(super) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
-    infcx: &InferCtxt<'tcx>,
+    ecx: &EvalCtxt<'_, 'tcx>,
     ty: Ty<'tcx>,
 ) -> Result<Vec<Ty<'tcx>>, NoSolution> {
     match *ty.kind() {
@@ -165,7 +168,7 @@ pub(super) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
         ty::Closure(_, substs) => Ok(vec![substs.as_closure().tupled_upvars_ty()]),
 
         ty::Generator(_, substs, Movability::Movable) => {
-            if infcx.tcx.features().generator_clone {
+            if ecx.tcx().features().generator_clone {
                 let generator = substs.as_generator();
                 Ok(vec![generator.tupled_upvars_ty(), generator.witness()])
             } else {
@@ -173,9 +176,7 @@ pub(super) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
             }
         }
 
-        ty::GeneratorWitness(types) => {
-            Ok(infcx.instantiate_binder_with_placeholders(types).to_vec())
-        }
+        ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()),
 
         ty::GeneratorWitnessMIR(..) => todo!(),
     }
@@ -191,11 +192,9 @@ pub(crate) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
         ty::FnDef(def_id, substs) => Ok(Some(
             tcx.fn_sig(def_id)
                 .subst(tcx, substs)
-                .map_bound(|sig| (tcx.intern_tup(sig.inputs()), sig.output())),
+                .map_bound(|sig| (tcx.mk_tup(sig.inputs()), sig.output())),
         )),
-        ty::FnPtr(sig) => {
-            Ok(Some(sig.map_bound(|sig| (tcx.intern_tup(sig.inputs()), sig.output()))))
-        }
+        ty::FnPtr(sig) => Ok(Some(sig.map_bound(|sig| (tcx.mk_tup(sig.inputs()), sig.output())))),
         ty::Closure(_, substs) => {
             let closure_substs = substs.as_closure();
             match closure_substs.kind_ty().to_opt_closure_kind() {
@@ -235,3 +234,112 @@ pub(crate) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
         }
     }
 }
+
+/// Assemble a list of predicates that would be present on a theoretical
+/// user impl for an object type. These predicates must be checked any time
+/// we assemble a built-in object candidate for an object type, since they
+/// are not implied by the well-formedness of the type.
+///
+/// For example, given the following traits:
+///
+/// ```rust,ignore (theoretical code)
+/// trait Foo: Baz {
+///     type Bar: Copy;
+/// }
+///
+/// trait Baz {}
+/// ```
+///
+/// For the dyn type `dyn Foo<Item = Ty>`, we can imagine there being a
+/// pair of theoretical impls:
+///
+/// ```rust,ignore (theoretical code)
+/// impl Foo for dyn Foo<Item = Ty>
+/// where
+///     Self: Baz,
+///     <Self as Foo>::Bar: Copy,
+/// {
+///     type Bar = Ty;
+/// }
+///
+/// impl Baz for dyn Foo<Item = Ty> {}
+/// ```
+///
+/// However, in order to make such impls well-formed, we need to do an
+/// additional step of eagerly folding the associated types in the where
+/// clauses of the impl. In this example, that means replacing
+/// `<Self as Foo>::Bar` with `Ty` in the first impl.
+pub(crate) fn predicates_for_object_candidate<'tcx>(
+    ecx: &EvalCtxt<'_, 'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+    trait_ref: ty::TraitRef<'tcx>,
+    object_bound: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
+) -> Vec<ty::Predicate<'tcx>> {
+    let tcx = ecx.tcx();
+    let mut requirements = vec![];
+    requirements.extend(
+        tcx.super_predicates_of(trait_ref.def_id).instantiate(tcx, trait_ref.substs).predicates,
+    );
+    for item in tcx.associated_items(trait_ref.def_id).in_definition_order() {
+        // FIXME(associated_const_equality): Also add associated consts to
+        // the requirements here.
+        if item.kind == ty::AssocKind::Type {
+            requirements.extend(tcx.item_bounds(item.def_id).subst(tcx, trait_ref.substs));
+        }
+    }
+
+    let mut replace_projection_with = FxHashMap::default();
+    for bound in object_bound {
+        if let ty::ExistentialPredicate::Projection(proj) = bound.skip_binder() {
+            let proj = proj.with_self_ty(tcx, trait_ref.self_ty());
+            let old_ty = replace_projection_with.insert(proj.def_id(), bound.rebind(proj));
+            assert_eq!(
+                old_ty,
+                None,
+                "{} has two substitutions: {} and {}",
+                proj.projection_ty,
+                proj.term,
+                old_ty.unwrap()
+            );
+        }
+    }
+
+    requirements.fold_with(&mut ReplaceProjectionWith {
+        ecx,
+        param_env,
+        mapping: replace_projection_with,
+    })
+}
+
+struct ReplaceProjectionWith<'a, 'tcx> {
+    ecx: &'a EvalCtxt<'a, 'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+    mapping: FxHashMap<DefId, ty::PolyProjectionPredicate<'tcx>>,
+}
+
+impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceProjectionWith<'_, 'tcx> {
+    fn interner(&self) -> TyCtxt<'tcx> {
+        self.ecx.tcx()
+    }
+
+    fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
+        if let ty::Alias(ty::Projection, alias_ty) = *ty.kind()
+            && let Some(replacement) = self.mapping.get(&alias_ty.def_id)
+        {
+            // We may have a case where our object type's projection bound is higher-ranked,
+            // but the where clauses we instantiated are not. We can solve this by instantiating
+            // the binder at the usage site.
+            let proj = self.ecx.instantiate_binder_with_infer(*replacement);
+            // FIXME: Technically this folder could be fallible?
+            let nested = self
+                .ecx
+                .eq(self.param_env, alias_ty, proj.projection_ty)
+                .expect("expected to be able to unify goal projection with dyn's projection");
+            // FIXME: Technically we could register these too..
+            assert!(nested.is_empty(), "did not expect unification to have any nested goals");
+            proj.term.ty().unwrap()
+        } else {
+            ty.super_fold_with(self)
+        }
+    }
+}
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index 9776cc57af8..1fb8659bb27 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -8,9 +8,8 @@ use crate::infer::region_constraints::{Constraint, RegionConstraintData};
 use crate::infer::InferCtxt;
 use crate::traits::project::ProjectAndUnifyResult;
 use rustc_middle::mir::interpret::ErrorHandled;
-use rustc_middle::ty::fold::{ir::TypeFolder, TypeSuperFoldable};
-#[cfg(not(bootstrap))]
-use rustc_middle::ty::visit::TypeVisitable;
+use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
+use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{ImplPolarity, Region, RegionVid};
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
@@ -351,14 +350,14 @@ impl<'tcx> AutoTraitFinder<'tcx> {
             )
             .map(|o| o.predicate);
             new_env = ty::ParamEnv::new(
-                tcx.mk_predicates(normalized_preds),
+                tcx.mk_predicates_from_iter(normalized_preds),
                 param_env.reveal(),
                 param_env.constness(),
             );
         }
 
         let final_user_env = ty::ParamEnv::new(
-            tcx.mk_predicates(user_computed_preds.into_iter()),
+            tcx.mk_predicates_from_iter(user_computed_preds.into_iter()),
             user_env.reveal(),
             user_env.constness(),
         );
diff --git a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs
index e26bef0b8b7..b42a49eb47b 100644
--- a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs
@@ -8,7 +8,7 @@ use crate::traits::{
     SelectionError, TraitEngine,
 };
 use rustc_data_structures::fx::FxIndexSet;
-use rustc_middle::ty::TypeVisitable;
+use rustc_middle::ty::TypeVisitableExt;
 
 pub struct FulfillmentContext<'tcx> {
     obligations: FxIndexSet<PredicateObligation<'tcx>>,
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 599238e405d..6b688c322c7 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -21,8 +21,8 @@ use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::util;
 use rustc_middle::traits::specialization_graph::OverlapMode;
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
-use rustc_middle::ty::visit::TypeVisitable;
-use rustc_middle::ty::{self, ir::TypeVisitor, ImplSubject, Ty, TyCtxt};
+use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
+use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitor};
 use rustc_span::symbol::sym;
 use rustc_span::DUMMY_SP;
 use std::fmt::Debug;
@@ -217,6 +217,7 @@ fn equate_impl_headers<'cx, 'tcx>(
     selcx
         .infcx
         .at(&ObligationCause::dummy(), ty::ParamEnv::empty())
+        .define_opaque_types(true)
         .eq_impl_headers(impl1_header, impl2_header)
         .map(|infer_ok| infer_ok.obligations)
         .ok()
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index dd9b5b534d7..345e84990ed 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -14,7 +14,7 @@ use rustc_middle::mir::interpret::ErrorHandled;
 
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
-use rustc_middle::ty::{self, ir::TypeVisitor, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, TyCtxt, TypeVisitable, TypeVisitableExt, TypeVisitor};
 
 use rustc_span::Span;
 use std::ops::ControlFlow;
diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs
index a2ddd91546c..b20636174ee 100644
--- a/compiler/rustc_trait_selection/src/traits/engine.rs
+++ b/compiler/rustc_trait_selection/src/traits/engine.rs
@@ -104,7 +104,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
         });
     }
 
-    pub fn normalize<T: TypeFoldable<'tcx>>(
+    pub fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(
         &self,
         cause: &ObligationCause<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
@@ -128,6 +128,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
     {
         self.infcx
             .at(cause, param_env)
+            .define_opaque_types(true)
             .eq_exp(a_is_expected, a, b)
             .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
     }
@@ -141,6 +142,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
     ) -> Result<(), TypeError<'tcx>> {
         self.infcx
             .at(cause, param_env)
+            .define_opaque_types(true)
             .eq(expected, actual)
             .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
     }
@@ -155,6 +157,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
     ) -> Result<(), TypeError<'tcx>> {
         self.infcx
             .at(cause, param_env)
+            .define_opaque_types(true)
             .sup(expected, actual)
             .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
     }
@@ -169,6 +172,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
     ) -> Result<(), TypeError<'tcx>> {
         self.infcx
             .at(cause, param_env)
+            .define_opaque_types(true)
             .sup(expected, actual)
             .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
     }
@@ -216,7 +220,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
         answer: T,
     ) -> Fallible<CanonicalQueryResponse<'tcx, T>>
     where
-        T: Debug + TypeFoldable<'tcx>,
+        T: Debug + TypeFoldable<TyCtxt<'tcx>>,
         Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>,
     {
         self.infcx.make_canonicalized_query_response(
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs
index 9474c70cb53..1174efdbfa8 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs
@@ -98,7 +98,7 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for CollectAllMismatches<'_, 'tcx> {
 
     fn register_predicates(
         &mut self,
-        _obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>,
+        _obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>,
     ) {
         // FIXME(deferred_projection_equality)
     }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index a32ab16263a..a844a1494e2 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -34,10 +34,11 @@ use rustc_infer::infer::{InferOk, TypeTrace};
 use rustc_middle::traits::select::OverflowError;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
-use rustc_middle::ty::fold::{ir::TypeFolder, TypeSuperFoldable};
+use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::print::{with_forced_trimmed_paths, FmtPrinter, Print};
 use rustc_middle::ty::{
     self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
+    TypeVisitable, TypeVisitableExt,
 };
 use rustc_session::config::TraitSolver;
 use rustc_session::Limit;
@@ -108,7 +109,7 @@ pub trait TypeErrCtxtExt<'tcx> {
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>
     where
         T: fmt::Display
-            + TypeFoldable<'tcx>
+            + TypeFoldable<TyCtxt<'tcx>>
             + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
         <T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug;
 
@@ -121,7 +122,7 @@ pub trait TypeErrCtxtExt<'tcx> {
     ) -> !
     where
         T: fmt::Display
-            + TypeFoldable<'tcx>
+            + TypeFoldable<TyCtxt<'tcx>>
             + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
         <T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug;
 
@@ -491,7 +492,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     ) -> !
     where
         T: fmt::Display
-            + TypeFoldable<'tcx>
+            + TypeFoldable<TyCtxt<'tcx>>
             + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
         <T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug,
     {
@@ -511,7 +512,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>
     where
         T: fmt::Display
-            + TypeFoldable<'tcx>
+            + TypeFoldable<TyCtxt<'tcx>>
             + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
         <T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug,
     {
@@ -2970,7 +2971,7 @@ impl ArgKind {
 
 struct HasNumericInferVisitor;
 
-impl<'tcx> ty::ir::TypeVisitor<TyCtxt<'tcx>> for HasNumericInferVisitor {
+impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for HasNumericInferVisitor {
     type BreakTy = ();
 
     fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 91b463800a8..66d74fd05a6 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -30,10 +30,10 @@ use rustc_middle::hir::map;
 use rustc_middle::ty::error::TypeError::{self, Sorts};
 use rustc_middle::ty::relate::TypeRelation;
 use rustc_middle::ty::{
-    self, ir::TypeFolder, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind,
-    DefIdTree, GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, InternalSubsts,
-    IsSuggestable, ToPredicate, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeSuperFoldable,
-    TypeckResults,
+    self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree,
+    GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, InternalSubsts,
+    IsSuggestable, ToPredicate, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeFolder,
+    TypeSuperFoldable, TypeVisitableExt, TypeckResults,
 };
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::{sym, Ident, Symbol};
@@ -927,7 +927,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 DefKind::Ctor(CtorOf::Variant, _) => {
                     "use parentheses to construct this tuple variant".to_string()
                 }
-                kind => format!("use parentheses to call this {}", kind.descr(def_id)),
+                kind => format!(
+                    "use parentheses to call this {}",
+                    self.tcx.def_kind_descr(kind, def_id)
+                ),
             },
             DefIdOrName::Name(name) => format!("use parentheses to call this {name}"),
         };
@@ -2139,7 +2142,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 err.note(&format!(
                     "{}s cannot be accessed directly on a `trait`, they can only be \
                         accessed through a specific `impl`",
-                    assoc_item.kind.as_def_kind().descr(item_def_id)
+                    self.tcx.def_kind_descr(assoc_item.kind.as_def_kind(), item_def_id)
                 ));
                 err.span_suggestion(
                     span,
@@ -2784,7 +2787,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                             _ => true,
                         };
                     if ident.span.is_visible(sm) && !ident.span.overlaps(span) && !same_line {
-                        multispan.push_span_label(ident.span, "required by a bound in this");
+                        multispan.push_span_label(
+                            ident.span,
+                            format!(
+                                "required by a bound in this {}",
+                                tcx.def_kind(item_def_id).descr(item_def_id)
+                            ),
+                        );
                     }
                 }
                 let descr = format!("required by a bound in `{item_name}`");
@@ -3098,6 +3107,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                 self.tcx.def_span(def_id),
                                 "required because it's used within this closure",
                             ),
+                            ty::Str => err.note("`str` is considered to contain a `[u8]` slice for auto trait purposes"),
                             _ => err.note(&msg),
                         };
                     }
@@ -3525,7 +3535,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         {
             if let hir::Expr { kind: hir::ExprKind::Block(..), .. } = expr {
                 let expr = expr.peel_blocks();
-                let ty = typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error());
+                let ty = typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error_misc());
                 let span = expr.span;
                 if Some(span) != err.span.primary_span() {
                     err.span_label(
@@ -3628,7 +3638,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         let mut assocs = vec![];
         let mut expr = expr;
         let mut prev_ty = self.resolve_vars_if_possible(
-            typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error()),
+            typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error_misc()),
         );
         while let hir::ExprKind::MethodCall(_path_segment, rcvr_expr, _args, span) = expr.kind {
             // Point at every method call in the chain with the resulting type.
@@ -3639,7 +3649,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 self.probe_assoc_types_at_expr(&type_diffs, span, prev_ty, expr.hir_id, param_env);
             assocs.push(assocs_in_this_method);
             prev_ty = self.resolve_vars_if_possible(
-                typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error()),
+                typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error_misc()),
             );
 
             if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
@@ -3657,7 +3667,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 if let hir::Node::Param(param) = parent {
                     // ...and it is a an fn argument.
                     let prev_ty = self.resolve_vars_if_possible(
-                        typeck_results.node_type_opt(param.hir_id).unwrap_or(tcx.ty_error()),
+                        typeck_results.node_type_opt(param.hir_id).unwrap_or(tcx.ty_error_misc()),
                     );
                     let assocs_in_this_method = self.probe_assoc_types_at_expr(&type_diffs, param.ty_span, prev_ty, param.hir_id, param_env);
                     if assocs_in_this_method.iter().any(|a| a.is_some()) {
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index deeed930e50..da2416b9646 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -8,7 +8,7 @@ use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::{self, Binder, Const, TypeVisitable};
+use rustc_middle::ty::{self, Binder, Const, TypeVisitableExt};
 use std::marker::PhantomData;
 
 use super::const_evaluatable;
diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs
index de730773794..b94346b0956 100644
--- a/compiler/rustc_trait_selection/src/traits/misc.rs
+++ b/compiler/rustc_trait_selection/src/traits/misc.rs
@@ -8,7 +8,7 @@ use rustc_infer::infer::canonical::Canonical;
 use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
 use rustc_infer::traits::query::NoSolution;
 use rustc_infer::{infer::outlives::env::OutlivesEnvironment, traits::FulfillmentError};
-use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeVisitableExt};
 use rustc_span::DUMMY_SP;
 
 use super::outlives_bounds::InferCtxtExt;
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 2d299486ee6..b2317f55d25 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -27,7 +27,7 @@ use crate::traits::error_reporting::TypeErrCtxtExt as _;
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc_errors::ErrorGuaranteed;
 use rustc_middle::ty::fold::TypeFoldable;
-use rustc_middle::ty::visit::TypeVisitable;
+use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
 use rustc_middle::ty::{self, DefIdTree, ToPredicate, Ty, TyCtxt, TypeSuperVisitable};
 use rustc_middle::ty::{InternalSubsts, SubstsRef};
 use rustc_span::def_id::{DefId, CRATE_DEF_ID};
@@ -141,7 +141,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>(
 fn pred_known_to_hold_modulo_regions<'tcx>(
     infcx: &InferCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
-    pred: impl ToPredicate<'tcx> + TypeVisitable<'tcx>,
+    pred: impl ToPredicate<'tcx> + TypeVisitable<TyCtxt<'tcx>>,
     span: Span,
 ) -> bool {
     let has_non_region_infer = pred.has_non_region_infer();
@@ -281,7 +281,7 @@ pub fn normalize_param_env_or_error<'tcx>(
     debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates);
 
     let elaborated_env = ty::ParamEnv::new(
-        tcx.intern_predicates(&predicates),
+        tcx.mk_predicates(&predicates),
         unnormalized_env.reveal(),
         unnormalized_env.constness(),
     );
@@ -333,10 +333,9 @@ pub fn normalize_param_env_or_error<'tcx>(
     // Not sure whether it is better to include the unnormalized TypeOutlives predicates
     // here. I believe they should not matter, because we are ignoring TypeOutlives param-env
     // predicates here anyway. Keeping them here anyway because it seems safer.
-    let outlives_env: Vec<_> =
-        non_outlives_predicates.iter().chain(&outlives_predicates).cloned().collect();
+    let outlives_env = non_outlives_predicates.iter().chain(&outlives_predicates).cloned();
     let outlives_env = ty::ParamEnv::new(
-        tcx.intern_predicates(&outlives_env),
+        tcx.mk_predicates_from_iter(outlives_env),
         unnormalized_env.reveal(),
         unnormalized_env.constness(),
     );
@@ -356,7 +355,7 @@ pub fn normalize_param_env_or_error<'tcx>(
     predicates.extend(outlives_predicates);
     debug!("normalize_param_env_or_error: final predicates={:?}", predicates);
     ty::ParamEnv::new(
-        tcx.intern_predicates(&predicates),
+        tcx.mk_predicates(&predicates),
         unnormalized_env.reveal(),
         unnormalized_env.constness(),
     )
@@ -371,7 +370,7 @@ pub fn fully_normalize<'tcx, T>(
     value: T,
 ) -> Result<T, Vec<FulfillmentError<'tcx>>>
 where
-    T: TypeFoldable<'tcx>,
+    T: TypeFoldable<TyCtxt<'tcx>>,
 {
     let ocx = ObligationCtxt::new(infcx);
     debug!(?value);
@@ -481,7 +480,7 @@ fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefI
         generics: &'tcx ty::Generics,
         trait_item_def_id: DefId,
     }
-    impl<'tcx> ty::ir::TypeVisitor<TyCtxt<'tcx>> for ReferencesOnlyParentGenerics<'tcx> {
+    impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for ReferencesOnlyParentGenerics<'tcx> {
         type BreakTy = ();
         fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
             // If this is a parameter from the trait item's own generics, then bail
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index df1aeed941d..4eacb5211f7 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -18,10 +18,10 @@ use rustc_errors::{DelayDm, FatalError, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::subst::{GenericArg, InternalSubsts};
+use rustc_middle::ty::ToPredicate;
 use rustc_middle::ty::{
-    self, ir::TypeVisitor, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
+    self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor,
 };
-use rustc_middle::ty::{Predicate, ToPredicate};
 use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY;
 use rustc_span::symbol::Symbol;
 use rustc_span::Span;
@@ -666,8 +666,9 @@ fn object_ty_for_trait<'tcx>(
     elaborated_predicates.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
     elaborated_predicates.dedup();
 
-    let existential_predicates = tcx
-        .mk_poly_existential_predicates(iter::once(trait_predicate).chain(elaborated_predicates));
+    let existential_predicates = tcx.mk_poly_existential_predicates_from_iter(
+        iter::once(trait_predicate).chain(elaborated_predicates),
+    );
     debug!(?existential_predicates);
 
     tcx.mk_dynamic(existential_predicates, lifetime, ty::Dyn)
@@ -766,11 +767,11 @@ fn receiver_is_dispatchable<'tcx>(
             ty::Binder::dummy(tcx.mk_trait_ref(trait_def_id, substs)).to_predicate(tcx)
         };
 
-        let caller_bounds: Vec<Predicate<'tcx>> =
-            param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]).collect();
+        let caller_bounds =
+            param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]);
 
         ty::ParamEnv::new(
-            tcx.intern_predicates(&caller_bounds),
+            tcx.mk_predicates_from_iter(caller_bounds),
             param_env.reveal(),
             param_env.constness(),
         )
@@ -790,7 +791,7 @@ fn receiver_is_dispatchable<'tcx>(
     infcx.predicate_must_hold_modulo_regions(&obligation)
 }
 
-fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>(
+fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
     tcx: TyCtxt<'tcx>,
     trait_def_id: DefId,
     value: T,
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 1c66fb257eb..e5b0f9d3300 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -30,8 +30,8 @@ use rustc_infer::infer::at::At;
 use rustc_infer::infer::resolve::OpportunisticRegionResolver;
 use rustc_infer::traits::ImplSourceBuiltinData;
 use rustc_middle::traits::select::OverflowError;
-use rustc_middle::ty::fold::{ir::TypeFolder, TypeFoldable, TypeSuperFoldable};
-use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable};
+use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
+use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt};
 use rustc_middle::ty::DefIdTree;
 use rustc_middle::ty::{self, Term, ToPredicate, Ty, TyCtxt};
 use rustc_span::symbol::sym;
@@ -53,11 +53,11 @@ pub trait NormalizeExt<'tcx> {
     ///
     /// This normalization should be used when the type contains inference variables or the
     /// projection may be fallible.
-    fn normalize<T: TypeFoldable<'tcx>>(&self, t: T) -> InferOk<'tcx, T>;
+    fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> InferOk<'tcx, T>;
 }
 
 impl<'tcx> NormalizeExt<'tcx> for At<'_, 'tcx> {
-    fn normalize<T: TypeFoldable<'tcx>>(&self, value: T) -> InferOk<'tcx, T> {
+    fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, value: T) -> InferOk<'tcx, T> {
         let mut selcx = SelectionContext::new(self.infcx);
         let Normalized { value, obligations } =
             normalize_with_depth(&mut selcx, self.param_env, self.cause.clone(), 0, value);
@@ -286,7 +286,12 @@ fn project_and_unify_type<'cx, 'tcx>(
         );
     obligations.extend(new);
 
-    match infcx.at(&obligation.cause, obligation.param_env).eq(normalized, actual) {
+    match infcx
+        .at(&obligation.cause, obligation.param_env)
+        // This is needed to support nested opaque types like `impl Fn() -> impl Trait`
+        .define_opaque_types(true)
+        .eq(normalized, actual)
+    {
         Ok(InferOk { obligations: inferred_obligations, value: () }) => {
             obligations.extend(inferred_obligations);
             ProjectAndUnifyResult::Holds(obligations)
@@ -307,7 +312,7 @@ pub(crate) fn normalize_with_depth<'a, 'b, 'tcx, T>(
     value: T,
 ) -> Normalized<'tcx, T>
 where
-    T: TypeFoldable<'tcx>,
+    T: TypeFoldable<TyCtxt<'tcx>>,
 {
     let mut obligations = Vec::new();
     let value = normalize_with_depth_to(selcx, param_env, cause, depth, value, &mut obligations);
@@ -324,7 +329,7 @@ pub(crate) fn normalize_with_depth_to<'a, 'b, 'tcx, T>(
     obligations: &mut Vec<PredicateObligation<'tcx>>,
 ) -> T
 where
-    T: TypeFoldable<'tcx>,
+    T: TypeFoldable<TyCtxt<'tcx>>,
 {
     debug!(obligations.len = obligations.len());
     let mut normalizer = AssocTypeNormalizer::new(selcx, param_env, cause, depth, obligations);
@@ -344,7 +349,7 @@ pub(crate) fn try_normalize_with_depth_to<'a, 'b, 'tcx, T>(
     obligations: &mut Vec<PredicateObligation<'tcx>>,
 ) -> T
 where
-    T: TypeFoldable<'tcx>,
+    T: TypeFoldable<TyCtxt<'tcx>>,
 {
     debug!(obligations.len = obligations.len());
     let mut normalizer = AssocTypeNormalizer::new_without_eager_inference_replacement(
@@ -360,7 +365,10 @@ where
     result
 }
 
-pub(crate) fn needs_normalization<'tcx, T: TypeVisitable<'tcx>>(value: &T, reveal: Reveal) -> bool {
+pub(crate) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
+    value: &T,
+    reveal: Reveal,
+) -> bool {
     match reveal {
         Reveal::UserFacing => value
             .has_type_flags(ty::TypeFlags::HAS_TY_PROJECTION | ty::TypeFlags::HAS_CT_PROJECTION),
@@ -422,7 +430,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
         }
     }
 
-    fn fold<T: TypeFoldable<'tcx>>(&mut self, value: T) -> T {
+    fn fold<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, value: T) -> T {
         let value = self.selcx.infcx.resolve_vars_if_possible(value);
         debug!(?value);
 
@@ -445,7 +453,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
         self.selcx.tcx()
     }
 
-    fn fold_binder<T: TypeFoldable<'tcx>>(
+    fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
         &mut self,
         t: ty::Binder<'tcx, T>,
     ) -> ty::Binder<'tcx, T> {
@@ -664,7 +672,12 @@ pub struct BoundVarReplacer<'me, 'tcx> {
 ///
 /// FIXME(@lcnr): We may even consider experimenting with eagerly replacing bound vars during
 /// normalization as well, at which point this function will be unnecessary and can be removed.
-pub fn with_replaced_escaping_bound_vars<'a, 'tcx, T: TypeFoldable<'tcx>, R: TypeFoldable<'tcx>>(
+pub fn with_replaced_escaping_bound_vars<
+    'a,
+    'tcx,
+    T: TypeFoldable<TyCtxt<'tcx>>,
+    R: TypeFoldable<TyCtxt<'tcx>>,
+>(
     infcx: &'a InferCtxt<'tcx>,
     universe_indices: &'a mut Vec<Option<ty::UniverseIndex>>,
     value: T,
@@ -690,7 +703,7 @@ pub fn with_replaced_escaping_bound_vars<'a, 'tcx, T: TypeFoldable<'tcx>, R: Typ
 impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> {
     /// Returns `Some` if we *were* able to replace bound vars. If there are any bound vars that
     /// use a binding level above `universe_indices.len()`, we fail.
-    pub fn replace_bound_vars<T: TypeFoldable<'tcx>>(
+    pub fn replace_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
         infcx: &'me InferCtxt<'tcx>,
         universe_indices: &'me mut Vec<Option<ty::UniverseIndex>>,
         value: T,
@@ -737,7 +750,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for BoundVarReplacer<'_, 'tcx> {
         self.infcx.tcx
     }
 
-    fn fold_binder<T: TypeFoldable<'tcx>>(
+    fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
         &mut self,
         t: ty::Binder<'tcx, T>,
     ) -> ty::Binder<'tcx, T> {
@@ -818,7 +831,7 @@ pub struct PlaceholderReplacer<'me, 'tcx> {
 }
 
 impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> {
-    pub fn replace_placeholders<T: TypeFoldable<'tcx>>(
+    pub fn replace_placeholders<T: TypeFoldable<TyCtxt<'tcx>>>(
         infcx: &'me InferCtxt<'tcx>,
         mapped_regions: BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>,
         mapped_types: BTreeMap<ty::PlaceholderType, ty::BoundTy>,
@@ -843,7 +856,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> {
         self.infcx.tcx
     }
 
-    fn fold_binder<T: TypeFoldable<'tcx>>(
+    fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
         &mut self,
         t: ty::Binder<'tcx, T>,
     ) -> ty::Binder<'tcx, T> {
@@ -1200,8 +1213,8 @@ struct Progress<'tcx> {
 }
 
 impl<'tcx> Progress<'tcx> {
-    fn error(tcx: TyCtxt<'tcx>) -> Self {
-        Progress { term: tcx.ty_error().into(), obligations: vec![] }
+    fn error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Self {
+        Progress { term: tcx.ty_error(guar).into(), obligations: vec![] }
     }
 
     fn with_addl_obligations(mut self, mut obligations: Vec<PredicateObligation<'tcx>>) -> Self {
@@ -1227,8 +1240,8 @@ fn project<'cx, 'tcx>(
         )));
     }
 
-    if obligation.predicate.references_error() {
-        return Ok(Projected::Progress(Progress::error(selcx.tcx())));
+    if let Err(guar) = obligation.predicate.error_reported() {
+        return Ok(Projected::Progress(Progress::error(selcx.tcx(), guar)));
     }
 
     let mut candidates = ProjectionCandidateSet::None;
@@ -1893,7 +1906,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
 ) -> Progress<'tcx> {
     let tcx = selcx.tcx();
     let self_ty = obligation.predicate.self_ty();
-    let substs = tcx.intern_substs(&[self_ty.into()]);
+    let substs = tcx.mk_substs(&[self_ty.into()]);
     let lang_items = tcx.lang_items();
     let item_def_id = obligation.predicate.def_id;
     let trait_def_id = tcx.trait_of_item(item_def_id).unwrap();
@@ -2084,8 +2097,9 @@ 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 Ok(assoc_ty) = specialization_graph::assoc_def(tcx, impl_def_id, assoc_item_id) else {
-        return Progress { term: tcx.ty_error().into(), obligations: nested };
+    let assoc_ty = match specialization_graph::assoc_def(tcx, impl_def_id, assoc_item_id) {
+        Ok(assoc_ty) => assoc_ty,
+        Err(guar) => return Progress::error(tcx, guar),
     };
 
     if !assoc_ty.item.defaultness(tcx).has_value() {
@@ -2097,7 +2111,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
             "confirm_impl_candidate: no associated type {:?} for {:?}",
             assoc_ty.item.name, obligation.predicate
         );
-        return Progress { term: tcx.ty_error().into(), obligations: nested };
+        return Progress { term: tcx.ty_error_misc().into(), obligations: nested };
     }
     // If we're trying to normalize `<Vec<u32> as X>::A<S>` using
     //`impl<T> X for Vec<T> { type A<Y> = Box<Y>; }`, then:
@@ -2181,11 +2195,12 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
     let mut obligations = data.nested;
 
     let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.def_id);
-    let Ok(leaf_def) = specialization_graph::assoc_def(tcx, data.impl_def_id, trait_fn_def_id) else {
-        return Progress { term: tcx.ty_error().into(), obligations };
+    let leaf_def = match specialization_graph::assoc_def(tcx, data.impl_def_id, trait_fn_def_id) {
+        Ok(assoc_ty) => assoc_ty,
+        Err(guar) => return Progress::error(tcx, guar),
     };
     if !leaf_def.item.defaultness(tcx).has_value() {
-        return Progress { term: tcx.ty_error().into(), obligations };
+        return Progress { term: tcx.ty_error_misc().into(), obligations };
     }
 
     // Use the default `impl Trait` for the trait, e.g., for a default trait body
@@ -2256,7 +2271,7 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
         obligation.recursion_depth + 1,
         tcx.bound_return_position_impl_trait_in_trait_tys(impl_fn_def_id)
             .map_bound(|tys| {
-                tys.map_or_else(|_| tcx.ty_error(), |tys| tys[&obligation.predicate.def_id])
+                tys.map_or_else(|guar| tcx.ty_error(guar), |tys| tys[&obligation.predicate.def_id])
             })
             .subst(tcx, impl_fn_substs),
         &mut obligations,
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index a266013b8fd..b0cec3ce7a3 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -11,9 +11,9 @@ use crate::traits::{ObligationCause, PredicateObligation, Reveal};
 use rustc_data_structures::sso::SsoHashMap;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_infer::traits::Normalized;
-use rustc_middle::ty::fold::{ir::FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
-use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable};
-use rustc_middle::ty::{self, ir::TypeVisitor, Ty, TyCtxt};
+use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
+use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
 use rustc_span::DUMMY_SP;
 
 use std::ops::ControlFlow;
@@ -32,7 +32,7 @@ pub trait QueryNormalizeExt<'tcx> {
     /// use [`TyCtxt::normalize_erasing_regions`], which wraps this procedure.
     fn query_normalize<T>(&self, value: T) -> Result<Normalized<'tcx, T>, NoSolution>
     where
-        T: TypeFoldable<'tcx>;
+        T: TypeFoldable<TyCtxt<'tcx>>;
 }
 
 impl<'cx, 'tcx> QueryNormalizeExt<'tcx> for At<'cx, 'tcx> {
@@ -51,7 +51,7 @@ impl<'cx, 'tcx> QueryNormalizeExt<'tcx> for At<'cx, 'tcx> {
     /// and other details are still "under development".
     fn query_normalize<T>(&self, value: T) -> Result<Normalized<'tcx, T>, NoSolution>
     where
-        T: TypeFoldable<'tcx>,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         debug!(
             "normalize::<{}>(value={:?}, param_env={:?}, cause={:?})",
@@ -116,7 +116,7 @@ struct MaxEscapingBoundVarVisitor {
 }
 
 impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxEscapingBoundVarVisitor {
-    fn visit_binder<T: TypeVisitable<'tcx>>(
+    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
         &mut self,
         t: &ty::Binder<'tcx, T>,
     ) -> ControlFlow<Self::BreakTy> {
@@ -177,7 +177,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
         self.infcx.tcx
     }
 
-    fn try_fold_binder<T: TypeFoldable<'tcx>>(
+    fn try_fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
         &mut self,
         t: ty::Binder<'tcx, T>,
     ) -> Result<ty::Binder<'tcx, T>, Self::Error> {
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
index 97002b461aa..9e8bc8bce9a 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
@@ -54,8 +54,8 @@ pub struct TypeOpOutput<'tcx, Op: TypeOp<'tcx>> {
 /// which produces the resulting query region constraints.
 ///
 /// [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html
-pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<'tcx> + 'tcx {
-    type QueryResponse: TypeFoldable<'tcx>;
+pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<TyCtxt<'tcx>> + 'tcx {
+    type QueryResponse: TypeFoldable<TyCtxt<'tcx>>;
 
     /// Give query the option for a simple fast path that never
     /// actually hits the tcx cache lookup etc. Return `Some(r)` with
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs
index 8f0b4de31e6..5b216c07692 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs
@@ -1,7 +1,7 @@
 use crate::infer::canonical::{Canonical, CanonicalQueryResponse};
 use crate::traits::query::Fallible;
 use rustc_middle::ty::fold::TypeFoldable;
-use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt};
+use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt};
 use std::fmt;
 
 pub use rustc_middle::traits::query::type_op::Normalize;
@@ -24,7 +24,7 @@ where
     }
 }
 
-pub trait Normalizable<'tcx>: fmt::Debug + TypeFoldable<'tcx> + Lift<'tcx> + Copy {
+pub trait Normalizable<'tcx>: fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<'tcx> + Copy {
     fn type_op_method(
         tcx: TyCtxt<'tcx>,
         canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index dae602908a3..4ad13dcb645 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -9,7 +9,7 @@ use hir::LangItem;
 use rustc_hir as hir;
 use rustc_infer::traits::ObligationCause;
 use rustc_infer::traits::{Obligation, SelectionError, TraitObligation};
-use rustc_middle::ty::{self, Ty, TypeVisitable};
+use rustc_middle::ty::{self, Ty, TypeVisitableExt};
 use rustc_target::spec::abi::Abi;
 
 use crate::traits;
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index e4a832e4728..21c158fd0fd 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -12,7 +12,7 @@ use rustc_infer::infer::InferOk;
 use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
 use rustc_middle::ty::{
     self, Binder, GenericParamDefKind, InternalSubsts, SubstsRef, ToPolyTraitRef, ToPredicate,
-    TraitRef, Ty, TyCtxt, TypeVisitable,
+    TraitRef, Ty, TyCtxt, TypeVisitableExt,
 };
 use rustc_session::config::TraitSolver;
 use rustc_span::def_id::DefId;
@@ -564,8 +564,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                 .into()
                             }
                         });
-                        let bound_vars = tcx.intern_bound_variable_kinds(&bound_vars);
-                        let assoc_ty_substs = tcx.intern_substs(&substs);
+                        let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars);
+                        let assoc_ty_substs = tcx.mk_substs(&substs);
                         let bound =
                             bound.map_bound(|b| b.kind().skip_binder()).subst(tcx, assoc_ty_substs);
                         tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars))
@@ -821,6 +821,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         self.infcx
             .at(&obligation.cause, obligation.param_env)
+            // needed for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs
+            .define_opaque_types(true)
             .sup(obligation_trait_ref, expected_trait_ref)
             .map(|InferOk { mut obligations, .. }| {
                 obligations.extend(nested);
@@ -878,7 +880,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                             .map(ty::ExistentialPredicate::AutoTrait)
                             .map(ty::Binder::dummy),
                     );
-                let existential_predicates = tcx.mk_poly_existential_predicates(iter);
+                let existential_predicates = tcx.mk_poly_existential_predicates_from_iter(iter);
                 let source_trait = tcx.mk_dynamic(existential_predicates, r_b, repr_a);
 
                 // Require that the traits involved in this upcast are **equal**;
@@ -977,7 +979,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                             .map(ty::ExistentialPredicate::AutoTrait)
                             .map(ty::Binder::dummy),
                     );
-                let existential_predicates = tcx.mk_poly_existential_predicates(iter);
+                let existential_predicates = tcx.mk_poly_existential_predicates_from_iter(iter);
                 let source_trait = tcx.mk_dynamic(existential_predicates, r_b, dyn_a);
 
                 // Require that the traits involved in this upcast are **equal**;
@@ -1097,7 +1099,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
                 // Check that the source struct with the target's
                 // unsizing parameters is equal to the target.
-                let substs = tcx.mk_substs(substs_a.iter().enumerate().map(|(i, k)| {
+                let substs = tcx.mk_substs_from_iter(substs_a.iter().enumerate().map(|(i, k)| {
                     if unsizing_params.contains(i as u32) { substs_b[i] } else { k }
                 }));
                 let new_struct = tcx.mk_adt(def, substs);
@@ -1129,7 +1131,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
                 // Check that the source tuple with the target's
                 // last element is equal to the target.
-                let new_tuple = tcx.mk_tup(a_mid.iter().copied().chain(iter::once(b_last)));
+                let new_tuple =
+                    tcx.mk_tup_from_iter(a_mid.iter().copied().chain(iter::once(b_last)));
                 let InferOk { obligations, .. } = self
                     .infcx
                     .at(&obligation.cause, obligation.param_env)
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 4b15dd408b3..01c1ad3a4ce 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -49,7 +49,7 @@ use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::relate::TypeRelation;
 use rustc_middle::ty::SubstsRef;
 use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate};
-use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable};
+use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
 use rustc_session::config::TraitSolver;
 use rustc_span::symbol::sym;
 
@@ -1406,7 +1406,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     /// The weird return type of this function allows it to be used with the `try` (`?`)
     /// operator within certain functions.
     #[inline(always)]
-    fn check_recursion_limit<T: Display + TypeFoldable<'tcx>, V>(
+    fn check_recursion_limit<T: Display + TypeFoldable<TyCtxt<'tcx>>, V>(
         &self,
         obligation: &Obligation<'tcx, T>,
         error_obligation: &Obligation<'tcx, V>,
@@ -1752,7 +1752,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         });
         self.infcx
             .at(&obligation.cause, obligation.param_env)
-            .define_opaque_types(false)
             .sup(ty::Binder::dummy(placeholder_trait_ref), trait_bound)
             .map(|InferOk { obligations: _, value: () }| {
                 // This method is called within a probe, so we can't have
@@ -1815,7 +1814,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let is_match = self
             .infcx
             .at(&obligation.cause, obligation.param_env)
-            .define_opaque_types(false)
             .sup(obligation.predicate, infer_projection)
             .map_or(false, |InferOk { obligations, value: () }| {
                 self.evaluate_predicates_recursively(
@@ -2232,7 +2230,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     }
                 }
                 // (*) binder moved here
-                let all_vars = self.tcx().mk_bound_variable_kinds(
+                let all_vars = self.tcx().mk_bound_variable_kinds_from_iter(
                     obligation.predicate.bound_vars().iter().chain(binder.bound_vars().iter()),
                 );
                 Where(ty::Binder::bind_with_vars(witness_tys.to_vec(), all_vars))
@@ -2302,12 +2300,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             | ty::Float(_)
             | ty::FnDef(..)
             | ty::FnPtr(_)
-            | ty::Str
             | ty::Error(_)
             | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
             | ty::Never
             | ty::Char => ty::Binder::dummy(Vec::new()),
 
+            // Treat this like `struct str([u8]);`
+            ty::Str => ty::Binder::dummy(vec![self.tcx().mk_slice(self.tcx().types.u8)]),
+
             ty::Placeholder(..)
             | ty::Dynamic(..)
             | ty::Param(..)
@@ -2445,7 +2445,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 // the placeholder trait ref may fail due the Generalizer relation
                 // raising a CyclicalTy error due to a sub_root_var relation
                 // for a variable being generalized...
-                self.infcx.tcx.sess.delay_span_bug(
+                let guar = self.infcx.tcx.sess.delay_span_bug(
                     obligation.cause.span,
                     &format!(
                         "Impl {:?} was matchable against {:?} but now is not",
@@ -2453,7 +2453,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     ),
                 );
                 let value = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id);
-                let err = self.tcx().ty_error();
+                let err = self.tcx().ty_error(guar);
                 let value = value.fold_with(&mut BottomUpFolder {
                     tcx: self.tcx(),
                     ty_op: |_| err,
@@ -2507,7 +2507,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let InferOk { obligations, .. } = self
             .infcx
             .at(&cause, obligation.param_env)
-            .define_opaque_types(false)
             .eq(placeholder_obligation_trait_ref, impl_trait_ref)
             .map_err(|e| {
                 debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx()))
@@ -2558,11 +2557,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     ) -> Result<Vec<PredicateObligation<'tcx>>, ()> {
         self.infcx
             .at(&obligation.cause, obligation.param_env)
-            // We don't want predicates for opaque types to just match all other types,
-            // if there is an obligation on the opaque type, then that obligation must be met
-            // opaquely. Otherwise we'd match any obligation to the opaque type and then error
-            // out later.
-            .define_opaque_types(false)
             .sup(obligation.predicate.to_poly_trait_ref(), poly_trait_ref)
             .map(|InferOk { obligations, .. }| obligations)
             .map_err(|_| ())
@@ -3042,7 +3036,7 @@ fn bind_generator_hidden_types_above<'tcx>(
     if considering_regions {
         debug_assert!(!hidden_types.has_erased_regions());
     }
-    let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.iter().chain(
+    let bound_vars = tcx.mk_bound_variable_kinds_from_iter(bound_vars.iter().chain(
         (num_bound_variables..counter).map(|i| ty::BoundVariableKind::Region(ty::BrAnon(i, None))),
     ));
     ty::Binder::bind_with_vars(hidden_types, bound_vars)
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
index 2e4a5cfe4bc..61ed9ef2ec1 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
@@ -4,7 +4,7 @@ use crate::traits;
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
-use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
 
 pub use rustc_middle::traits::specialization_graph::*;
 
diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs
index 32dd8f25b44..e38ae9381c1 100644
--- a/compiler/rustc_trait_selection/src/traits/structural_match.rs
+++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs
@@ -1,8 +1,6 @@
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
-#[cfg(not(bootstrap))]
-use rustc_middle::ty::TypeVisitable;
-use rustc_middle::ty::{self, ir::TypeVisitor, Ty, TyCtxt, TypeSuperVisitable};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
 use rustc_span::Span;
 use std::ops::ControlFlow;
 
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index b5df583e3f4..bcf63d5a6f6 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -4,7 +4,7 @@ use smallvec::SmallVec;
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def_id::DefId;
-use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitableExt};
 use rustc_middle::ty::{GenericArg, SubstsRef};
 
 use super::NormalizeExt;
@@ -239,7 +239,7 @@ pub fn predicate_for_trait_def<'tcx>(
     cause: ObligationCause<'tcx>,
     trait_def_id: DefId,
     recursion_depth: usize,
-    params: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
+    params: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
 ) -> PredicateObligation<'tcx> {
     let trait_ref = tcx.mk_trait_ref(trait_def_id, params);
     predicate_for_trait_ref(tcx, cause, param_env, trait_ref, recursion_depth)
@@ -292,7 +292,7 @@ pub fn closure_trait_ref_and_return_type<'tcx>(
     assert!(!self_ty.has_escaping_bound_vars());
     let arguments_tuple = match tuple_arguments {
         TupleArgumentsFlag::No => sig.skip_binder().inputs()[0],
-        TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()),
+        TupleArgumentsFlag::Yes => tcx.mk_tup(sig.skip_binder().inputs()),
     };
     let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty, arguments_tuple]);
     sig.map_bound(|sig| (trait_ref, sig.output()))
diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs
index 9f5c5bbeac8..a4e9928f8b2 100644
--- a/compiler/rustc_trait_selection/src/traits/vtable.rs
+++ b/compiler/rustc_trait_selection/src/traits/vtable.rs
@@ -4,7 +4,7 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
 use rustc_infer::traits::util::PredicateSet;
 use rustc_infer::traits::ImplSource;
-use rustc_middle::ty::visit::TypeVisitable;
+use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::InternalSubsts;
 use rustc_middle::ty::{self, GenericParamDefKind, ToPredicate, Ty, TyCtxt, VtblEntry};
 use rustc_span::{sym, Span};
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 6a881c233db..d498af359c5 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -3,7 +3,7 @@ use crate::traits;
 use rustc_hir as hir;
 use rustc_hir::lang_items::LangItem;
 use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
 use rustc_span::{Span, DUMMY_SP};
 
diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs
index e2b5d17e073..f8c8f744e6d 100644
--- a/compiler/rustc_traits/src/chalk/db.rs
+++ b/compiler/rustc_traits/src/chalk/db.rs
@@ -769,12 +769,12 @@ struct ReplaceOpaqueTyFolder<'tcx> {
     binder_index: ty::DebruijnIndex,
 }
 
-impl<'tcx> ty::ir::TypeFolder<TyCtxt<'tcx>> for ReplaceOpaqueTyFolder<'tcx> {
+impl<'tcx> ty::TypeFolder<TyCtxt<'tcx>> for ReplaceOpaqueTyFolder<'tcx> {
     fn interner(&self) -> TyCtxt<'tcx> {
         self.tcx
     }
 
-    fn fold_binder<T: TypeFoldable<'tcx>>(
+    fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
         &mut self,
         t: ty::Binder<'tcx, T>,
     ) -> ty::Binder<'tcx, T> {
diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs
index 7635f4bfec3..60e22d1001c 100644
--- a/compiler/rustc_traits/src/chalk/lowering.rs
+++ b/compiler/rustc_traits/src/chalk/lowering.rs
@@ -35,9 +35,8 @@ use rustc_ast::ast;
 use rustc_middle::traits::{ChalkEnvironmentAndGoal, ChalkRustInterner as RustInterner};
 use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
 use rustc_middle::ty::{
-    self,
-    ir::{TypeFolder, TypeVisitor},
-    Binder, Region, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable,
+    self, Binder, Region, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
+    TypeSuperVisitable, TypeVisitable, TypeVisitor,
 };
 use rustc_span::def_id::DefId;
 
@@ -63,7 +62,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Substitution<RustInterner<'tcx>>> for Subst
 
 impl<'tcx> LowerInto<'tcx, SubstsRef<'tcx>> for &chalk_ir::Substitution<RustInterner<'tcx>> {
     fn lower_into(self, interner: RustInterner<'tcx>) -> SubstsRef<'tcx> {
-        interner.tcx.mk_substs(self.iter(interner).map(|subst| subst.lower_into(interner)))
+        interner
+            .tcx
+            .mk_substs_from_iter(self.iter(interner).map(|subst| subst.lower_into(interner)))
     }
 }
 
@@ -456,7 +457,7 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty<RustInterner<'tcx>> {
                 interner.tcx.mk_alias_ty(assoc_ty.0, substitution.lower_into(interner)),
             ),
             TyKind::Foreign(def_id) => ty::Foreign(def_id.0),
-            TyKind::Error => return interner.tcx.ty_error(),
+            TyKind::Error => return interner.tcx.ty_error_misc(),
             TyKind::Alias(alias_ty) => match alias_ty {
                 chalk_ir::AliasTy::Projection(projection) => ty::Alias(
                     ty::Projection,
@@ -488,7 +489,7 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty<RustInterner<'tcx>> {
             TyKind::InferenceVar(_, _) => unimplemented!(),
             TyKind::Dyn(_) => unimplemented!(),
         };
-        interner.tcx.mk_ty(kind)
+        interner.tcx.mk_ty_from_kind(kind)
     }
 }
 
@@ -880,7 +881,7 @@ impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::AliasEqBound<RustInterner<'tcx>
 /// It's important to note that because of prior substitution, we may have
 /// late-bound regions, even outside of fn contexts, since this is the best way
 /// to prep types for chalk lowering.
-pub(crate) fn collect_bound_vars<'tcx, T: TypeFoldable<'tcx>>(
+pub(crate) fn collect_bound_vars<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
     interner: RustInterner<'tcx>,
     tcx: TyCtxt<'tcx>,
     ty: Binder<'tcx, T>,
@@ -931,7 +932,7 @@ impl<'tcx> BoundVarsCollector<'tcx> {
 }
 
 impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for BoundVarsCollector<'tcx> {
-    fn visit_binder<T: TypeVisitable<'tcx>>(
+    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
         &mut self,
         t: &Binder<'tcx, T>,
     ) -> ControlFlow<Self::BreakTy> {
@@ -1016,7 +1017,10 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for NamedBoundVarSubstitutor<'a, 'tcx> {
         self.tcx
     }
 
-    fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> {
+    fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
+        &mut self,
+        t: Binder<'tcx, T>,
+    ) -> Binder<'tcx, T> {
         self.binder_index.shift_in(1);
         let result = t.super_fold_with(self);
         self.binder_index.shift_out(1);
@@ -1072,7 +1076,10 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ParamsSubstitutor<'tcx> {
         self.tcx
     }
 
-    fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> {
+    fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
+        &mut self,
+        t: Binder<'tcx, T>,
+    ) -> Binder<'tcx, T> {
         self.binder_index.shift_in(1);
         let result = t.super_fold_with(self);
         self.binder_index.shift_out(1);
diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs
index f33f9edd627..a5ebc26a8bc 100644
--- a/compiler/rustc_traits/src/chalk/mod.rs
+++ b/compiler/rustc_traits/src/chalk/mod.rs
@@ -9,7 +9,7 @@ pub(crate) mod lowering;
 use rustc_middle::infer::canonical::{CanonicalTyVarKind, CanonicalVarKind};
 use rustc_middle::traits::ChalkRustInterner;
 use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
+use rustc_middle::ty::{self, TyCtxt, TypeFoldable, TypeVisitable};
 
 use rustc_infer::infer::canonical::{
     Canonical, CanonicalVarValues, Certainty, QueryRegionConstraints, QueryResponse,
@@ -96,37 +96,34 @@ pub(crate) fn evaluate_goal<'tcx>(
         use rustc_middle::infer::canonical::CanonicalVarInfo;
 
         let mut reverse_param_substitutor = ReverseParamsSubstitutor::new(tcx, params);
-        let var_values = tcx.mk_substs(
+        let var_values = tcx.mk_substs_from_iter(
             subst
                 .as_slice(interner)
                 .iter()
                 .map(|p| p.lower_into(interner).fold_with(&mut reverse_param_substitutor)),
         );
-        let variables: Vec<_> = binders
-            .iter(interner)
-            .map(|var| {
-                let kind = match var.kind {
-                    chalk_ir::VariableKind::Ty(ty_kind) => CanonicalVarKind::Ty(match ty_kind {
-                        chalk_ir::TyVariableKind::General => CanonicalTyVarKind::General(
-                            ty::UniverseIndex::from_usize(var.skip_kind().counter),
-                        ),
-                        chalk_ir::TyVariableKind::Integer => CanonicalTyVarKind::Int,
-                        chalk_ir::TyVariableKind::Float => CanonicalTyVarKind::Float,
-                    }),
-                    chalk_ir::VariableKind::Lifetime => CanonicalVarKind::Region(
+        let variables = binders.iter(interner).map(|var| {
+            let kind = match var.kind {
+                chalk_ir::VariableKind::Ty(ty_kind) => CanonicalVarKind::Ty(match ty_kind {
+                    chalk_ir::TyVariableKind::General => CanonicalTyVarKind::General(
                         ty::UniverseIndex::from_usize(var.skip_kind().counter),
                     ),
-                    // FIXME(compiler-errors): We don't currently have a way of turning
-                    // a Chalk ty back into a rustc ty, right?
-                    chalk_ir::VariableKind::Const(_) => todo!(),
-                };
-                CanonicalVarInfo { kind }
-            })
-            .collect();
+                    chalk_ir::TyVariableKind::Integer => CanonicalTyVarKind::Int,
+                    chalk_ir::TyVariableKind::Float => CanonicalTyVarKind::Float,
+                }),
+                chalk_ir::VariableKind::Lifetime => {
+                    CanonicalVarKind::Region(ty::UniverseIndex::from_usize(var.skip_kind().counter))
+                }
+                // FIXME(compiler-errors): We don't currently have a way of turning
+                // a Chalk ty back into a rustc ty, right?
+                chalk_ir::VariableKind::Const(_) => todo!(),
+            };
+            CanonicalVarInfo { kind }
+        });
         let max_universe = binders.iter(interner).map(|v| v.skip_kind().counter).max().unwrap_or(0);
         let sol = Canonical {
             max_universe: ty::UniverseIndex::from_usize(max_universe),
-            variables: tcx.intern_canonical_var_infos(&variables),
+            variables: tcx.mk_canonical_var_infos_from_iter(variables),
             value: QueryResponse {
                 var_values: CanonicalVarValues { var_values },
                 region_constraints: QueryRegionConstraints::default(),
diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs
index abf0c1c5f3e..ddd4ca1436c 100644
--- a/compiler/rustc_traits/src/implied_outlives_bounds.rs
+++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs
@@ -7,7 +7,7 @@ use rustc_infer::infer::outlives::components::{push_outlives_components, Compone
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::query::OutlivesBound;
 use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 use rustc_span::def_id::CRATE_DEF_ID;
 use rustc_span::source_map::DUMMY_SP;
 use rustc_trait_selection::infer::InferCtxtBuilderExt;
diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs
index 2c18a034050..f0597f19225 100644
--- a/compiler/rustc_traits/src/normalize_erasing_regions.rs
+++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs
@@ -1,7 +1,7 @@
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt, TypeFoldable};
+use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt, TypeFoldable, TypeVisitableExt};
 use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
 use rustc_trait_selection::traits::{Normalized, ObligationCause};
 use std::sync::atomic::Ordering;
@@ -22,7 +22,7 @@ pub(crate) fn provide(p: &mut Providers) {
     };
 }
 
-fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq + Copy>(
+fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<TyCtxt<'tcx>> + PartialEq + Copy>(
     tcx: TyCtxt<'tcx>,
     goal: ParamEnvAnd<'tcx, T>,
 ) -> Result<T, NoSolution> {
diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs
index d34fce64dd7..e0fd487b3d3 100644
--- a/compiler/rustc_traits/src/type_op.rs
+++ b/compiler/rustc_traits/src/type_op.rs
@@ -161,7 +161,7 @@ fn type_op_normalize<'tcx, T>(
     key: ParamEnvAnd<'tcx, Normalize<T>>,
 ) -> Fallible<T>
 where
-    T: fmt::Debug + TypeFoldable<'tcx> + Lift<'tcx>,
+    T: fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<'tcx>,
 {
     let (param_env, Normalize { value }) = key.into_parts();
     let Normalized { value, obligations } =
diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs
index b3b9a67b26e..4b4a8ebd079 100644
--- a/compiler/rustc_transmute/src/lib.rs
+++ b/compiler/rustc_transmute/src/lib.rs
@@ -117,7 +117,7 @@ mod rustc {
             c: Const<'tcx>,
         ) -> Option<Self> {
             use rustc_middle::ty::ScalarInt;
-            use rustc_middle::ty::TypeVisitable;
+            use rustc_middle::ty::TypeVisitableExt;
             use rustc_span::symbol::sym;
 
             let c = c.eval(tcx, param_env);
diff --git a/compiler/rustc_error_messages/locales/en-US/ty_utils.ftl b/compiler/rustc_ty_utils/locales/en-US.ftl
index abe65a0e3fe..abe65a0e3fe 100644
--- a/compiler/rustc_error_messages/locales/en-US/ty_utils.ftl
+++ b/compiler/rustc_ty_utils/locales/en-US.ftl
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index 41924dc2a6d..35c9f95eb03 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -54,7 +54,7 @@ fn fn_sig_for_fn_abi<'tcx>(
                 sig = sig.map_bound(|mut sig| {
                     let mut inputs_and_output = sig.inputs_and_output.to_vec();
                     inputs_and_output[0] = tcx.mk_mut_ptr(inputs_and_output[0]);
-                    sig.inputs_and_output = tcx.intern_type_list(&inputs_and_output);
+                    sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
                     sig
                 });
             }
@@ -63,7 +63,7 @@ fn fn_sig_for_fn_abi<'tcx>(
         ty::Closure(def_id, substs) => {
             let sig = substs.as_closure().sig();
 
-            let bound_vars = tcx.mk_bound_variable_kinds(
+            let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
                 sig.bound_vars().iter().chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))),
             );
             let br = ty::BoundRegion {
@@ -88,7 +88,7 @@ fn fn_sig_for_fn_abi<'tcx>(
         ty::Generator(did, substs, _) => {
             let sig = substs.as_generator().poly_sig();
 
-            let bound_vars = tcx.mk_bound_variable_kinds(
+            let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
                 sig.bound_vars().iter().chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))),
             );
             let br = ty::BoundRegion {
@@ -99,7 +99,7 @@ fn fn_sig_for_fn_abi<'tcx>(
 
             let pin_did = tcx.require_lang_item(LangItem::Pin, None);
             let pin_adt_ref = tcx.adt_def(pin_did);
-            let pin_substs = tcx.intern_substs(&[env_ty.into()]);
+            let pin_substs = tcx.mk_substs(&[env_ty.into()]);
             let env_ty = tcx.mk_adt(pin_adt_ref, pin_substs);
 
             let sig = sig.skip_binder();
@@ -111,7 +111,7 @@ fn fn_sig_for_fn_abi<'tcx>(
                 // The signature should be `Future::poll(_, &mut Context<'_>) -> Poll<Output>`
                 let poll_did = tcx.require_lang_item(LangItem::Poll, None);
                 let poll_adt_ref = tcx.adt_def(poll_did);
-                let poll_substs = tcx.intern_substs(&[sig.return_ty.into()]);
+                let poll_substs = tcx.mk_substs(&[sig.return_ty.into()]);
                 let ret_ty = tcx.mk_adt(poll_adt_ref, poll_substs);
 
                 // We have to replace the `ResumeTy` that is used for type and borrow checking
@@ -133,7 +133,7 @@ fn fn_sig_for_fn_abi<'tcx>(
                 // The signature should be `Generator::resume(_, Resume) -> GeneratorState<Yield, Return>`
                 let state_did = tcx.require_lang_item(LangItem::GeneratorState, None);
                 let state_adt_ref = tcx.adt_def(state_did);
-                let state_substs = tcx.intern_substs(&[sig.yield_ty.into(), sig.return_ty.into()]);
+                let state_substs = tcx.mk_substs(&[sig.yield_ty.into(), sig.return_ty.into()]);
                 let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
 
                 (sig.resume_ty, ret_ty)
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index 164cac6a010..d4866b5dbdd 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -1,13 +1,18 @@
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::definitions::DefPathData;
+use rustc_hir::intravisit::{self, Visitor};
+use rustc_middle::ty::{self, DefIdTree, TyCtxt};
 
 pub fn provide(providers: &mut ty::query::Providers) {
     *providers = ty::query::Providers {
         associated_item,
         associated_item_def_ids,
         associated_items,
+        associated_items_for_impl_trait_in_trait,
+        associated_item_for_impl_trait_in_trait,
         impl_item_implementor_ids,
         ..*providers
     };
@@ -112,3 +117,97 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A
         fn_has_self_parameter: has_self,
     }
 }
+
+/// Given an `fn_def_id` of a trait or of an impl that implements a given trait:
+/// if `fn_def_id` is the def id of a function defined inside a trait, then it creates and returns
+/// the associated items that correspond to each impl trait in return position for that trait.
+/// if `fn_def_id` is the def id of a function defined inside an impl that implements a trait, then it
+/// creates and returns the associated items that correspond to each impl trait in return position
+/// of the implemented trait.
+fn associated_items_for_impl_trait_in_trait(tcx: TyCtxt<'_>, fn_def_id: DefId) -> &'_ [DefId] {
+    let parent_def_id = tcx.parent(fn_def_id);
+
+    match tcx.def_kind(parent_def_id) {
+        DefKind::Trait => {
+            struct RPITVisitor {
+                rpits: Vec<LocalDefId>,
+            }
+
+            impl<'v> Visitor<'v> for RPITVisitor {
+                fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
+                    if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind {
+                        self.rpits.push(item_id.owner_id.def_id)
+                    }
+                    intravisit::walk_ty(self, ty)
+                }
+            }
+
+            let mut visitor = RPITVisitor { rpits: Vec::new() };
+
+            if let Some(output) = tcx.hir().get_fn_output(fn_def_id.expect_local()) {
+                visitor.visit_fn_ret_ty(output);
+
+                tcx.arena.alloc_from_iter(visitor.rpits.iter().map(|opaque_ty_def_id| {
+                    tcx.associated_item_for_impl_trait_in_trait(opaque_ty_def_id).to_def_id()
+                }))
+            } else {
+                &[]
+            }
+        }
+
+        DefKind::Impl { .. } => {
+            let Some(trait_fn_def_id) = tcx.associated_item(fn_def_id).trait_item_def_id else { return &[] };
+
+            tcx.arena.alloc_from_iter(
+                tcx.associated_items_for_impl_trait_in_trait(trait_fn_def_id).iter().map(
+                    move |trait_assoc_def_id| {
+                        impl_associated_item_for_impl_trait_in_trait(
+                            tcx,
+                            trait_assoc_def_id.expect_local(),
+                            fn_def_id.expect_local(),
+                        )
+                        .to_def_id()
+                    },
+                ),
+            )
+        }
+
+        def_kind => bug!(
+            "associated_items_for_impl_trait_in_trait: {:?} should be Trait or Impl but is {:?}",
+            parent_def_id,
+            def_kind
+        ),
+    }
+}
+
+/// Given an `opaque_ty_def_id` corresponding to an impl trait in trait, create and return the
+/// corresponding associated item.
+fn associated_item_for_impl_trait_in_trait(
+    tcx: TyCtxt<'_>,
+    opaque_ty_def_id: LocalDefId,
+) -> LocalDefId {
+    let fn_def_id = tcx.impl_trait_in_trait_parent(opaque_ty_def_id.to_def_id());
+    let trait_def_id = tcx.parent(fn_def_id);
+    assert_eq!(tcx.def_kind(trait_def_id), DefKind::Trait);
+
+    let span = tcx.def_span(opaque_ty_def_id);
+    let trait_assoc_ty =
+        tcx.at(span).create_def(trait_def_id.expect_local(), DefPathData::ImplTraitAssocTy);
+    trait_assoc_ty.def_id()
+}
+
+/// Given an `trait_assoc_def_id` that corresponds to a previously synthethized impl trait in trait
+/// into an associated type and an `impl_def_id` corresponding to an impl block, create and return
+/// the corresponding associated item inside the impl block.
+fn impl_associated_item_for_impl_trait_in_trait(
+    tcx: TyCtxt<'_>,
+    trait_assoc_def_id: LocalDefId,
+    impl_fn_def_id: LocalDefId,
+) -> LocalDefId {
+    let impl_def_id = tcx.local_parent(impl_fn_def_id);
+
+    let span = tcx.def_span(trait_assoc_def_id);
+    let impl_assoc_ty = tcx.at(span).create_def(impl_def_id, DefPathData::ImplTraitAssocTy);
+
+    impl_assoc_ty.def_id()
+}
diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs
index 852156c24f4..f2635271609 100644
--- a/compiler/rustc_ty_utils/src/consts.rs
+++ b/compiler/rustc_ty_utils/src/consts.rs
@@ -5,7 +5,7 @@ use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
 use rustc_middle::thir::visit;
 use rustc_middle::thir::visit::Visitor;
 use rustc_middle::ty::abstract_const::CastKind;
-use rustc_middle::ty::{self, Expr, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, Expr, TyCtxt, TypeVisitableExt};
 use rustc_middle::{mir, thir};
 use rustc_span::Span;
 use rustc_target::abi::VariantIdx;
@@ -144,7 +144,7 @@ fn recurse_build<'tcx>(
             for &id in args.iter() {
                 new_args.push(recurse_build(tcx, body, id, root_span)?);
             }
-            let new_args = tcx.intern_const_list(&new_args);
+            let new_args = tcx.mk_const_list(&new_args);
             tcx.mk_const(Expr::FunctionCall(fun, new_args), node.ty)
         }
         &ExprKind::Binary { op, lhs, rhs } if check_binop(op) => {
diff --git a/compiler/rustc_ty_utils/src/errors.rs b/compiler/rustc_ty_utils/src/errors.rs
index c05eeb353a8..ab3e62f0484 100644
--- a/compiler/rustc_ty_utils/src/errors.rs
+++ b/compiler/rustc_ty_utils/src/errors.rs
@@ -16,7 +16,7 @@ pub struct NeedsDropOverflow<'tcx> {
 pub struct GenericConstantTooComplex {
     #[primary_span]
     pub span: Span,
-    #[note(maybe_supported)]
+    #[note(ty_utils_maybe_supported)]
     pub maybe_supported: Option<()>,
     #[subdiagnostic]
     pub sub: GenericConstantTooComplexSub,
diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs
index eb307e66e34..7fecee2a38b 100644
--- a/compiler/rustc_ty_utils/src/implied_bounds.rs
+++ b/compiler/rustc_ty_utils/src/implied_bounds.rs
@@ -19,16 +19,16 @@ fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Ty<'_>> {
             let mut assumed_wf_types: Vec<_> =
                 tcx.assumed_wf_types(tcx.parent(def_id)).as_slice().into();
             assumed_wf_types.extend(liberated_sig.inputs_and_output);
-            tcx.intern_type_list(&assumed_wf_types)
+            tcx.mk_type_list(&assumed_wf_types)
         }
         DefKind::Impl { .. } => {
             match tcx.impl_trait_ref(def_id) {
                 Some(trait_ref) => {
                     let types: Vec<_> = trait_ref.skip_binder().substs.types().collect();
-                    tcx.intern_type_list(&types)
+                    tcx.mk_type_list(&types)
                 }
                 // Only the impl self type
-                None => tcx.intern_type_list(&[tcx.type_of(def_id).subst_identity()]),
+                None => tcx.mk_type_list(&[tcx.type_of(def_id).subst_identity()]),
             }
         }
         DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)),
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index de7230b0cfa..2eaeca73da7 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -3,7 +3,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::traits::CodegenObligationError;
 use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::{self, Instance, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, Instance, TyCtxt, TypeVisitableExt};
 use rustc_span::sym;
 use rustc_trait_selection::traits;
 use traits::{translate_substs, Reveal};
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 1a62794b0b4..e3132fcc4c4 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -7,7 +7,7 @@ use rustc_middle::ty::layout::{
     IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, MAX_SIMD_LANES,
 };
 use rustc_middle::ty::{
-    self, subst::SubstsRef, AdtDef, EarlyBinder, ReprOptions, Ty, TyCtxt, TypeVisitable,
+    self, subst::SubstsRef, AdtDef, EarlyBinder, ReprOptions, Ty, TyCtxt, TypeVisitableExt,
 };
 use rustc_session::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo};
 use rustc_span::symbol::Symbol;
@@ -104,23 +104,23 @@ fn layout_of_uncached<'tcx>(
         assert!(size.bits() <= 128);
         Scalar::Initialized { value, valid_range: WrappingRange::full(size) }
     };
-    let scalar = |value: Primitive| tcx.intern_layout(LayoutS::scalar(cx, scalar_unit(value)));
+    let scalar = |value: Primitive| tcx.mk_layout(LayoutS::scalar(cx, scalar_unit(value)));
 
     let univariant = |fields: &[Layout<'_>], repr: &ReprOptions, kind| {
-        Ok(tcx.intern_layout(univariant_uninterned(cx, ty, fields, repr, kind)?))
+        Ok(tcx.mk_layout(univariant_uninterned(cx, ty, fields, repr, kind)?))
     };
     debug_assert!(!ty.has_non_region_infer());
 
     Ok(match *ty.kind() {
         // Basic scalars.
-        ty::Bool => tcx.intern_layout(LayoutS::scalar(
+        ty::Bool => tcx.mk_layout(LayoutS::scalar(
             cx,
             Scalar::Initialized {
                 value: Int(I8, false),
                 valid_range: WrappingRange { start: 0, end: 1 },
             },
         )),
-        ty::Char => tcx.intern_layout(LayoutS::scalar(
+        ty::Char => tcx.mk_layout(LayoutS::scalar(
             cx,
             Scalar::Initialized {
                 value: Int(I32, false),
@@ -136,11 +136,11 @@ fn layout_of_uncached<'tcx>(
         ty::FnPtr(_) => {
             let mut ptr = scalar_unit(Pointer(dl.instruction_address_space));
             ptr.valid_range_mut().start = 1;
-            tcx.intern_layout(LayoutS::scalar(cx, ptr))
+            tcx.mk_layout(LayoutS::scalar(cx, ptr))
         }
 
         // The never type.
-        ty::Never => tcx.intern_layout(cx.layout_of_never_type()),
+        ty::Never => tcx.mk_layout(cx.layout_of_never_type()),
 
         // Potentially-wide pointers.
         ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
@@ -151,7 +151,7 @@ fn layout_of_uncached<'tcx>(
 
             let pointee = tcx.normalize_erasing_regions(param_env, pointee);
             if pointee.is_sized(tcx, param_env) {
-                return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr)));
+                return Ok(tcx.mk_layout(LayoutS::scalar(cx, data_ptr)));
             }
 
             let unsized_part = tcx.struct_tail_erasing_lifetimes(pointee, param_env);
@@ -164,7 +164,7 @@ fn layout_of_uncached<'tcx>(
                 let metadata_layout = cx.layout_of(metadata_ty)?;
                 // If the metadata is a 1-zst, then the pointer is thin.
                 if metadata_layout.is_zst() && metadata_layout.align.abi.bytes() == 1 {
-                    return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr)));
+                    return Ok(tcx.mk_layout(LayoutS::scalar(cx, data_ptr)));
                 }
 
                 let Abi::Scalar(metadata) = metadata_layout.abi else {
@@ -174,7 +174,7 @@ fn layout_of_uncached<'tcx>(
             } else {
                 match unsized_part.kind() {
                     ty::Foreign(..) => {
-                        return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr)));
+                        return Ok(tcx.mk_layout(LayoutS::scalar(cx, data_ptr)));
                     }
                     ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)),
                     ty::Dynamic(..) => {
@@ -189,7 +189,7 @@ fn layout_of_uncached<'tcx>(
             };
 
             // Effectively a (ptr, meta) tuple.
-            tcx.intern_layout(cx.scalar_pair(data_ptr, metadata))
+            tcx.mk_layout(cx.scalar_pair(data_ptr, metadata))
         }
 
         ty::Dynamic(_, _, ty::DynStar) => {
@@ -197,7 +197,7 @@ fn layout_of_uncached<'tcx>(
             data.valid_range_mut().start = 0;
             let mut vtable = scalar_unit(Pointer(AddressSpace::DATA));
             vtable.valid_range_mut().start = 1;
-            tcx.intern_layout(cx.scalar_pair(data, vtable))
+            tcx.mk_layout(cx.scalar_pair(data, vtable))
         }
 
         // Arrays and slices.
@@ -222,7 +222,7 @@ fn layout_of_uncached<'tcx>(
 
             let largest_niche = if count != 0 { element.largest_niche } else { None };
 
-            tcx.intern_layout(LayoutS {
+            tcx.mk_layout(LayoutS {
                 variants: Variants::Single { index: VariantIdx::new(0) },
                 fields: FieldsShape::Array { stride: element.size, count },
                 abi,
@@ -233,7 +233,7 @@ fn layout_of_uncached<'tcx>(
         }
         ty::Slice(element) => {
             let element = cx.layout_of(element)?;
-            tcx.intern_layout(LayoutS {
+            tcx.mk_layout(LayoutS {
                 variants: Variants::Single { index: VariantIdx::new(0) },
                 fields: FieldsShape::Array { stride: element.size, count: 0 },
                 abi: Abi::Aggregate { sized: false },
@@ -242,7 +242,7 @@ fn layout_of_uncached<'tcx>(
                 size: Size::ZERO,
             })
         }
-        ty::Str => tcx.intern_layout(LayoutS {
+        ty::Str => tcx.mk_layout(LayoutS {
             variants: Variants::Single { index: VariantIdx::new(0) },
             fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 },
             abi: Abi::Aggregate { sized: false },
@@ -265,7 +265,7 @@ fn layout_of_uncached<'tcx>(
                 Abi::Aggregate { ref mut sized } => *sized = false,
                 _ => bug!(),
             }
-            tcx.intern_layout(unit)
+            tcx.mk_layout(unit)
         }
 
         ty::Generator(def_id, substs, _) => generator_layout(cx, ty, def_id, substs)?,
@@ -394,7 +394,7 @@ fn layout_of_uncached<'tcx>(
                 FieldsShape::Array { stride: e_ly.size, count: e_len }
             };
 
-            tcx.intern_layout(LayoutS {
+            tcx.mk_layout(LayoutS {
                 variants: Variants::Single { index: VariantIdx::new(0) },
                 fields,
                 abi: Abi::Vector { element: e_abi, count: e_len },
@@ -427,12 +427,12 @@ fn layout_of_uncached<'tcx>(
                     return Err(LayoutError::Unknown(ty));
                 }
 
-                return Ok(tcx.intern_layout(
+                return Ok(tcx.mk_layout(
                     cx.layout_of_union(&def.repr(), &variants).ok_or(LayoutError::Unknown(ty))?,
                 ));
             }
 
-            tcx.intern_layout(
+            tcx.mk_layout(
                 cx.layout_of_struct_or_enum(
                     &def.repr(),
                     &variants,
@@ -636,7 +636,7 @@ fn generator_layout<'tcx>(
         value: Primitive::Int(discr_int, false),
         valid_range: WrappingRange { start: 0, end: max_discr },
     };
-    let tag_layout = cx.tcx.intern_layout(LayoutS::scalar(cx, tag));
+    let tag_layout = cx.tcx.mk_layout(LayoutS::scalar(cx, tag));
 
     let promoted_layouts = ineligible_locals
         .iter()
@@ -784,7 +784,7 @@ fn generator_layout<'tcx>(
         Abi::Aggregate { sized: true }
     };
 
-    let layout = tcx.intern_layout(LayoutS {
+    let layout = tcx.mk_layout(LayoutS {
         variants: Variants::Multiple {
             tag,
             tag_encoding: TagEncoding::Direct,
diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs
index 0853de601b0..35f468aa952 100644
--- a/compiler/rustc_ty_utils/src/lib.rs
+++ b/compiler/rustc_ty_utils/src/lib.rs
@@ -15,6 +15,8 @@ extern crate rustc_middle;
 #[macro_use]
 extern crate tracing;
 
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_macros::fluent_messages;
 use rustc_middle::ty::query::Providers;
 
 mod abi;
@@ -31,6 +33,8 @@ pub mod representability;
 mod structural_match;
 mod ty;
 
+fluent_messages! { "../locales/en-US.ftl" }
+
 pub fn provide(providers: &mut Providers) {
     abi::provide(providers);
     assoc::provide(providers);
diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs
index c177d60bb59..de7fd003176 100644
--- a/compiler/rustc_ty_utils/src/needs_drop.rs
+++ b/compiler/rustc_ty_utils/src/needs_drop.rs
@@ -303,7 +303,7 @@ fn adt_drop_tys<'tcx>(
         false,
     )
     .collect::<Result<Vec<_>, _>>()
-    .map(|components| tcx.intern_type_list(&components))
+    .map(|components| tcx.mk_type_list(&components))
 }
 // If `def_id` refers to a generic ADT, the queries above and below act as if they had been handed
 // a `tcx.make_ty(def, identity_substs)` and as such it is legal to substitute the generic parameters
@@ -320,7 +320,7 @@ fn adt_significant_drop_tys(
         true,
     )
     .collect::<Result<Vec<_>, _>>()
-    .map(|components| tcx.intern_type_list(&components))
+    .map(|components| tcx.mk_type_list(&components))
 }
 
 pub(crate) fn provide(providers: &mut ty::query::Providers) {
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index f1af0073e4d..18159778a8e 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -2,11 +2,9 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_index::bit_set::BitSet;
-#[cfg(not(bootstrap))]
-use rustc_middle::ty::ir::TypeVisitable;
 use rustc_middle::ty::{
-    self, ir::TypeVisitor, Binder, EarlyBinder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt,
-    TypeSuperVisitable,
+    self, Binder, EarlyBinder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt,
+    TypeSuperVisitable, TypeVisitable, TypeVisitor,
 };
 use rustc_session::config::TraitSolver;
 use rustc_span::def_id::{DefId, CRATE_DEF_ID};
@@ -100,12 +98,12 @@ fn impl_defaultness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Defaultness {
 fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] {
     if let Some(def_id) = def_id.as_local() {
         if matches!(tcx.representability(def_id), ty::Representability::Infinite) {
-            return tcx.intern_type_list(&[tcx.ty_error()]);
+            return tcx.mk_type_list(&[tcx.ty_error_misc()]);
         }
     }
     let def = tcx.adt_def(def_id);
 
-    let result = tcx.mk_type_list(
+    let result = tcx.mk_type_list_from_iter(
         def.variants()
             .iter()
             .flat_map(|v| v.fields.last())
@@ -228,11 +226,8 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
         None => hir::Constness::NotConst,
     };
 
-    let unnormalized_env = ty::ParamEnv::new(
-        tcx.intern_predicates(&predicates),
-        traits::Reveal::UserFacing,
-        constness,
-    );
+    let unnormalized_env =
+        ty::ParamEnv::new(tcx.mk_predicates(&predicates), traits::Reveal::UserFacing, constness);
 
     let body_id = local_did.unwrap_or(CRATE_DEF_ID);
     let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id);
@@ -388,7 +383,7 @@ fn well_formed_types_in_env(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Predica
         }
     });
 
-    tcx.mk_predicates(clauses.chain(input_clauses))
+    tcx.mk_predicates_from_iter(clauses.chain(input_clauses))
 }
 
 fn param_env_reveal_all_normalized(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
diff --git a/config.toml.example b/config.toml.example
index df4478bb0cb..69eb228a2d5 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -666,6 +666,9 @@ changelog-seen = 2
 # LTO entirely.
 #lto = "thin-local"
 
+# Build compiler with the optimization enabled and -Zvalidate-mir, currently only for `std`
+#validate-mir-opts = 3
+
 # =============================================================================
 # Options for specific targets
 #
diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs
index 1573b3d77dc..d4a12509b1c 100644
--- a/library/alloc/src/collections/vec_deque/mod.rs
+++ b/library/alloc/src/collections/vec_deque/mod.rs
@@ -944,65 +944,72 @@ impl<T, A: Allocator> VecDeque<T, A> {
             return;
         }
 
-        if target_cap < self.capacity() {
-            // There are three cases of interest:
-            //   All elements are out of desired bounds
-            //   Elements are contiguous, and head is out of desired bounds
-            //   Elements are discontiguous, and tail is out of desired bounds
+        // There are three cases of interest:
+        //   All elements are out of desired bounds
+        //   Elements are contiguous, and tail is out of desired bounds
+        //   Elements are discontiguous
+        //
+        // At all other times, element positions are unaffected.
+
+        // `head` and `len` are at most `isize::MAX` and `target_cap < self.capacity()`, so nothing can
+        // overflow.
+        let tail_outside = (target_cap + 1..=self.capacity()).contains(&(self.head + self.len));
+
+        if self.len == 0 {
+            self.head = 0;
+        } else if self.head >= target_cap && tail_outside {
+            // Head and tail are both out of bounds, so copy all of them to the front.
             //
-            // At all other times, element positions are unaffected.
+            //  H := head
+            //  L := last element
+            //                    H           L
+            //   [. . . . . . . . o o o o o o o . ]
+            //    H           L
+            //   [o o o o o o o . ]
+            unsafe {
+                // nonoverlapping because `self.head >= target_cap >= self.len`.
+                self.copy_nonoverlapping(self.head, 0, self.len);
+            }
+            self.head = 0;
+        } else if self.head < target_cap && tail_outside {
+            // Head is in bounds, tail is out of bounds.
+            // Copy the overflowing part to the beginning of the
+            // buffer. This won't overlap because `target_cap >= self.len`.
             //
-            // Indicates that elements at the head should be moved.
-
-            let tail_outside = (target_cap + 1..=self.capacity()).contains(&(self.head + self.len));
-            // Move elements from out of desired bounds (positions after target_cap)
-            if self.len == 0 {
-                self.head = 0;
-            } else if self.head >= target_cap && tail_outside {
-                //  H := head
-                //  L := last element
-                //                    H           L
-                //   [. . . . . . . . o o o o o o o . ]
-                //    H           L
-                //   [o o o o o o o . ]
-                unsafe {
-                    // nonoverlapping because self.head >= target_cap >= self.len
-                    self.copy_nonoverlapping(self.head, 0, self.len);
-                }
-                self.head = 0;
-            } else if self.head < target_cap && tail_outside {
-                //  H := head
-                //  L := last element
-                //          H           L
-                //   [. . . o o o o o o o . . . . . . ]
-                //      L   H
-                //   [o o . o o o o o ]
-                let len = self.head + self.len - target_cap;
-                unsafe {
-                    self.copy_nonoverlapping(target_cap, 0, len);
-                }
-            } else if self.head >= target_cap {
-                //  H := head
-                //  L := last element
-                //            L                   H
-                //   [o o o o o . . . . . . . . . o o ]
-                //            L   H
-                //   [o o o o o . o o ]
-                let len = self.capacity() - self.head;
-                let new_head = target_cap - len;
-                unsafe {
-                    // can't use copy_nonoverlapping here for the same reason
-                    // as in `handle_capacity_increase()`
-                    self.copy(self.head, new_head, len);
-                }
-                self.head = new_head;
+            //  H := head
+            //  L := last element
+            //          H           L
+            //   [. . . o o o o o o o . . . . . . ]
+            //      L   H
+            //   [o o . o o o o o ]
+            let len = self.head + self.len - target_cap;
+            unsafe {
+                self.copy_nonoverlapping(target_cap, 0, len);
             }
-
-            self.buf.shrink_to_fit(target_cap);
-
-            debug_assert!(self.head < self.capacity() || self.capacity() == 0);
-            debug_assert!(self.len <= self.capacity());
+        } else if !self.is_contiguous() {
+            // The head slice is at least partially out of bounds, tail is in bounds.
+            // Copy the head backwards so it lines up with the target capacity.
+            // This won't overlap because `target_cap >= self.len`.
+            //
+            //  H := head
+            //  L := last element
+            //            L                   H
+            //   [o o o o o . . . . . . . . . o o ]
+            //            L   H
+            //   [o o o o o . o o ]
+            let head_len = self.capacity() - self.head;
+            let new_head = target_cap - head_len;
+            unsafe {
+                // can't use `copy_nonoverlapping()` here because the new and old
+                // regions for the head might overlap.
+                self.copy(self.head, new_head, head_len);
+            }
+            self.head = new_head;
         }
+        self.buf.shrink_to_fit(target_cap);
+
+        debug_assert!(self.head < self.capacity() || self.capacity() == 0);
+        debug_assert!(self.len <= self.capacity());
     }
 
     /// Shortens the deque, keeping the first `len` elements and dropping
diff --git a/library/alloc/src/collections/vec_deque/tests.rs b/library/alloc/src/collections/vec_deque/tests.rs
index 220ad71beab..205a8ff3c19 100644
--- a/library/alloc/src/collections/vec_deque/tests.rs
+++ b/library/alloc/src/collections/vec_deque/tests.rs
@@ -749,6 +749,48 @@ fn test_drain() {
 }
 
 #[test]
+fn issue_108453() {
+    let mut deque = VecDeque::with_capacity(10);
+
+    deque.push_back(1u8);
+    deque.push_back(2);
+    deque.push_back(3);
+
+    deque.push_front(10);
+    deque.push_front(9);
+
+    deque.shrink_to(9);
+
+    assert_eq!(deque.into_iter().collect::<Vec<_>>(), vec![9, 10, 1, 2, 3]);
+}
+
+#[test]
+fn test_shrink_to() {
+    // test deques with capacity 16 with all possible head positions, lengths and target capacities.
+    let cap = 16;
+
+    for len in 0..cap {
+        for head in 0..cap {
+            let expected = (1..=len).collect::<VecDeque<_>>();
+
+            for target_cap in len..cap {
+                let mut deque = VecDeque::with_capacity(cap);
+                // currently, `with_capacity` always allocates the exact capacity if it's greater than 8.
+                assert_eq!(deque.capacity(), cap);
+
+                // we can let the head point anywhere in the buffer since the deque is empty.
+                deque.head = head;
+                deque.extend(1..=len);
+
+                deque.shrink_to(target_cap);
+
+                assert_eq!(deque, expected);
+            }
+        }
+    }
+}
+
+#[test]
 fn test_shrink_to_fit() {
     // This test checks that every single combination of head and tail position,
     // is tested. Capacity 15 should be large enough to cover every case.
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index a07f3da78d3..b279f21b524 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -378,8 +378,8 @@ mod spec_extend;
 /// Currently, `Vec` does not guarantee the order in which elements are dropped.
 /// The order has changed in the past and may change again.
 ///
-/// [`get`]: ../../std/vec/struct.Vec.html#method.get
-/// [`get_mut`]: ../../std/vec/struct.Vec.html#method.get_mut
+/// [`get`]: slice::get
+/// [`get_mut`]: slice::get_mut
 /// [`String`]: crate::string::String
 /// [`&str`]: type@str
 /// [`shrink_to_fit`]: Vec::shrink_to_fit
diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs
index f95b880df34..805354be089 100644
--- a/library/core/src/convert/mod.rs
+++ b/library/core/src/convert/mod.rs
@@ -542,7 +542,7 @@ pub trait Into<T>: Sized {
 #[const_trait]
 pub trait From<T>: Sized {
     /// Converts to this type from the input type.
-    #[lang = "from"]
+    #[rustc_diagnostic_item = "from_fn"]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn from(value: T) -> Self;
diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs
index 156b925de77..ae00232c12c 100644
--- a/library/core/src/iter/mod.rs
+++ b/library/core/src/iter/mod.rs
@@ -278,6 +278,7 @@
 //!
 //! ```
 //! # #![allow(unused_must_use)]
+//! # #![cfg_attr(not(bootstrap), allow(map_unit_fn))]
 //! let v = vec![1, 2, 3, 4, 5];
 //! v.iter().map(|x| println!("{x}"));
 //! ```
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 9e3e13e7004..b8e7d0a68da 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -69,6 +69,7 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
 #[doc(notable_trait)]
 #[rustc_diagnostic_item = "Iterator"]
 #[must_use = "iterators are lazy and do nothing unless consumed"]
+#[cfg_attr(not(bootstrap), const_trait)]
 pub trait Iterator {
     /// The type of the elements being iterated over.
     #[rustc_diagnostic_item = "IteratorItem"]
@@ -141,6 +142,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[unstable(feature = "iter_next_chunk", reason = "recently added", issue = "98326")]
+    #[rustc_do_not_const_check]
     fn next_chunk<const N: usize>(
         &mut self,
     ) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>>
@@ -218,6 +220,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn size_hint(&self) -> (usize, Option<usize>) {
         (0, None)
     }
@@ -255,6 +258,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn count(self) -> usize
     where
         Self: Sized,
@@ -285,6 +289,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn last(self) -> Option<Self::Item>
     where
         Self: Sized,
@@ -331,6 +336,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")]
+    #[rustc_do_not_const_check]
     fn advance_by(&mut self, n: usize) -> Result<(), usize> {
         for i in 0..n {
             self.next().ok_or(i)?;
@@ -379,6 +385,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn nth(&mut self, n: usize) -> Option<Self::Item> {
         self.advance_by(n).ok()?;
         self.next()
@@ -431,6 +438,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iterator_step_by", since = "1.28.0")]
+    #[rustc_do_not_const_check]
     fn step_by(self, step: usize) -> StepBy<Self>
     where
         Self: Sized,
@@ -502,6 +510,7 @@ pub trait Iterator {
     /// [`OsStr`]: ../../std/ffi/struct.OsStr.html
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter>
     where
         Self: Sized,
@@ -620,6 +629,7 @@ pub trait Iterator {
     /// [`zip`]: crate::iter::zip
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter>
     where
         Self: Sized,
@@ -662,6 +672,7 @@ pub trait Iterator {
     /// [`intersperse_with`]: Iterator::intersperse_with
     #[inline]
     #[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
+    #[rustc_do_not_const_check]
     fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
     where
         Self: Sized,
@@ -720,6 +731,7 @@ pub trait Iterator {
     /// [`intersperse`]: Iterator::intersperse
     #[inline]
     #[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
+    #[rustc_do_not_const_check]
     fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
     where
         Self: Sized,
@@ -777,8 +789,10 @@ pub trait Iterator {
     ///     println!("{x}");
     /// }
     /// ```
+    #[rustc_diagnostic_item = "IteratorMap"]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn map<B, F>(self, f: F) -> Map<Self, F>
     where
         Self: Sized,
@@ -824,6 +838,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iterator_for_each", since = "1.21.0")]
+    #[rustc_do_not_const_check]
     fn for_each<F>(self, f: F)
     where
         Self: Sized,
@@ -899,6 +914,7 @@ pub trait Iterator {
     /// Note that `iter.filter(f).next()` is equivalent to `iter.find(f)`.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn filter<P>(self, predicate: P) -> Filter<Self, P>
     where
         Self: Sized,
@@ -944,6 +960,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
     where
         Self: Sized,
@@ -990,6 +1007,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn enumerate(self) -> Enumerate<Self>
     where
         Self: Sized,
@@ -1061,6 +1079,7 @@ pub trait Iterator {
     /// [`next`]: Iterator::next
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn peekable(self) -> Peekable<Self>
     where
         Self: Sized,
@@ -1126,6 +1145,7 @@ pub trait Iterator {
     #[inline]
     #[doc(alias = "drop_while")]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
     where
         Self: Sized,
@@ -1207,6 +1227,7 @@ pub trait Iterator {
     /// the iteration should stop, but wasn't placed back into the iterator.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
     where
         Self: Sized,
@@ -1295,6 +1316,7 @@ pub trait Iterator {
     /// [`fuse`]: Iterator::fuse
     #[inline]
     #[stable(feature = "iter_map_while", since = "1.57.0")]
+    #[rustc_do_not_const_check]
     fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
     where
         Self: Sized,
@@ -1326,6 +1348,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn skip(self, n: usize) -> Skip<Self>
     where
         Self: Sized,
@@ -1379,6 +1402,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn take(self, n: usize) -> Take<Self>
     where
         Self: Sized,
@@ -1428,6 +1452,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
     where
         Self: Sized,
@@ -1468,6 +1493,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
     where
         Self: Sized,
@@ -1552,6 +1578,7 @@ pub trait Iterator {
     /// [`flat_map()`]: Iterator::flat_map
     #[inline]
     #[stable(feature = "iterator_flatten", since = "1.29.0")]
+    #[rustc_do_not_const_check]
     fn flatten(self) -> Flatten<Self>
     where
         Self: Sized,
@@ -1620,6 +1647,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn fuse(self) -> Fuse<Self>
     where
         Self: Sized,
@@ -1704,6 +1732,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn inspect<F>(self, f: F) -> Inspect<Self, F>
     where
         Self: Sized,
@@ -1734,6 +1763,7 @@ pub trait Iterator {
     /// assert_eq!(of_rust, vec!["of", "Rust"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn by_ref(&mut self) -> &mut Self
     where
         Self: Sized,
@@ -1853,6 +1883,7 @@ pub trait Iterator {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"]
     #[cfg_attr(not(test), rustc_diagnostic_item = "iterator_collect_fn")]
+    #[rustc_do_not_const_check]
     fn collect<B: FromIterator<Self::Item>>(self) -> B
     where
         Self: Sized,
@@ -1931,6 +1962,7 @@ pub trait Iterator {
     /// [`collect`]: Iterator::collect
     #[inline]
     #[unstable(feature = "iterator_try_collect", issue = "94047")]
+    #[rustc_do_not_const_check]
     fn try_collect<B>(&mut self) -> ChangeOutputType<Self::Item, B>
     where
         Self: Sized,
@@ -2004,6 +2036,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[unstable(feature = "iter_collect_into", reason = "new API", issue = "94780")]
+    #[rustc_do_not_const_check]
     fn collect_into<E: Extend<Self::Item>>(self, collection: &mut E) -> &mut E
     where
         Self: Sized,
@@ -2038,6 +2071,7 @@ pub trait Iterator {
     /// assert_eq!(odd, vec![1, 3]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn partition<B, F>(self, f: F) -> (B, B)
     where
         Self: Sized,
@@ -2100,6 +2134,7 @@ pub trait Iterator {
     /// assert!(a[i..].iter().all(|&n| n % 2 == 1)); // odds
     /// ```
     #[unstable(feature = "iter_partition_in_place", reason = "new API", issue = "62543")]
+    #[rustc_do_not_const_check]
     fn partition_in_place<'a, T: 'a, P>(mut self, ref mut predicate: P) -> usize
     where
         Self: Sized + DoubleEndedIterator<Item = &'a mut T>,
@@ -2157,6 +2192,7 @@ pub trait Iterator {
     /// assert!(!"IntoIterator".chars().is_partitioned(char::is_uppercase));
     /// ```
     #[unstable(feature = "iter_is_partitioned", reason = "new API", issue = "62544")]
+    #[rustc_do_not_const_check]
     fn is_partitioned<P>(mut self, mut predicate: P) -> bool
     where
         Self: Sized,
@@ -2251,6 +2287,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iterator_try_fold", since = "1.27.0")]
+    #[rustc_do_not_const_check]
     fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
     where
         Self: Sized,
@@ -2309,6 +2346,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iterator_try_fold", since = "1.27.0")]
+    #[rustc_do_not_const_check]
     fn try_for_each<F, R>(&mut self, f: F) -> R
     where
         Self: Sized,
@@ -2428,6 +2466,7 @@ pub trait Iterator {
     #[doc(alias = "inject", alias = "foldl")]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn fold<B, F>(mut self, init: B, mut f: F) -> B
     where
         Self: Sized,
@@ -2465,6 +2504,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iterator_fold_self", since = "1.51.0")]
+    #[rustc_do_not_const_check]
     fn reduce<F>(mut self, f: F) -> Option<Self::Item>
     where
         Self: Sized,
@@ -2536,6 +2576,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[unstable(feature = "iterator_try_reduce", reason = "new API", issue = "87053")]
+    #[rustc_do_not_const_check]
     fn try_reduce<F, R>(&mut self, f: F) -> ChangeOutputType<R, Option<R::Output>>
     where
         Self: Sized,
@@ -2593,6 +2634,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn all<F>(&mut self, f: F) -> bool
     where
         Self: Sized,
@@ -2646,6 +2688,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn any<F>(&mut self, f: F) -> bool
     where
         Self: Sized,
@@ -2709,6 +2752,7 @@ pub trait Iterator {
     /// Note that `iter.find(f)` is equivalent to `iter.filter(f).next()`.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
     where
         Self: Sized,
@@ -2740,6 +2784,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iterator_find_map", since = "1.30.0")]
+    #[rustc_do_not_const_check]
     fn find_map<B, F>(&mut self, f: F) -> Option<B>
     where
         Self: Sized,
@@ -2796,6 +2841,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[unstable(feature = "try_find", reason = "new API", issue = "63178")]
+    #[rustc_do_not_const_check]
     fn try_find<F, R>(&mut self, f: F) -> ChangeOutputType<R, Option<Self::Item>>
     where
         Self: Sized,
@@ -2878,6 +2924,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn position<P>(&mut self, predicate: P) -> Option<usize>
     where
         Self: Sized,
@@ -2935,6 +2982,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn rposition<P>(&mut self, predicate: P) -> Option<usize>
     where
         P: FnMut(Self::Item) -> bool,
@@ -2986,6 +3034,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn max(self) -> Option<Self::Item>
     where
         Self: Sized,
@@ -3024,6 +3073,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn min(self) -> Option<Self::Item>
     where
         Self: Sized,
@@ -3046,6 +3096,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iter_cmp_by_key", since = "1.6.0")]
+    #[rustc_do_not_const_check]
     fn max_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
     where
         Self: Sized,
@@ -3079,6 +3130,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iter_max_by", since = "1.15.0")]
+    #[rustc_do_not_const_check]
     fn max_by<F>(self, compare: F) -> Option<Self::Item>
     where
         Self: Sized,
@@ -3106,6 +3158,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iter_cmp_by_key", since = "1.6.0")]
+    #[rustc_do_not_const_check]
     fn min_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
     where
         Self: Sized,
@@ -3139,6 +3192,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iter_min_by", since = "1.15.0")]
+    #[rustc_do_not_const_check]
     fn min_by<F>(self, compare: F) -> Option<Self::Item>
     where
         Self: Sized,
@@ -3176,6 +3230,7 @@ pub trait Iterator {
     #[inline]
     #[doc(alias = "reverse")]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn rev(self) -> Rev<Self>
     where
         Self: Sized + DoubleEndedIterator,
@@ -3214,6 +3269,7 @@ pub trait Iterator {
     /// assert_eq!(z, [3, 6]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
     where
         FromA: Default + Extend<A>,
@@ -3246,6 +3302,7 @@ pub trait Iterator {
     /// assert_eq!(v_map, vec![1, 2, 3]);
     /// ```
     #[stable(feature = "iter_copied", since = "1.36.0")]
+    #[rustc_do_not_const_check]
     fn copied<'a, T: 'a>(self) -> Copied<Self>
     where
         Self: Sized + Iterator<Item = &'a T>,
@@ -3293,6 +3350,7 @@ pub trait Iterator {
     /// assert_eq!(&[vec![23]], &faster[..]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn cloned<'a, T: 'a>(self) -> Cloned<Self>
     where
         Self: Sized + Iterator<Item = &'a T>,
@@ -3327,6 +3385,7 @@ pub trait Iterator {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
+    #[rustc_do_not_const_check]
     fn cycle(self) -> Cycle<Self>
     where
         Self: Sized + Clone,
@@ -3370,6 +3429,7 @@ pub trait Iterator {
     /// ```
     #[track_caller]
     #[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+    #[rustc_do_not_const_check]
     fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
     where
         Self: Sized,
@@ -3400,6 +3460,7 @@ pub trait Iterator {
     /// assert_eq!(sum, 6);
     /// ```
     #[stable(feature = "iter_arith", since = "1.11.0")]
+    #[rustc_do_not_const_check]
     fn sum<S>(self) -> S
     where
         Self: Sized,
@@ -3429,6 +3490,7 @@ pub trait Iterator {
     /// assert_eq!(factorial(5), 120);
     /// ```
     #[stable(feature = "iter_arith", since = "1.11.0")]
+    #[rustc_do_not_const_check]
     fn product<P>(self) -> P
     where
         Self: Sized,
@@ -3450,6 +3512,7 @@ pub trait Iterator {
     /// assert_eq!([1, 2].iter().cmp([1].iter()), Ordering::Greater);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
+    #[rustc_do_not_const_check]
     fn cmp<I>(self, other: I) -> Ordering
     where
         I: IntoIterator<Item = Self::Item>,
@@ -3479,6 +3542,7 @@ pub trait Iterator {
     /// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (2 * x).cmp(&y)), Ordering::Greater);
     /// ```
     #[unstable(feature = "iter_order_by", issue = "64295")]
+    #[rustc_do_not_const_check]
     fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
     where
         Self: Sized,
@@ -3535,6 +3599,7 @@ pub trait Iterator {
     /// ```
     ///
     #[stable(feature = "iter_order", since = "1.5.0")]
+    #[rustc_do_not_const_check]
     fn partial_cmp<I>(self, other: I) -> Option<Ordering>
     where
         I: IntoIterator,
@@ -3573,6 +3638,7 @@ pub trait Iterator {
     /// );
     /// ```
     #[unstable(feature = "iter_order_by", issue = "64295")]
+    #[rustc_do_not_const_check]
     fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
     where
         Self: Sized,
@@ -3606,6 +3672,7 @@ pub trait Iterator {
     /// assert_eq!([1].iter().eq([1, 2].iter()), false);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
+    #[rustc_do_not_const_check]
     fn eq<I>(self, other: I) -> bool
     where
         I: IntoIterator,
@@ -3631,6 +3698,7 @@ pub trait Iterator {
     /// assert!(xs.iter().eq_by(&ys, |&x, &y| x * x == y));
     /// ```
     #[unstable(feature = "iter_order_by", issue = "64295")]
+    #[rustc_do_not_const_check]
     fn eq_by<I, F>(self, other: I, eq: F) -> bool
     where
         Self: Sized,
@@ -3663,6 +3731,7 @@ pub trait Iterator {
     /// assert_eq!([1].iter().ne([1, 2].iter()), true);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
+    #[rustc_do_not_const_check]
     fn ne<I>(self, other: I) -> bool
     where
         I: IntoIterator,
@@ -3684,6 +3753,7 @@ pub trait Iterator {
     /// assert_eq!([1, 2].iter().lt([1, 2].iter()), false);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
+    #[rustc_do_not_const_check]
     fn lt<I>(self, other: I) -> bool
     where
         I: IntoIterator,
@@ -3705,6 +3775,7 @@ pub trait Iterator {
     /// assert_eq!([1, 2].iter().le([1, 2].iter()), true);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
+    #[rustc_do_not_const_check]
     fn le<I>(self, other: I) -> bool
     where
         I: IntoIterator,
@@ -3726,6 +3797,7 @@ pub trait Iterator {
     /// assert_eq!([1, 2].iter().gt([1, 2].iter()), false);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
+    #[rustc_do_not_const_check]
     fn gt<I>(self, other: I) -> bool
     where
         I: IntoIterator,
@@ -3747,6 +3819,7 @@ pub trait Iterator {
     /// assert_eq!([1, 2].iter().ge([1, 2].iter()), true);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
+    #[rustc_do_not_const_check]
     fn ge<I>(self, other: I) -> bool
     where
         I: IntoIterator,
@@ -3778,6 +3851,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
+    #[rustc_do_not_const_check]
     fn is_sorted(self) -> bool
     where
         Self: Sized,
@@ -3806,6 +3880,7 @@ pub trait Iterator {
     ///
     /// [`is_sorted`]: Iterator::is_sorted
     #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
+    #[rustc_do_not_const_check]
     fn is_sorted_by<F>(mut self, compare: F) -> bool
     where
         Self: Sized,
@@ -3852,6 +3927,7 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
+    #[rustc_do_not_const_check]
     fn is_sorted_by_key<F, K>(self, f: F) -> bool
     where
         Self: Sized,
@@ -3867,6 +3943,7 @@ pub trait Iterator {
     #[inline]
     #[doc(hidden)]
     #[unstable(feature = "trusted_random_access", issue = "none")]
+    #[rustc_do_not_const_check]
     unsafe fn __iterator_get_unchecked(&mut self, _idx: usize) -> Self::Item
     where
         Self: TrustedRandomAccessNoCoerce,
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index dc0702c467a..d3727a824b5 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -194,6 +194,7 @@
 #![feature(cfg_target_has_atomic_equal_alignment)]
 #![feature(const_closures)]
 #![feature(const_fn_floating_point_arithmetic)]
+#![feature(const_for)]
 #![feature(const_mut_refs)]
 #![feature(const_precise_live_drops)]
 #![feature(const_refs_to_cell)]
diff --git a/library/core/src/slice/sort.rs b/library/core/src/slice/sort.rs
index 4ca4eb86bde..7b8062c431e 100644
--- a/library/core/src/slice/sort.rs
+++ b/library/core/src/slice/sort.rs
@@ -673,19 +673,23 @@ where
 fn break_patterns<T>(v: &mut [T]) {
     let len = v.len();
     if len >= 8 {
-        // Pseudorandom number generator from the "Xorshift RNGs" paper by George Marsaglia.
-        let mut random = len as u32;
-        let mut gen_u32 = || {
-            random ^= random << 13;
-            random ^= random >> 17;
-            random ^= random << 5;
-            random
-        };
+        let mut seed = len;
         let mut gen_usize = || {
+            // Pseudorandom number generator from the "Xorshift RNGs" paper by George Marsaglia.
             if usize::BITS <= 32 {
-                gen_u32() as usize
+                let mut r = seed as u32;
+                r ^= r << 13;
+                r ^= r >> 17;
+                r ^= r << 5;
+                seed = r as usize;
+                seed
             } else {
-                (((gen_u32() as u64) << 32) | (gen_u32() as u64)) as usize
+                let mut r = seed as u64;
+                r ^= r << 13;
+                r ^= r >> 7;
+                r ^= r << 17;
+                seed = r as usize;
+                seed
             }
         };
 
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index 1d14efc7523..00bcaf3e18c 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -922,13 +922,13 @@ impl AtomicBool {
     ///
     /// let mut atomic = AtomicBool::new(true);
     /// unsafe {
-    ///     my_atomic_op(atomic.as_mut_ptr());
+    ///     my_atomic_op(atomic.as_ptr());
     /// }
     /// # }
     /// ```
     #[inline]
     #[unstable(feature = "atomic_mut_ptr", reason = "recently added", issue = "66893")]
-    pub const fn as_mut_ptr(&self) -> *mut bool {
+    pub const fn as_ptr(&self) -> *mut bool {
         self.v.get().cast()
     }
 
@@ -1814,12 +1814,12 @@ impl<T> AtomicPtr<T> {
     ///
     /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
     /// unsafe {
-    ///     my_atomic_op(atomic.as_mut_ptr());
+    ///     my_atomic_op(atomic.as_ptr());
     /// }
     /// ```
     #[inline]
     #[unstable(feature = "atomic_mut_ptr", reason = "recently added", issue = "66893")]
-    pub const fn as_mut_ptr(&self) -> *mut *mut T {
+    pub const fn as_ptr(&self) -> *mut *mut T {
         self.p.get()
     }
 }
@@ -2719,7 +2719,7 @@ macro_rules! atomic_int {
             ///
             /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
             /// unsafe {
-            ///     my_atomic_op(atomic.as_mut_ptr());
+            ///     my_atomic_op(atomic.as_ptr());
             /// }
             /// # }
             /// ```
@@ -2727,7 +2727,7 @@ macro_rules! atomic_int {
             #[unstable(feature = "atomic_mut_ptr",
                    reason = "recently added",
                    issue = "66893")]
-            pub const fn as_mut_ptr(&self) -> *mut $int_type {
+            pub const fn as_ptr(&self) -> *mut $int_type {
                 self.v.get()
             }
         }
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 349cd91c89e..311b2e21c17 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -43,7 +43,7 @@ dlmalloc = { version = "0.2.3", features = ['rustc-dep-of-std'] }
 fortanix-sgx-abi = { version = "0.5.0", features = ['rustc-dep-of-std'] }
 
 [target.'cfg(target_os = "hermit")'.dependencies]
-hermit-abi = { version = "0.2.6", features = ['rustc-dep-of-std'] }
+hermit-abi = { version = "0.3.0", features = ['rustc-dep-of-std'] }
 
 [target.wasm32-wasi.dependencies]
 wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false }
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 839fdc96632..909d9bf4093 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -1595,3 +1595,19 @@ fn test_read_dir_infinite_loop() {
     // Check for duplicate errors
     assert!(dir.filter(|e| e.is_err()).take(2).count() < 2);
 }
+
+#[test]
+fn rename_directory() {
+    let tmpdir = tmpdir();
+    let old_path = tmpdir.join("foo/bar/baz");
+    fs::create_dir_all(&old_path).unwrap();
+    let test_file = &old_path.join("temp.txt");
+
+    File::create(test_file).unwrap();
+
+    let new_path = tmpdir.join("quux/blat");
+    fs::create_dir_all(&new_path).unwrap();
+    fs::rename(&old_path, &new_path.join("newdir")).unwrap();
+    assert!(new_path.join("newdir").is_dir());
+    assert!(new_path.join("newdir/temp.txt").exists());
+}
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index e35145c4ade..203c490fa29 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -1568,7 +1568,7 @@ mod static_keyword {}
 ///
 /// # Style conventions
 ///
-/// Structs are always written in CamelCase, with few exceptions. While the trailing comma on a
+/// Structs are always written in UpperCamelCase, with few exceptions. While the trailing comma on a
 /// struct's list of fields can be omitted, it's usually kept for convenience in adding and
 /// removing fields down the line.
 ///
diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs
index 439b8d52a2d..258919d53a4 100644
--- a/library/std/src/os/fd/owned.rs
+++ b/library/std/src/os/fd/owned.rs
@@ -9,7 +9,7 @@ use crate::fs;
 use crate::io;
 use crate::marker::PhantomData;
 use crate::mem::forget;
-#[cfg(not(any(target_arch = "wasm32", target_env = "sgx")))]
+#[cfg(not(any(target_arch = "wasm32", target_env = "sgx", target_os = "hermit")))]
 use crate::sys::cvt;
 use crate::sys_common::{AsInner, FromInner, IntoInner};
 
@@ -89,7 +89,7 @@ impl OwnedFd {
 impl BorrowedFd<'_> {
     /// Creates a new `OwnedFd` instance that shares the same underlying file
     /// description as the existing `BorrowedFd` instance.
-    #[cfg(not(target_arch = "wasm32"))]
+    #[cfg(not(any(target_arch = "wasm32", target_os = "hermit")))]
     #[stable(feature = "io_safety", since = "1.63.0")]
     pub fn try_clone_to_owned(&self) -> crate::io::Result<OwnedFd> {
         // We want to atomically duplicate this file descriptor and set the
@@ -112,7 +112,7 @@ impl BorrowedFd<'_> {
 
     /// Creates a new `OwnedFd` instance that shares the same underlying file
     /// description as the existing `BorrowedFd` instance.
-    #[cfg(target_arch = "wasm32")]
+    #[cfg(any(target_arch = "wasm32", target_os = "hermit"))]
     #[stable(feature = "io_safety", since = "1.63.0")]
     pub fn try_clone_to_owned(&self) -> crate::io::Result<OwnedFd> {
         Err(crate::io::const_io_error!(
@@ -174,7 +174,10 @@ impl Drop for OwnedFd {
             // the file descriptor was closed or not, and if we retried (for
             // something like EINTR), we might close another valid file descriptor
             // opened after we closed ours.
+            #[cfg(not(target_os = "hermit"))]
             let _ = libc::close(self.fd);
+            #[cfg(target_os = "hermit")]
+            let _ = hermit_abi::close(self.fd);
         }
     }
 }
diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs
index c138162f1ab..0a4cefd2095 100644
--- a/library/std/src/os/fd/raw.rs
+++ b/library/std/src/os/fd/raw.rs
@@ -4,6 +4,9 @@
 
 use crate::fs;
 use crate::io;
+#[cfg(target_os = "hermit")]
+use crate::os::hermit::io::OwnedFd;
+#[cfg(not(target_os = "hermit"))]
 use crate::os::raw;
 #[cfg(all(doc, not(target_arch = "wasm32")))]
 use crate::os::unix::io::AsFd;
@@ -12,11 +15,18 @@ use crate::os::unix::io::OwnedFd;
 #[cfg(target_os = "wasi")]
 use crate::os::wasi::io::OwnedFd;
 use crate::sys_common::{AsInner, IntoInner};
+#[cfg(target_os = "hermit")]
+use hermit_abi as libc;
 
 /// Raw file descriptors.
 #[rustc_allowed_through_unstable_modules]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(target_os = "hermit"))]
 pub type RawFd = raw::c_int;
+#[rustc_allowed_through_unstable_modules]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(target_os = "hermit")]
+pub type RawFd = i32;
 
 /// A trait to extract the raw file descriptor from an underlying object.
 ///
diff --git a/library/std/src/os/hermit/io/mod.rs b/library/std/src/os/hermit/io/mod.rs
new file mode 100644
index 00000000000..524dfae0d63
--- /dev/null
+++ b/library/std/src/os/hermit/io/mod.rs
@@ -0,0 +1,13 @@
+#![stable(feature = "os_fd", since = "1.66.0")]
+
+mod net;
+#[path = "../../fd/owned.rs"]
+mod owned;
+#[path = "../../fd/raw.rs"]
+mod raw;
+
+// Export the types and traits for the public API.
+#[stable(feature = "os_fd", since = "1.66.0")]
+pub use owned::*;
+#[stable(feature = "os_fd", since = "1.66.0")]
+pub use raw::*;
diff --git a/library/std/src/os/hermit/io/net.rs b/library/std/src/os/hermit/io/net.rs
new file mode 100644
index 00000000000..8f3802d7873
--- /dev/null
+++ b/library/std/src/os/hermit/io/net.rs
@@ -0,0 +1,46 @@
+use crate::os::hermit::io::OwnedFd;
+use crate::os::hermit::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
+use crate::sys_common::{self, AsInner, FromInner, IntoInner};
+use crate::{net, sys};
+
+macro_rules! impl_as_raw_fd {
+    ($($t:ident)*) => {$(
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl AsRawFd for net::$t {
+            #[inline]
+            fn as_raw_fd(&self) -> RawFd {
+                self.as_inner().socket().as_raw_fd()
+            }
+        }
+    )*};
+}
+impl_as_raw_fd! { TcpStream TcpListener UdpSocket }
+
+macro_rules! impl_from_raw_fd {
+    ($($t:ident)*) => {$(
+        #[stable(feature = "from_raw_os", since = "1.1.0")]
+        impl FromRawFd for net::$t {
+            #[inline]
+            unsafe fn from_raw_fd(fd: RawFd) -> net::$t {
+                unsafe {
+                    let socket = sys::net::Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd)));
+                    net::$t::from_inner(sys_common::net::$t::from_inner(socket))
+                }
+            }
+        }
+    )*};
+}
+impl_from_raw_fd! { TcpStream TcpListener UdpSocket }
+
+macro_rules! impl_into_raw_fd {
+    ($($t:ident)*) => {$(
+        #[stable(feature = "into_raw_os", since = "1.4.0")]
+        impl IntoRawFd for net::$t {
+            #[inline]
+            fn into_raw_fd(self) -> RawFd {
+                self.into_inner().into_socket().into_inner().into_inner().into_raw_fd()
+            }
+        }
+    )*};
+}
+impl_into_raw_fd! { TcpStream TcpListener UdpSocket }
diff --git a/library/std/src/os/hermit/mod.rs b/library/std/src/os/hermit/mod.rs
index 4657b545a1b..89b1b831912 100644
--- a/library/std/src/os/hermit/mod.rs
+++ b/library/std/src/os/hermit/mod.rs
@@ -1,6 +1,11 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
+#[allow(unused_extern_crates)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub extern crate hermit_abi as abi;
+
 pub mod ffi;
+pub mod io;
 
 /// A prelude for conveniently writing platform-specific code.
 ///
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index 42773805cdb..af137c9bd85 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -60,16 +60,6 @@ pub mod windows {}
         all(target_vendor = "fortanix", target_env = "sgx")
     )
 )))]
-#[cfg(target_os = "hermit")]
-#[path = "hermit/mod.rs"]
-pub mod unix;
-#[cfg(not(all(
-    doc,
-    any(
-        all(target_arch = "wasm32", not(target_os = "wasi")),
-        all(target_vendor = "fortanix", target_env = "sgx")
-    )
-)))]
 #[cfg(all(not(target_os = "hermit"), any(unix, doc)))]
 pub mod unix;
 
@@ -123,6 +113,8 @@ pub mod freebsd;
 pub mod fuchsia;
 #[cfg(target_os = "haiku")]
 pub mod haiku;
+#[cfg(target_os = "hermit")]
+pub mod hermit;
 #[cfg(target_os = "horizon")]
 pub mod horizon;
 #[cfg(target_os = "illumos")]
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index b0db3112e22..e59f32af77d 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -95,13 +95,16 @@ impl Default for Hook {
 
 static HOOK: RwLock<Hook> = RwLock::new(Hook::Default);
 
-/// Registers a custom panic hook, replacing any that was previously registered.
+/// Registers a custom panic hook, replacing the previously registered hook.
 ///
 /// The panic hook is invoked when a thread panics, but before the panic runtime
 /// is invoked. As such, the hook will run with both the aborting and unwinding
-/// runtimes. The default hook prints a message to standard error and generates
-/// a backtrace if requested, but this behavior can be customized with the
-/// `set_hook` and [`take_hook`] functions.
+/// runtimes.
+///
+/// The default hook, which is registered at startup, prints a message to standard error and
+/// generates a backtrace if requested. This behavior can be customized using the `set_hook` function.
+/// The current hook can be retrieved while reinstating the default hook with the [`take_hook`]
+/// function.
 ///
 /// [`take_hook`]: ./fn.take_hook.html
 ///
@@ -143,13 +146,14 @@ pub fn set_hook(hook: Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send>) {
     drop(old);
 }
 
-/// Unregisters the current panic hook, returning it.
+/// Unregisters the current panic hook and returns it, registering the default hook
+/// in its place.
 ///
 /// *See also the function [`set_hook`].*
 ///
 /// [`set_hook`]: ./fn.set_hook.html
 ///
-/// If no custom hook is registered, the default hook will be returned.
+/// If the default hook is registered it will be returned, but remain registered.
 ///
 /// # Panics
 ///
diff --git a/library/std/src/sys/hermit/args.rs b/library/std/src/sys/hermit/args.rs
index afcae6c90ee..220a76e4b12 100644
--- a/library/std/src/sys/hermit/args.rs
+++ b/library/std/src/sys/hermit/args.rs
@@ -1,6 +1,6 @@
 use crate::ffi::{c_char, CStr, OsString};
 use crate::fmt;
-use crate::os::unix::ffi::OsStringExt;
+use crate::os::hermit::ffi::OsStringExt;
 use crate::ptr;
 use crate::sync::atomic::{
     AtomicIsize, AtomicPtr,
diff --git a/library/std/src/sys/hermit/fd.rs b/library/std/src/sys/hermit/fd.rs
index c400f5f2c2e..3a2cdd301ea 100644
--- a/library/std/src/sys/hermit/fd.rs
+++ b/library/std/src/sys/hermit/fd.rs
@@ -1,36 +1,23 @@
 #![unstable(reason = "not public", issue = "none", feature = "fd")]
 
 use crate::io::{self, Read};
-use crate::mem;
+use crate::os::hermit::io::{FromRawFd, OwnedFd, RawFd};
 use crate::sys::cvt;
 use crate::sys::hermit::abi;
 use crate::sys::unsupported;
-use crate::sys_common::AsInner;
+use crate::sys_common::{AsInner, FromInner, IntoInner};
+
+use crate::os::hermit::io::*;
 
 #[derive(Debug)]
 pub struct FileDesc {
-    fd: i32,
+    fd: OwnedFd,
 }
 
 impl FileDesc {
-    pub fn new(fd: i32) -> FileDesc {
-        FileDesc { fd }
-    }
-
-    pub fn raw(&self) -> i32 {
-        self.fd
-    }
-
-    /// Extracts the actual file descriptor without closing it.
-    pub fn into_raw(self) -> i32 {
-        let fd = self.fd;
-        mem::forget(self);
-        fd
-    }
-
     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
-        let result = unsafe { abi::read(self.fd, buf.as_mut_ptr(), buf.len()) };
-        cvt(result as i32)
+        let result = cvt(unsafe { abi::read(self.fd.as_raw_fd(), buf.as_mut_ptr(), buf.len()) })?;
+        Ok(result as usize)
     }
 
     pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
@@ -39,8 +26,8 @@ impl FileDesc {
     }
 
     pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
-        let result = unsafe { abi::write(self.fd, buf.as_ptr(), buf.len()) };
-        cvt(result as i32)
+        let result = cvt(unsafe { abi::write(self.fd.as_raw_fd(), buf.as_ptr(), buf.len()) })?;
+        Ok(result as usize)
     }
 
     pub fn duplicate(&self) -> io::Result<FileDesc> {
@@ -69,19 +56,45 @@ impl<'a> Read for &'a FileDesc {
     }
 }
 
-impl AsInner<i32> for FileDesc {
-    fn as_inner(&self) -> &i32 {
+impl IntoInner<OwnedFd> for FileDesc {
+    fn into_inner(self) -> OwnedFd {
+        self.fd
+    }
+}
+
+impl FromInner<OwnedFd> for FileDesc {
+    fn from_inner(owned_fd: OwnedFd) -> Self {
+        Self { fd: owned_fd }
+    }
+}
+
+impl FromRawFd for FileDesc {
+    unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
+        Self { fd: FromRawFd::from_raw_fd(raw_fd) }
+    }
+}
+
+impl AsInner<OwnedFd> for FileDesc {
+    fn as_inner(&self) -> &OwnedFd {
         &self.fd
     }
 }
 
-impl Drop for FileDesc {
-    fn drop(&mut self) {
-        // Note that errors are ignored when closing a file descriptor. The
-        // reason for this is that if an error occurs we don't actually know if
-        // the file descriptor was closed or not, and if we retried (for
-        // something like EINTR), we might close another valid file descriptor
-        // (opened after we closed ours.
-        let _ = unsafe { abi::close(self.fd) };
+impl AsFd for FileDesc {
+    fn as_fd(&self) -> BorrowedFd<'_> {
+        self.fd.as_fd()
+    }
+}
+
+impl AsRawFd for FileDesc {
+    #[inline]
+    fn as_raw_fd(&self) -> RawFd {
+        self.fd.as_raw_fd()
+    }
+}
+
+impl IntoRawFd for FileDesc {
+    fn into_raw_fd(self) -> RawFd {
+        self.fd.into_raw_fd()
     }
 }
diff --git a/library/std/src/sys/hermit/fs.rs b/library/std/src/sys/hermit/fs.rs
index 6fb92c037ee..c966f217757 100644
--- a/library/std/src/sys/hermit/fs.rs
+++ b/library/std/src/sys/hermit/fs.rs
@@ -3,14 +3,17 @@ use crate::fmt;
 use crate::hash::{Hash, Hasher};
 use crate::io::{self, Error, ErrorKind};
 use crate::io::{BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
+use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
 use crate::path::{Path, PathBuf};
 use crate::sys::common::small_c_string::run_path_with_cstr;
 use crate::sys::cvt;
-use crate::sys::hermit::abi;
-use crate::sys::hermit::abi::{O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY};
+use crate::sys::hermit::abi::{
+    self, O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY,
+};
 use crate::sys::hermit::fd::FileDesc;
 use crate::sys::time::SystemTime;
 use crate::sys::unsupported;
+use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 
 pub use crate::sys_common::fs::{copy, try_exists};
 //pub use crate::sys_common::fs::remove_dir_all;
@@ -283,7 +286,7 @@ impl File {
         }
 
         let fd = unsafe { cvt(abi::open(path.as_ptr(), flags, mode))? };
-        Ok(File(FileDesc::new(fd as i32)))
+        Ok(File(unsafe { FileDesc::from_raw_fd(fd as i32) }))
     }
 
     pub fn file_attr(&self) -> io::Result<FileAttr> {
@@ -363,6 +366,54 @@ impl DirBuilder {
     }
 }
 
+impl AsInner<FileDesc> for File {
+    fn as_inner(&self) -> &FileDesc {
+        &self.0
+    }
+}
+
+impl AsInnerMut<FileDesc> for File {
+    fn as_inner_mut(&mut self) -> &mut FileDesc {
+        &mut self.0
+    }
+}
+
+impl IntoInner<FileDesc> for File {
+    fn into_inner(self) -> FileDesc {
+        self.0
+    }
+}
+
+impl FromInner<FileDesc> for File {
+    fn from_inner(file_desc: FileDesc) -> Self {
+        Self(file_desc)
+    }
+}
+
+impl AsFd for File {
+    fn as_fd(&self) -> BorrowedFd<'_> {
+        self.0.as_fd()
+    }
+}
+
+impl AsRawFd for File {
+    fn as_raw_fd(&self) -> RawFd {
+        self.0.as_raw_fd()
+    }
+}
+
+impl IntoRawFd for File {
+    fn into_raw_fd(self) -> RawFd {
+        self.0.into_raw_fd()
+    }
+}
+
+impl FromRawFd for File {
+    unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
+        Self(FromRawFd::from_raw_fd(raw_fd))
+    }
+}
+
 pub fn readdir(_p: &Path) -> io::Result<ReadDir> {
     unsupported()
 }
diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs
index 20fd3dd8f09..d34a4cfedea 100644
--- a/library/std/src/sys/hermit/mod.rs
+++ b/library/std/src/sys/hermit/mod.rs
@@ -13,7 +13,7 @@
 //! compiling for wasm. That way it's a compile time error for something that's
 //! guaranteed to be a runtime error!
 
-#![allow(unsafe_op_in_unsafe_fn)]
+#![allow(missing_docs, nonstandard_style, unsafe_op_in_unsafe_fn)]
 
 use crate::intrinsics;
 use crate::os::raw::c_char;
@@ -57,9 +57,7 @@ pub mod locks {
 }
 
 use crate::io::ErrorKind;
-
-#[allow(unused_extern_crates)]
-pub extern crate hermit_abi as abi;
+use crate::os::hermit::abi;
 
 pub fn unsupported<T>() -> crate::io::Result<T> {
     Err(unsupported_err())
@@ -126,25 +124,72 @@ pub unsafe extern "C" fn runtime_entry(
 
 pub fn decode_error_kind(errno: i32) -> ErrorKind {
     match errno {
-        x if x == 13 as i32 => ErrorKind::PermissionDenied,
-        x if x == 98 as i32 => ErrorKind::AddrInUse,
-        x if x == 99 as i32 => ErrorKind::AddrNotAvailable,
-        x if x == 11 as i32 => ErrorKind::WouldBlock,
-        x if x == 103 as i32 => ErrorKind::ConnectionAborted,
-        x if x == 111 as i32 => ErrorKind::ConnectionRefused,
-        x if x == 104 as i32 => ErrorKind::ConnectionReset,
-        x if x == 17 as i32 => ErrorKind::AlreadyExists,
-        x if x == 4 as i32 => ErrorKind::Interrupted,
-        x if x == 22 as i32 => ErrorKind::InvalidInput,
-        x if x == 2 as i32 => ErrorKind::NotFound,
-        x if x == 107 as i32 => ErrorKind::NotConnected,
-        x if x == 1 as i32 => ErrorKind::PermissionDenied,
-        x if x == 32 as i32 => ErrorKind::BrokenPipe,
-        x if x == 110 as i32 => ErrorKind::TimedOut,
+        abi::errno::EACCES => ErrorKind::PermissionDenied,
+        abi::errno::EADDRINUSE => ErrorKind::AddrInUse,
+        abi::errno::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
+        abi::errno::EAGAIN => ErrorKind::WouldBlock,
+        abi::errno::ECONNABORTED => ErrorKind::ConnectionAborted,
+        abi::errno::ECONNREFUSED => ErrorKind::ConnectionRefused,
+        abi::errno::ECONNRESET => ErrorKind::ConnectionReset,
+        abi::errno::EEXIST => ErrorKind::AlreadyExists,
+        abi::errno::EINTR => ErrorKind::Interrupted,
+        abi::errno::EINVAL => ErrorKind::InvalidInput,
+        abi::errno::ENOENT => ErrorKind::NotFound,
+        abi::errno::ENOTCONN => ErrorKind::NotConnected,
+        abi::errno::EPERM => ErrorKind::PermissionDenied,
+        abi::errno::EPIPE => ErrorKind::BrokenPipe,
+        abi::errno::ETIMEDOUT => ErrorKind::TimedOut,
         _ => ErrorKind::Uncategorized,
     }
 }
 
-pub fn cvt(result: i32) -> crate::io::Result<usize> {
-    if result < 0 { Err(crate::io::Error::from_raw_os_error(-result)) } else { Ok(result as usize) }
+#[doc(hidden)]
+pub trait IsNegative {
+    fn is_negative(&self) -> bool;
+    fn negate(&self) -> i32;
+}
+
+macro_rules! impl_is_negative {
+    ($($t:ident)*) => ($(impl IsNegative for $t {
+        fn is_negative(&self) -> bool {
+            *self < 0
+        }
+
+        fn negate(&self) -> i32 {
+            i32::try_from(-(*self)).unwrap()
+        }
+    })*)
+}
+
+impl IsNegative for i32 {
+    fn is_negative(&self) -> bool {
+        *self < 0
+    }
+
+    fn negate(&self) -> i32 {
+        -(*self)
+    }
+}
+impl_is_negative! { i8 i16 i64 isize }
+
+pub fn cvt<T: IsNegative>(t: T) -> crate::io::Result<T> {
+    if t.is_negative() {
+        let e = decode_error_kind(t.negate());
+        Err(crate::io::Error::from(e))
+    } else {
+        Ok(t)
+    }
+}
+
+pub fn cvt_r<T, F>(mut f: F) -> crate::io::Result<T>
+where
+    T: IsNegative,
+    F: FnMut() -> T,
+{
+    loop {
+        match cvt(f()) {
+            Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
+            other => return other,
+        }
+    }
 }
diff --git a/library/std/src/sys/hermit/net.rs b/library/std/src/sys/hermit/net.rs
index 8a13879d8cc..5fb6281aa1e 100644
--- a/library/std/src/sys/hermit/net.rs
+++ b/library/std/src/sys/hermit/net.rs
@@ -1,490 +1,353 @@
-use crate::fmt;
-use crate::io::{self, ErrorKind, IoSlice, IoSliceMut};
-use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
-use crate::str;
-use crate::sync::Arc;
-use crate::sys::hermit::abi;
-use crate::sys::hermit::abi::IpAddress::{Ipv4, Ipv6};
-use crate::sys::unsupported;
-use crate::sys_common::AsInner;
+#![allow(dead_code)]
+
+use crate::cmp;
+use crate::io::{self, IoSlice, IoSliceMut};
+use crate::mem;
+use crate::net::{Shutdown, SocketAddr};
+use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, RawFd};
+use crate::sys::hermit::fd::FileDesc;
+use crate::sys::time::Instant;
+use crate::sys_common::net::{getsockopt, setsockopt, sockaddr_to_addr};
+use crate::sys_common::{AsInner, FromInner, IntoInner};
 use crate::time::Duration;
 
-/// Checks whether the HermitCore's socket interface has been started already, and
-/// if not, starts it.
-pub fn init() -> io::Result<()> {
-    if abi::network_init() < 0 {
-        return Err(io::const_io_error!(
-            ErrorKind::Uncategorized,
-            "Unable to initialize network interface",
-        ));
-    }
-
-    Ok(())
-}
-
-#[derive(Debug, Clone)]
-pub struct Socket(abi::Handle);
-
-impl AsInner<abi::Handle> for Socket {
-    fn as_inner(&self) -> &abi::Handle {
-        &self.0
-    }
-}
+use core::ffi::c_int;
 
-impl Drop for Socket {
-    fn drop(&mut self) {
-        let _ = abi::tcpstream::close(self.0);
-    }
-}
+#[allow(unused_extern_crates)]
+pub extern crate hermit_abi as netc;
 
-// Arc is used to count the number of used sockets.
-// Only if all sockets are released, the drop
-// method will close the socket.
-#[derive(Clone)]
-pub struct TcpStream(Arc<Socket>);
-
-impl TcpStream {
-    pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
-        let addr = addr?;
-
-        match abi::tcpstream::connect(addr.ip().to_string().as_bytes(), addr.port(), None) {
-            Ok(handle) => Ok(TcpStream(Arc::new(Socket(handle)))),
-            _ => Err(io::const_io_error!(
-                ErrorKind::Uncategorized,
-                "Unable to initiate a connection on a socket",
-            )),
-        }
-    }
+pub use crate::sys::{cvt, cvt_r};
 
-    pub fn connect_timeout(saddr: &SocketAddr, duration: Duration) -> io::Result<TcpStream> {
-        match abi::tcpstream::connect(
-            saddr.ip().to_string().as_bytes(),
-            saddr.port(),
-            Some(duration.as_millis() as u64),
-        ) {
-            Ok(handle) => Ok(TcpStream(Arc::new(Socket(handle)))),
-            _ => Err(io::const_io_error!(
-                ErrorKind::Uncategorized,
-                "Unable to initiate a connection on a socket",
-            )),
-        }
-    }
+pub type wrlen_t = usize;
 
-    pub fn set_read_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
-        abi::tcpstream::set_read_timeout(*self.0.as_inner(), duration.map(|d| d.as_millis() as u64))
-            .map_err(|_| {
-                io::const_io_error!(ErrorKind::Uncategorized, "Unable to set timeout value")
-            })
+pub fn cvt_gai(err: i32) -> io::Result<()> {
+    if err == 0 {
+        return Ok(());
     }
 
-    pub fn set_write_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
-        abi::tcpstream::set_write_timeout(
-            *self.0.as_inner(),
-            duration.map(|d| d.as_millis() as u64),
-        )
-        .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "Unable to set timeout value"))
-    }
+    let detail = "";
 
-    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
-        let duration = abi::tcpstream::get_read_timeout(*self.0.as_inner()).map_err(|_| {
-            io::const_io_error!(ErrorKind::Uncategorized, "Unable to determine timeout value")
-        })?;
+    Err(io::Error::new(
+        io::ErrorKind::Uncategorized,
+        &format!("failed to lookup address information: {detail}")[..],
+    ))
+}
 
-        Ok(duration.map(|d| Duration::from_millis(d)))
+/// Checks whether the HermitCore's socket interface has been started already, and
+/// if not, starts it.
+pub fn init() {
+    if unsafe { netc::network_init() } < 0 {
+        panic!("Unable to initialize network interface");
     }
+}
 
-    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
-        let duration = abi::tcpstream::get_write_timeout(*self.0.as_inner()).map_err(|_| {
-            io::const_io_error!(ErrorKind::Uncategorized, "Unable to determine timeout value")
-        })?;
+#[derive(Debug)]
+pub struct Socket(FileDesc);
 
-        Ok(duration.map(|d| Duration::from_millis(d)))
+impl Socket {
+    pub fn new(addr: &SocketAddr, ty: i32) -> io::Result<Socket> {
+        let fam = match *addr {
+            SocketAddr::V4(..) => netc::AF_INET,
+            SocketAddr::V6(..) => netc::AF_INET6,
+        };
+        Socket::new_raw(fam, ty)
     }
 
-    pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
-        abi::tcpstream::peek(*self.0.as_inner(), buf)
-            .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "peek failed"))
+    pub fn new_raw(fam: i32, ty: i32) -> io::Result<Socket> {
+        let fd = cvt(unsafe { netc::socket(fam, ty, 0) })?;
+        Ok(Socket(unsafe { FileDesc::from_raw_fd(fd) }))
     }
 
-    pub fn read(&self, buffer: &mut [u8]) -> io::Result<usize> {
-        self.read_vectored(&mut [IoSliceMut::new(buffer)])
+    pub fn new_pair(_fam: i32, _ty: i32) -> io::Result<(Socket, Socket)> {
+        unimplemented!()
     }
 
-    pub fn read_vectored(&self, ioslice: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        let mut size: usize = 0;
-
-        for i in ioslice.iter_mut() {
-            let ret = abi::tcpstream::read(*self.0.as_inner(), &mut i[0..]).map_err(|_| {
-                io::const_io_error!(ErrorKind::Uncategorized, "Unable to read on socket")
-            })?;
+    pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> {
+        self.set_nonblocking(true)?;
+        let r = unsafe {
+            let (addr, len) = addr.into_inner();
+            cvt(netc::connect(self.as_raw_fd(), addr.as_ptr(), len))
+        };
+        self.set_nonblocking(false)?;
 
-            if ret != 0 {
-                size += ret;
-            }
+        match r {
+            Ok(_) => return Ok(()),
+            // there's no ErrorKind for EINPROGRESS :(
+            Err(ref e) if e.raw_os_error() == Some(netc::errno::EINPROGRESS) => {}
+            Err(e) => return Err(e),
         }
 
-        Ok(size)
-    }
-
-    #[inline]
-    pub fn is_read_vectored(&self) -> bool {
-        true
-    }
-
-    pub fn write(&self, buffer: &[u8]) -> io::Result<usize> {
-        self.write_vectored(&[IoSlice::new(buffer)])
-    }
+        let mut pollfd = netc::pollfd { fd: self.as_raw_fd(), events: netc::POLLOUT, revents: 0 };
 
-    pub fn write_vectored(&self, ioslice: &[IoSlice<'_>]) -> io::Result<usize> {
-        let mut size: usize = 0;
-
-        for i in ioslice.iter() {
-            size += abi::tcpstream::write(*self.0.as_inner(), i).map_err(|_| {
-                io::const_io_error!(ErrorKind::Uncategorized, "Unable to write on socket")
-            })?;
+        if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
+            return Err(io::const_io_error!(
+                io::ErrorKind::InvalidInput,
+                "cannot set a 0 duration timeout",
+            ));
         }
 
-        Ok(size)
-    }
-
-    #[inline]
-    pub fn is_write_vectored(&self) -> bool {
-        true
-    }
-
-    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
-        let (ipaddr, port) = abi::tcpstream::peer_addr(*self.0.as_inner())
-            .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "peer_addr failed"))?;
+        let start = Instant::now();
 
-        let saddr = match ipaddr {
-            Ipv4(ref addr) => SocketAddr::new(IpAddr::V4(Ipv4Addr::from(addr.0)), port),
-            Ipv6(ref addr) => SocketAddr::new(IpAddr::V6(Ipv6Addr::from(addr.0)), port),
-            _ => {
-                return Err(io::const_io_error!(ErrorKind::Uncategorized, "peer_addr failed"));
+        loop {
+            let elapsed = start.elapsed();
+            if elapsed >= timeout {
+                return Err(io::const_io_error!(io::ErrorKind::TimedOut, "connection timed out"));
             }
-        };
-
-        Ok(saddr)
-    }
-
-    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        unsupported()
-    }
-
-    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
-        abi::tcpstream::shutdown(*self.0.as_inner(), how as i32)
-            .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "unable to shutdown socket"))
-    }
-
-    pub fn duplicate(&self) -> io::Result<TcpStream> {
-        Ok(self.clone())
-    }
-
-    pub fn set_linger(&self, _linger: Option<Duration>) -> io::Result<()> {
-        unsupported()
-    }
-
-    pub fn linger(&self) -> io::Result<Option<Duration>> {
-        unsupported()
-    }
-
-    pub fn set_nodelay(&self, mode: bool) -> io::Result<()> {
-        abi::tcpstream::set_nodelay(*self.0.as_inner(), mode)
-            .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "set_nodelay failed"))
-    }
-
-    pub fn nodelay(&self) -> io::Result<bool> {
-        abi::tcpstream::nodelay(*self.0.as_inner())
-            .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "nodelay failed"))
-    }
-
-    pub fn set_ttl(&self, tll: u32) -> io::Result<()> {
-        abi::tcpstream::set_tll(*self.0.as_inner(), tll)
-            .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "unable to set TTL"))
-    }
-
-    pub fn ttl(&self) -> io::Result<u32> {
-        abi::tcpstream::get_tll(*self.0.as_inner())
-            .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "unable to get TTL"))
-    }
 
-    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        unsupported()
-    }
-
-    pub fn set_nonblocking(&self, mode: bool) -> io::Result<()> {
-        abi::tcpstream::set_nonblocking(*self.0.as_inner(), mode).map_err(|_| {
-            io::const_io_error!(ErrorKind::Uncategorized, "unable to set blocking mode")
-        })
-    }
-}
-
-impl fmt::Debug for TcpStream {
-    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        Ok(())
-    }
-}
-
-#[derive(Clone)]
-pub struct TcpListener(SocketAddr);
-
-impl TcpListener {
-    pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
-        let addr = addr?;
-
-        Ok(TcpListener(*addr))
-    }
-
-    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        Ok(self.0)
-    }
-
-    pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
-        let (handle, ipaddr, port) = abi::tcplistener::accept(self.0.port())
-            .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "accept failed"))?;
-        let saddr = match ipaddr {
-            Ipv4(ref addr) => SocketAddr::new(IpAddr::V4(Ipv4Addr::from(addr.0)), port),
-            Ipv6(ref addr) => SocketAddr::new(IpAddr::V6(Ipv6Addr::from(addr.0)), port),
-            _ => {
-                return Err(io::const_io_error!(ErrorKind::Uncategorized, "accept failed"));
+            let timeout = timeout - elapsed;
+            let mut timeout = timeout
+                .as_secs()
+                .saturating_mul(1_000)
+                .saturating_add(timeout.subsec_nanos() as u64 / 1_000_000);
+            if timeout == 0 {
+                timeout = 1;
             }
-        };
-
-        Ok((TcpStream(Arc::new(Socket(handle))), saddr))
-    }
 
-    pub fn duplicate(&self) -> io::Result<TcpListener> {
-        Ok(self.clone())
-    }
-
-    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
-        unsupported()
-    }
-
-    pub fn ttl(&self) -> io::Result<u32> {
-        unsupported()
-    }
-
-    pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
-        unsupported()
+            let timeout = cmp::min(timeout, c_int::MAX as u64) as c_int;
+
+            match unsafe { netc::poll(&mut pollfd, 1, timeout) } {
+                -1 => {
+                    let err = io::Error::last_os_error();
+                    if err.kind() != io::ErrorKind::Interrupted {
+                        return Err(err);
+                    }
+                }
+                0 => {}
+                _ => {
+                    // linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look
+                    // for POLLHUP rather than read readiness
+                    if pollfd.revents & netc::POLLHUP != 0 {
+                        let e = self.take_error()?.unwrap_or_else(|| {
+                            io::const_io_error!(
+                                io::ErrorKind::Uncategorized,
+                                "no error set after POLLHUP",
+                            )
+                        });
+                        return Err(e);
+                    }
+
+                    return Ok(());
+                }
+            }
+        }
     }
 
-    pub fn only_v6(&self) -> io::Result<bool> {
-        unsupported()
+    pub fn accept(
+        &self,
+        storage: *mut netc::sockaddr,
+        len: *mut netc::socklen_t,
+    ) -> io::Result<Socket> {
+        let fd = cvt(unsafe { netc::accept(self.0.as_raw_fd(), storage, len) })?;
+        Ok(Socket(unsafe { FileDesc::from_raw_fd(fd) }))
     }
 
-    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        unsupported()
+    pub fn duplicate(&self) -> io::Result<Socket> {
+        let fd = cvt(unsafe { netc::dup(self.0.as_raw_fd()) })?;
+        Ok(Socket(unsafe { FileDesc::from_raw_fd(fd) }))
     }
 
-    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
-        unsupported()
+    fn recv_with_flags(&self, buf: &mut [u8], flags: i32) -> io::Result<usize> {
+        let ret =
+            cvt(unsafe { netc::recv(self.0.as_raw_fd(), buf.as_mut_ptr(), buf.len(), flags) })?;
+        Ok(ret as usize)
     }
-}
 
-impl fmt::Debug for TcpListener {
-    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        Ok(())
+    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
+        self.recv_with_flags(buf, 0)
     }
-}
-
-pub struct UdpSocket(abi::Handle);
 
-impl UdpSocket {
-    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
-        unsupported()
+    pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
+        self.recv_with_flags(buf, netc::MSG_PEEK)
     }
 
-    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
-        unsupported()
-    }
+    pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        let mut size: isize = 0;
 
-    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        unsupported()
-    }
+        for i in bufs.iter_mut() {
+            let ret: isize =
+                cvt(unsafe { netc::read(self.0.as_raw_fd(), i.as_mut_ptr(), i.len()) })?;
 
-    pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
-        unsupported()
-    }
+            if ret != 0 {
+                size += ret;
+            }
+        }
 
-    pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
-        unsupported()
+        Ok(size.try_into().unwrap())
     }
 
-    pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
-        unsupported()
+    #[inline]
+    pub fn is_read_vectored(&self) -> bool {
+        true
     }
 
-    pub fn duplicate(&self) -> io::Result<UdpSocket> {
-        unsupported()
-    }
+    fn recv_from_with_flags(&self, buf: &mut [u8], flags: i32) -> io::Result<(usize, SocketAddr)> {
+        let mut storage: netc::sockaddr_storage = unsafe { mem::zeroed() };
+        let mut addrlen = mem::size_of_val(&storage) as netc::socklen_t;
 
-    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-        unsupported()
+        let n = cvt(unsafe {
+            netc::recvfrom(
+                self.as_raw_fd(),
+                buf.as_mut_ptr(),
+                buf.len(),
+                flags,
+                &mut storage as *mut _ as *mut _,
+                &mut addrlen,
+            )
+        })?;
+        Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?))
     }
 
-    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-        unsupported()
+    pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
+        self.recv_from_with_flags(buf, 0)
     }
 
-    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
-        unsupported()
+    pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
+        self.recv_from_with_flags(buf, netc::MSG_PEEK)
     }
 
-    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
-        unsupported()
+    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
+        let sz = cvt(unsafe { netc::write(self.0.as_raw_fd(), buf.as_ptr(), buf.len()) })?;
+        Ok(sz.try_into().unwrap())
     }
 
-    pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
-        unsupported()
-    }
+    pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        let mut size: isize = 0;
 
-    pub fn broadcast(&self) -> io::Result<bool> {
-        unsupported()
-    }
+        for i in bufs.iter() {
+            size += cvt(unsafe { netc::write(self.0.as_raw_fd(), i.as_ptr(), i.len()) })?;
+        }
 
-    pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
-        unsupported()
+        Ok(size.try_into().unwrap())
     }
 
-    pub fn multicast_loop_v4(&self) -> io::Result<bool> {
-        unsupported()
+    pub fn is_write_vectored(&self) -> bool {
+        true
     }
 
-    pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
-        unsupported()
-    }
+    pub fn set_timeout(&self, dur: Option<Duration>, kind: i32) -> io::Result<()> {
+        let timeout = match dur {
+            Some(dur) => {
+                if dur.as_secs() == 0 && dur.subsec_nanos() == 0 {
+                    return Err(io::const_io_error!(
+                        io::ErrorKind::InvalidInput,
+                        "cannot set a 0 duration timeout",
+                    ));
+                }
+
+                let secs = if dur.as_secs() > netc::time_t::MAX as u64 {
+                    netc::time_t::MAX
+                } else {
+                    dur.as_secs() as netc::time_t
+                };
+                let mut timeout = netc::timeval {
+                    tv_sec: secs,
+                    tv_usec: dur.subsec_micros() as netc::suseconds_t,
+                };
+                if timeout.tv_sec == 0 && timeout.tv_usec == 0 {
+                    timeout.tv_usec = 1;
+                }
+                timeout
+            }
+            None => netc::timeval { tv_sec: 0, tv_usec: 0 },
+        };
 
-    pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
-        unsupported()
+        setsockopt(self, netc::SOL_SOCKET, kind, timeout)
     }
 
-    pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
-        unsupported()
+    pub fn timeout(&self, kind: i32) -> io::Result<Option<Duration>> {
+        let raw: netc::timeval = getsockopt(self, netc::SOL_SOCKET, kind)?;
+        if raw.tv_sec == 0 && raw.tv_usec == 0 {
+            Ok(None)
+        } else {
+            let sec = raw.tv_sec as u64;
+            let nsec = (raw.tv_usec as u32) * 1000;
+            Ok(Some(Duration::new(sec, nsec)))
+        }
     }
 
-    pub fn multicast_loop_v6(&self) -> io::Result<bool> {
-        unsupported()
+    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
+        let how = match how {
+            Shutdown::Write => netc::SHUT_WR,
+            Shutdown::Read => netc::SHUT_RD,
+            Shutdown::Both => netc::SHUT_RDWR,
+        };
+        cvt(unsafe { netc::shutdown_socket(self.as_raw_fd(), how) })?;
+        Ok(())
     }
 
-    pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
-        unsupported()
-    }
+    pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> {
+        let linger = netc::linger {
+            l_onoff: linger.is_some() as i32,
+            l_linger: linger.unwrap_or_default().as_secs() as libc::c_int,
+        };
 
-    pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
-        unsupported()
+        setsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER, linger)
     }
 
-    pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
-        unsupported()
-    }
+    pub fn linger(&self) -> io::Result<Option<Duration>> {
+        let val: netc::linger = getsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER)?;
 
-    pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
-        unsupported()
+        Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64)))
     }
 
-    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
-        unsupported()
+    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
+        let value: i32 = if nodelay { 1 } else { 0 };
+        setsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY, value)
     }
 
-    pub fn ttl(&self) -> io::Result<u32> {
-        unsupported()
+    pub fn nodelay(&self) -> io::Result<bool> {
+        let raw: i32 = getsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY)?;
+        Ok(raw != 0)
+    }
+
+    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
+        let mut nonblocking: i32 = if nonblocking { 1 } else { 0 };
+        cvt(unsafe {
+            netc::ioctl(
+                self.as_raw_fd(),
+                netc::FIONBIO,
+                &mut nonblocking as *mut _ as *mut core::ffi::c_void,
+            )
+        })
+        .map(drop)
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        unsupported()
-    }
-
-    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
-        unsupported()
-    }
-
-    pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
-        unsupported()
-    }
-
-    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
-        unsupported()
+        unimplemented!()
     }
 
-    pub fn send(&self, _: &[u8]) -> io::Result<usize> {
-        unsupported()
-    }
-
-    pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
-        unsupported()
+    // This is used by sys_common code to abstract over Windows and Unix.
+    pub fn as_raw(&self) -> RawFd {
+        self.0.as_raw_fd()
     }
 }
 
-impl fmt::Debug for UdpSocket {
-    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        Ok(())
+impl AsInner<FileDesc> for Socket {
+    fn as_inner(&self) -> &FileDesc {
+        &self.0
     }
 }
 
-pub struct LookupHost(!);
-
-impl LookupHost {
-    pub fn port(&self) -> u16 {
+impl IntoInner<FileDesc> for Socket {
+    fn into_inner(self) -> FileDesc {
         self.0
     }
 }
 
-impl Iterator for LookupHost {
-    type Item = SocketAddr;
-    fn next(&mut self) -> Option<SocketAddr> {
-        self.0
+impl FromInner<FileDesc> for Socket {
+    fn from_inner(file_desc: FileDesc) -> Self {
+        Self(file_desc)
     }
 }
 
-impl TryFrom<&str> for LookupHost {
-    type Error = io::Error;
-
-    fn try_from(_v: &str) -> io::Result<LookupHost> {
-        unsupported()
+impl AsFd for Socket {
+    fn as_fd(&self) -> BorrowedFd<'_> {
+        self.0.as_fd()
     }
 }
 
-impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
-    type Error = io::Error;
-
-    fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> {
-        unsupported()
+impl AsRawFd for Socket {
+    fn as_raw_fd(&self) -> RawFd {
+        self.0.as_raw_fd()
     }
 }
-
-#[allow(nonstandard_style)]
-pub mod netc {
-    pub const AF_INET: u8 = 0;
-    pub const AF_INET6: u8 = 1;
-    pub type sa_family_t = u8;
-
-    #[derive(Copy, Clone)]
-    pub struct in_addr {
-        pub s_addr: u32,
-    }
-
-    #[derive(Copy, Clone)]
-    pub struct sockaddr_in {
-        pub sin_family: sa_family_t,
-        pub sin_port: u16,
-        pub sin_addr: in_addr,
-    }
-
-    #[derive(Copy, Clone)]
-    pub struct in6_addr {
-        pub s6_addr: [u8; 16],
-    }
-
-    #[derive(Copy, Clone)]
-    pub struct sockaddr_in6 {
-        pub sin6_family: sa_family_t,
-        pub sin6_port: u16,
-        pub sin6_addr: in6_addr,
-        pub sin6_flowinfo: u32,
-        pub sin6_scope_id: u32,
-    }
-
-    #[derive(Copy, Clone)]
-    pub struct sockaddr {}
-}
diff --git a/library/std/src/sys/hermit/os.rs b/library/std/src/sys/hermit/os.rs
index 8f927df85be..e53dbae6119 100644
--- a/library/std/src/sys/hermit/os.rs
+++ b/library/std/src/sys/hermit/os.rs
@@ -4,7 +4,7 @@ use crate::ffi::{CStr, OsStr, OsString};
 use crate::fmt;
 use crate::io;
 use crate::marker::PhantomData;
-use crate::os::unix::ffi::OsStringExt;
+use crate::os::hermit::ffi::OsStringExt;
 use crate::path::{self, PathBuf};
 use crate::str;
 use crate::sync::Mutex;
diff --git a/library/std/src/sys/hermit/time.rs b/library/std/src/sys/hermit/time.rs
index c17e6c8af62..32ddc4346ee 100644
--- a/library/std/src/sys/hermit/time.rs
+++ b/library/std/src/sys/hermit/time.rs
@@ -1,6 +1,7 @@
 #![allow(dead_code)]
 
 use crate::cmp::Ordering;
+use crate::ops::{Add, AddAssign, Sub, SubAssign};
 use crate::sys::hermit::abi;
 use crate::sys::hermit::abi::timespec;
 use crate::sys::hermit::abi::{CLOCK_MONOTONIC, CLOCK_REALTIME, NSEC_PER_SEC};
@@ -102,55 +103,122 @@ impl Hash for Timespec {
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
-pub struct Instant {
-    t: Timespec,
-}
+pub struct Instant(Timespec);
 
 impl Instant {
     pub fn now() -> Instant {
         let mut time: Timespec = Timespec::zero();
         let _ = unsafe { abi::clock_gettime(CLOCK_MONOTONIC, &mut time.t as *mut timespec) };
 
-        Instant { t: time }
+        Instant(time)
+    }
+
+    #[stable(feature = "time2", since = "1.8.0")]
+    pub fn elapsed(&self) -> Duration {
+        Instant::now() - *self
+    }
+
+    pub fn duration_since(&self, earlier: Instant) -> Duration {
+        self.checked_duration_since(earlier).unwrap_or_default()
+    }
+
+    pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> {
+        self.checked_sub_instant(&earlier)
     }
 
     pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
-        self.t.sub_timespec(&other.t).ok()
+        self.0.sub_timespec(&other.0).ok()
     }
 
     pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
-        Some(Instant { t: self.t.checked_add_duration(other)? })
+        Some(Instant(self.0.checked_add_duration(other)?))
     }
 
     pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
-        Some(Instant { t: self.t.checked_sub_duration(other)? })
+        Some(Instant(self.0.checked_sub_duration(other)?))
+    }
+
+    pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
+        self.0.checked_add_duration(&duration).map(Instant)
+    }
+
+    pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
+        self.0.checked_sub_duration(&duration).map(Instant)
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
-pub struct SystemTime {
-    t: Timespec,
+impl Add<Duration> for Instant {
+    type Output = Instant;
+
+    /// # Panics
+    ///
+    /// This function may panic if the resulting point in time cannot be represented by the
+    /// underlying data structure. See [`Instant::checked_add`] for a version without panic.
+    fn add(self, other: Duration) -> Instant {
+        self.checked_add(other).expect("overflow when adding duration to instant")
+    }
 }
 
-pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() };
+impl AddAssign<Duration> for Instant {
+    fn add_assign(&mut self, other: Duration) {
+        *self = *self + other;
+    }
+}
+
+impl Sub<Duration> for Instant {
+    type Output = Instant;
+
+    fn sub(self, other: Duration) -> Instant {
+        self.checked_sub(other).expect("overflow when subtracting duration from instant")
+    }
+}
+
+impl SubAssign<Duration> for Instant {
+    fn sub_assign(&mut self, other: Duration) {
+        *self = *self - other;
+    }
+}
+
+impl Sub<Instant> for Instant {
+    type Output = Duration;
+
+    /// Returns the amount of time elapsed from another instant to this one,
+    /// or zero duration if that instant is later than this one.
+    ///
+    /// # Panics
+    ///
+    /// Previous rust versions panicked when `other` was later than `self`. Currently this
+    /// method saturates. Future versions may reintroduce the panic in some circumstances.
+    /// See [Monotonicity].
+    ///
+    /// [Monotonicity]: Instant#monotonicity
+    fn sub(self, other: Instant) -> Duration {
+        self.duration_since(other)
+    }
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub struct SystemTime(Timespec);
+
+pub const UNIX_EPOCH: SystemTime = SystemTime(Timespec::zero());
 
 impl SystemTime {
     pub fn now() -> SystemTime {
         let mut time: Timespec = Timespec::zero();
         let _ = unsafe { abi::clock_gettime(CLOCK_REALTIME, &mut time.t as *mut timespec) };
 
-        SystemTime { t: time }
+        SystemTime(time)
     }
 
     pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
-        self.t.sub_timespec(&other.t)
+        self.0.sub_timespec(&other.0)
     }
 
     pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
-        Some(SystemTime { t: self.t.checked_add_duration(other)? })
+        Some(SystemTime(self.0.checked_add_duration(other)?))
     }
 
     pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
-        Some(SystemTime { t: self.t.checked_sub_duration(other)? })
+        Some(SystemTime(self.0.checked_sub_duration(other)?))
     }
 }
diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs
index ab57fba6c9f..66c33d58d6c 100644
--- a/library/std/src/sys/unix/fd.rs
+++ b/library/std/src/sys/unix/fd.rs
@@ -197,11 +197,6 @@ impl FileDesc {
         }
     }
 
-    #[cfg(target_os = "linux")]
-    pub fn get_cloexec(&self) -> io::Result<bool> {
-        unsafe { Ok((cvt(libc::fcntl(self.as_raw_fd(), libc::F_GETFD))? & libc::FD_CLOEXEC) != 0) }
-    }
-
     #[cfg(not(any(
         target_env = "newlib",
         target_os = "solaris",
diff --git a/library/std/src/sys/windows/args.rs b/library/std/src/sys/windows/args.rs
index 6741ae46d32..30356fa8519 100644
--- a/library/std/src/sys/windows/args.rs
+++ b/library/std/src/sys/windows/args.rs
@@ -270,7 +270,7 @@ pub(crate) fn make_bat_command_line(
     // It is necessary to surround the command in an extra pair of quotes,
     // hence the trailing quote here. It will be closed after all arguments
     // have been added.
-    let mut cmd: Vec<u16> = "cmd.exe /c \"".encode_utf16().collect();
+    let mut cmd: Vec<u16> = "cmd.exe /d /c \"".encode_utf16().collect();
 
     // Push the script name surrounded by its quote pair.
     cmd.push(b'"' as u16);
@@ -290,6 +290,15 @@ pub(crate) fn make_bat_command_line(
     // reconstructed by the batch script by default.
     for arg in args {
         cmd.push(' ' as u16);
+        // Make sure to always quote special command prompt characters, including:
+        // * Characters `cmd /?` says require quotes.
+        // * `%` for environment variables, as in `%TMP%`.
+        // * `|<>` pipe/redirect characters.
+        const SPECIAL: &[u8] = b"\t &()[]{}^=;!'+,`~%|<>";
+        let force_quotes = match arg {
+            Arg::Regular(arg) if !force_quotes => arg.bytes().iter().any(|c| SPECIAL.contains(c)),
+            _ => force_quotes,
+        };
         append_arg(&mut cmd, arg, force_quotes)?;
     }
 
diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs
index f58dcf1287b..1d0ab772739 100644
--- a/library/std/src/sys/windows/c.rs
+++ b/library/std/src/sys/windows/c.rs
@@ -539,14 +539,6 @@ pub struct SYMBOLIC_LINK_REPARSE_BUFFER {
     pub PathBuffer: WCHAR,
 }
 
-/// NB: Use carefully! In general using this as a reference is likely to get the
-/// provenance wrong for the `PathBuffer` field!
-#[repr(C)]
-pub struct FILE_NAME_INFO {
-    pub FileNameLength: DWORD,
-    pub FileName: [WCHAR; 1],
-}
-
 #[repr(C)]
 pub struct MOUNT_POINT_REPARSE_BUFFER {
     pub SubstituteNameOffset: c_ushort,
diff --git a/library/std/src/sys/windows/io.rs b/library/std/src/sys/windows/io.rs
index 2cc34c986b9..7fdd1f702e2 100644
--- a/library/std/src/sys/windows/io.rs
+++ b/library/std/src/sys/windows/io.rs
@@ -2,8 +2,7 @@ use crate::marker::PhantomData;
 use crate::mem::size_of;
 use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle};
 use crate::slice;
-use crate::sys::{c, Align8};
-use core;
+use crate::sys::c;
 use libc;
 
 #[derive(Copy, Clone)]
@@ -125,22 +124,33 @@ unsafe fn msys_tty_on(handle: c::HANDLE) -> bool {
         return false;
     }
 
-    const SIZE: usize = size_of::<c::FILE_NAME_INFO>() + c::MAX_PATH * size_of::<c::WCHAR>();
-    let mut name_info_bytes = Align8([0u8; SIZE]);
+    /// Mirrors [`FILE_NAME_INFO`], giving it a fixed length that we can stack
+    /// allocate
+    ///
+    /// [`FILE_NAME_INFO`]: https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_name_info
+    #[repr(C)]
+    #[allow(non_snake_case)]
+    struct FILE_NAME_INFO {
+        FileNameLength: u32,
+        FileName: [u16; c::MAX_PATH as usize],
+    }
+    let mut name_info = FILE_NAME_INFO { FileNameLength: 0, FileName: [0; c::MAX_PATH as usize] };
+    // Safety: buffer length is fixed.
     let res = c::GetFileInformationByHandleEx(
         handle,
         c::FileNameInfo,
-        name_info_bytes.0.as_mut_ptr() as *mut libc::c_void,
-        SIZE as u32,
+        &mut name_info as *mut _ as *mut libc::c_void,
+        size_of::<FILE_NAME_INFO>() as u32,
     );
     if res == 0 {
         return false;
     }
-    let name_info: &c::FILE_NAME_INFO = &*(name_info_bytes.0.as_ptr() as *const c::FILE_NAME_INFO);
-    let name_len = name_info.FileNameLength as usize / 2;
-    // Offset to get the `FileName` field.
-    let name_ptr = name_info_bytes.0.as_ptr().offset(size_of::<c::DWORD>() as isize).cast::<u16>();
-    let s = core::slice::from_raw_parts(name_ptr, name_len);
+
+    // Use `get` because `FileNameLength` can be out of range.
+    let s = match name_info.FileName.get(..name_info.FileNameLength as usize / 2) {
+        None => return false,
+        Some(s) => s,
+    };
     let name = String::from_utf16_lossy(s);
     // Get the file name only.
     let name = name.rsplit('\\').next().unwrap_or(&name);
diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs
index 6b24b0e9aa8..e9c727cbbd1 100644
--- a/library/std/src/sys_common/mod.rs
+++ b/library/std/src/sys_common/mod.rs
@@ -44,7 +44,6 @@ cfg_if::cfg_if! {
 
 cfg_if::cfg_if! {
     if #[cfg(any(target_os = "l4re",
-                 target_os = "hermit",
                  feature = "restricted-std",
                  all(target_family = "wasm", not(target_os = "emscripten")),
                  all(target_vendor = "fortanix", target_env = "sgx")))] {
diff --git a/library/std/src/sys_common/thread_parking/id.rs b/library/std/src/sys_common/thread_parking/id.rs
index e98169597c3..575988ec760 100644
--- a/library/std/src/sys_common/thread_parking/id.rs
+++ b/library/std/src/sys_common/thread_parking/id.rs
@@ -60,7 +60,7 @@ impl Parker {
         if state == PARKED {
             // Loop to guard against spurious wakeups.
             while state == PARKED {
-                park(self.state.as_mut_ptr().addr());
+                park(self.state.as_ptr().addr());
                 state = self.state.load(Acquire);
             }
 
@@ -76,7 +76,7 @@ impl Parker {
 
         let state = self.state.fetch_sub(1, Acquire).wrapping_sub(1);
         if state == PARKED {
-            park_timeout(dur, self.state.as_mut_ptr().addr());
+            park_timeout(dur, self.state.as_ptr().addr());
             // Swap to ensure that we observe all state changes with acquire
             // ordering, even if the state has been changed after the timeout
             // occured.
@@ -99,7 +99,7 @@ impl Parker {
             // and terminated before this call is made. This call then returns an
             // error or wakes up an unrelated thread. The platform API and
             // environment does allow this, however.
-            unpark(tid, self.state.as_mut_ptr().addr());
+            unpark(tid, self.state.as_ptr().addr());
         }
     }
 }
diff --git a/library/std/src/time.rs b/library/std/src/time.rs
index acf9c29083f..5c2e9da70fb 100644
--- a/library/std/src/time.rs
+++ b/library/std/src/time.rs
@@ -352,7 +352,7 @@ impl Instant {
         self.checked_duration_since(earlier).unwrap_or_default()
     }
 
-    /// Returns the amount of time elapsed since this instant was created.
+    /// Returns the amount of time elapsed since this instant.
     ///
     /// # Panics
     ///
@@ -525,8 +525,8 @@ impl SystemTime {
         self.0.sub_time(&earlier.0).map_err(SystemTimeError)
     }
 
-    /// Returns the difference between the clock time when this
-    /// system time was created, and the current clock time.
+    /// Returns the difference from this system time to the
+    /// current clock time.
     ///
     /// This function may fail as the underlying system clock is susceptible to
     /// drift and updates (e.g., the system clock could go backwards), so this
diff --git a/library/std/tests/common/mod.rs b/library/std/tests/common/mod.rs
new file mode 100644
index 00000000000..fce220223a0
--- /dev/null
+++ b/library/std/tests/common/mod.rs
@@ -0,0 +1,58 @@
+#![allow(unused)]
+
+use std::env;
+use std::fs;
+use std::path::{Path, PathBuf};
+use std::thread;
+use rand::RngCore;
+
+/// Copied from `std::test_helpers::test_rng`, since these tests rely on the
+/// seed not being the same for every RNG invocation too.
+#[track_caller]
+pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
+    use core::hash::{BuildHasher, Hash, Hasher};
+    let mut hasher = std::collections::hash_map::RandomState::new().build_hasher();
+    core::panic::Location::caller().hash(&mut hasher);
+    let hc64 = hasher.finish();
+    let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<Vec<u8>>();
+    let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
+    rand::SeedableRng::from_seed(seed)
+}
+
+// Copied from std::sys_common::io
+pub struct TempDir(PathBuf);
+
+impl TempDir {
+    pub fn join(&self, path: &str) -> PathBuf {
+        let TempDir(ref p) = *self;
+        p.join(path)
+    }
+
+    pub fn path(&self) -> &Path {
+        let TempDir(ref p) = *self;
+        p
+    }
+}
+
+impl Drop for TempDir {
+    fn drop(&mut self) {
+        // Gee, seeing how we're testing the fs module I sure hope that we
+        // at least implement this correctly!
+        let TempDir(ref p) = *self;
+        let result = fs::remove_dir_all(p);
+        // Avoid panicking while panicking as this causes the process to
+        // immediately abort, without displaying test results.
+        if !thread::panicking() {
+            result.unwrap();
+        }
+    }
+}
+
+#[track_caller] // for `test_rng`
+pub fn tmpdir() -> TempDir {
+    let p = env::temp_dir();
+    let mut r = test_rng();
+    let ret = p.join(&format!("rust-{}", r.next_u32()));
+    fs::create_dir(&ret).unwrap();
+    TempDir(ret)
+}
diff --git a/library/std/tests/create_dir_all_bare.rs b/library/std/tests/create_dir_all_bare.rs
new file mode 100644
index 00000000000..fe789323f97
--- /dev/null
+++ b/library/std/tests/create_dir_all_bare.rs
@@ -0,0 +1,39 @@
+#![cfg(all(test, not(any(target_os = "emscripten", target_env = "sgx"))))]
+
+//! Note that this test changes the current directory so
+//! should not be in the same process as other tests.
+use std::env;
+use std::fs;
+use std::path::{Path, PathBuf};
+
+mod common;
+
+// On some platforms, setting the current directory will prevent deleting it.
+// So this helper ensures the current directory is reset.
+struct CurrentDir(PathBuf);
+impl CurrentDir {
+    fn new() -> Self {
+        Self(env::current_dir().unwrap())
+    }
+    fn set(&self, path: &Path) {
+        env::set_current_dir(path).unwrap();
+    }
+    fn with(path: &Path, f: impl FnOnce()) {
+        let current_dir = Self::new();
+        current_dir.set(path);
+        f();
+    }
+}
+impl Drop for CurrentDir {
+    fn drop(&mut self) {
+        env::set_current_dir(&self.0).unwrap();
+    }
+}
+
+#[test]
+fn create_dir_all_bare() {
+    let tmpdir = common::tmpdir();
+    CurrentDir::with(tmpdir.path(), || {
+        fs::create_dir_all("create-dir-all-bare").unwrap();
+    });
+}
diff --git a/library/std/tests/env.rs b/library/std/tests/env.rs
index aae2c49d898..96b4f372b8b 100644
--- a/library/std/tests/env.rs
+++ b/library/std/tests/env.rs
@@ -3,18 +3,8 @@ use std::ffi::{OsStr, OsString};
 
 use rand::distributions::{Alphanumeric, DistString};
 
-/// Copied from `std::test_helpers::test_rng`, since these tests rely on the
-/// seed not being the same for every RNG invocation too.
-#[track_caller]
-pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
-    use core::hash::{BuildHasher, Hash, Hasher};
-    let mut hasher = std::collections::hash_map::RandomState::new().build_hasher();
-    core::panic::Location::caller().hash(&mut hasher);
-    let hc64 = hasher.finish();
-    let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<Vec<u8>>();
-    let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
-    rand::SeedableRng::from_seed(seed)
-}
+mod common;
+use common::test_rng;
 
 #[track_caller]
 fn make_rand_name() -> OsString {
diff --git a/library/test/Cargo.toml b/library/test/Cargo.toml
index 61b6f33bce0..18cb023d274 100644
--- a/library/test/Cargo.toml
+++ b/library/test/Cargo.toml
@@ -7,11 +7,9 @@ edition = "2021"
 crate-type = ["dylib", "rlib"]
 
 [dependencies]
-cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
 getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] }
 std = { path = "../std" }
 core = { path = "../core" }
-libc = { version = "0.2", default-features = false }
 panic_unwind = { path = "../panic_unwind" }
 panic_abort = { path = "../panic_abort" }
 
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 952c70cec1c..b33fc02f49c 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -792,7 +792,7 @@ impl<'a> Builder<'a> {
                 run::CollectLicenseMetadata,
                 run::GenerateCopyright,
             ),
-            Kind::Setup => describe!(setup::Profile),
+            Kind::Setup => describe!(setup::Profile, setup::Hook, setup::Link, setup::Vscode),
             Kind::Clean => describe!(clean::CleanAll, clean::Rustc, clean::Std),
             // special-cased in Build::build()
             Kind::Format => vec![],
@@ -1915,6 +1915,13 @@ impl<'a> Builder<'a> {
             }
         }
 
+        if matches!(mode, Mode::Std) {
+            if let Some(mir_opt_level) = self.config.rust_validate_mir_opts {
+                rustflags.arg("-Zvalidate-mir");
+                rustflags.arg(&format!("-Zmir-opt-level={}", mir_opt_level));
+            }
+        }
+
         Cargo { command: cargo, rustflags, rustdocflags, allow_features }
     }
 
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index f0fcdf0d5a0..348d22a9ce6 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -459,72 +459,6 @@ impl Step for StdLink {
         let libdir = builder.sysroot_libdir(target_compiler, target);
         let hostdir = builder.sysroot_libdir(target_compiler, compiler.host);
         add_to_sysroot(builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
-
-        if compiler.stage == 0 {
-            // special handling for stage0, to make `rustup toolchain link` and `x dist --stage 0`
-            // work for stage0-sysroot
-            let sysroot = builder.out.join(&compiler.host.triple).join("stage0-sysroot");
-
-            let host_lib_dir = builder.initial_rustc.ancestors().nth(2).unwrap().join("lib");
-            let host_bin_dir = builder.out.join(&builder.initial_rustc.parent().unwrap());
-            let host_codegen_backends =
-                host_lib_dir.join("rustlib").join(&compiler.host.triple).join("codegen-backends");
-            let sysroot_bin_dir = sysroot.join("bin");
-            let sysroot_lib_dir = sysroot.join("lib");
-            let sysroot_codegen_backends = builder.sysroot_codegen_backends(compiler);
-
-            // Create the `bin` directory in stage0-sysroot
-            t!(fs::create_dir_all(&sysroot_bin_dir));
-
-            // copy bin files from `builder.initial_rustc/./` to `stage0-sysroot/bin`
-            if let Ok(files) = fs::read_dir(&host_bin_dir) {
-                for file in files {
-                    let file = t!(file);
-                    if file.file_name() == "rustfmt" {
-                        // This is when `rustc` and `cargo` are set in `config.toml`
-                        if !file.path().starts_with(&builder.out) {
-                            builder.copy(
-                                &file.path().into_boxed_path(),
-                                &sysroot_bin_dir.join(file.file_name()),
-                            );
-                        } else {
-                            builder.copy(
-                                &builder
-                                    .out
-                                    .join(&compiler.host.triple)
-                                    .join("rustfmt/bin/rustfmt"),
-                                &sysroot_bin_dir.join(file.file_name()),
-                            );
-                        }
-                    } else {
-                        builder.copy(
-                            &file.path().into_boxed_path(),
-                            &sysroot_bin_dir.join(file.file_name()),
-                        );
-                    }
-                }
-            }
-
-            // copy dylib files from `builder.initial_rustc/../lib/*` while excluding the `rustlib` directory to `stage0-sysroot/lib`
-            if let Ok(files) = fs::read_dir(&host_lib_dir) {
-                for file in files {
-                    let file = t!(file);
-                    let path = file.path();
-                    if path.is_file()
-                        && is_dylib(&file.file_name().into_string().unwrap())
-                        && !path.starts_with(sysroot_lib_dir.join("rustlib").into_boxed_path())
-                    {
-                        builder.copy(&path, &sysroot_lib_dir.join(path.file_name().unwrap()));
-                    }
-                }
-            }
-
-            t!(fs::create_dir_all(&sysroot_codegen_backends));
-            // copy `codegen-backends` from `host_lib_dir/rustlib/codegen_backends` to `stage0-sysroot/lib/rustlib/host-triple/codegen-backends` if it exists.
-            if host_codegen_backends.exists() {
-                builder.cp_r(&host_codegen_backends, &sysroot_codegen_backends);
-            }
-        }
     }
 }
 
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 56f96734bbb..4a563bc396d 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -173,6 +173,7 @@ pub struct Config {
     pub rust_profile_use: Option<String>,
     pub rust_profile_generate: Option<String>,
     pub rust_lto: RustcLto,
+    pub rust_validate_mir_opts: Option<u32>,
     pub llvm_profile_use: Option<String>,
     pub llvm_profile_generate: bool,
     pub llvm_libunwind_default: Option<LlvmLibunwind>,
@@ -770,6 +771,7 @@ define_config! {
         // ignored; this is set from an env var set by bootstrap.py
         download_rustc: Option<StringOrBool> = "download-rustc",
         lto: Option<String> = "lto",
+        validate_mir_opts: Option<u32> = "validate-mir-opts",
     }
 }
 
@@ -1149,6 +1151,7 @@ impl Config {
                 .as_deref()
                 .map(|value| RustcLto::from_str(value).unwrap())
                 .unwrap_or_default();
+            config.rust_validate_mir_opts = rust.validate_mir_opts;
         } else {
             config.rust_profile_use = flags.rust_profile_use;
             config.rust_profile_generate = flags.rust_profile_generate;
diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs
index d6592d2d771..d1e2149d3f9 100644
--- a/src/bootstrap/download.rs
+++ b/src/bootstrap/download.rs
@@ -2,7 +2,7 @@ use std::{
     env,
     ffi::{OsStr, OsString},
     fs::{self, File},
-    io::{self, BufRead, BufReader, ErrorKind},
+    io::{BufRead, BufReader, ErrorKind},
     path::{Path, PathBuf},
     process::{Command, Stdio},
 };
@@ -26,14 +26,6 @@ impl Config {
         self.verbose > 0
     }
 
-    pub fn symlink_file<P: AsRef<Path>, Q: AsRef<Path>>(&self, src: P, link: Q) -> io::Result<()> {
-        #[cfg(unix)]
-        use std::os::unix::fs::symlink as symlink_file;
-        #[cfg(windows)]
-        use std::os::windows::fs::symlink_file;
-        if !self.dry_run() { symlink_file(src.as_ref(), link.as_ref()) } else { Ok(()) }
-    }
-
     pub(crate) fn create(&self, path: &Path, s: &str) {
         if self.dry_run() {
             return;
@@ -338,15 +330,6 @@ impl Config {
         let bin_root = self.out.join(host.triple).join("rustfmt");
         let rustfmt_path = bin_root.join("bin").join(exe("rustfmt", host));
         let rustfmt_stamp = bin_root.join(".rustfmt-stamp");
-
-        #[cfg(not(windows))]
-        {
-            let legacy_rustfmt = self.initial_rustc.with_file_name(exe("rustfmt", host));
-            if !legacy_rustfmt.exists() {
-                t!(self.symlink_file(&rustfmt_path, &legacy_rustfmt));
-            }
-        }
-
         if rustfmt_path.exists() && !program_out_of_date(&rustfmt_stamp, &channel) {
             return Some(rustfmt_path);
         }
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index f07e710a9e6..9d1504c34e8 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -554,7 +554,8 @@ Arguments:
             Kind::Setup => {
                 subcommand_help.push_str(&format!(
                     "\n
-x.py setup creates a `config.toml` which changes the defaults for x.py itself.
+x.py setup creates a `config.toml` which changes the defaults for x.py itself,
+as well as setting up a git pre-push hook, VS code config and toolchain link.
 
 Arguments:
     This subcommand accepts a 'profile' to use for builds. For example:
@@ -564,7 +565,13 @@ Arguments:
     The profile is optional and you will be prompted interactively if it is not given.
     The following profiles are available:
 
-{}",
+{}
+
+    To only set up the git hook, VS code or toolchain link, you may use
+        ./x.py setup hook
+        ./x.py setup vscode
+        ./x.py setup link
+",
                     Profile::all_for_help("        ").trim_end()
                 ));
             }
@@ -638,7 +645,7 @@ Arguments:
             }
             Kind::Setup => {
                 let profile = if paths.len() > 1 {
-                    eprintln!("\nerror: At most one profile can be passed to setup\n");
+                    eprintln!("\nerror: At most one option can be passed to setup\n");
                     usage(1, &opts, verbose, &subcommand_help)
                 } else if let Some(path) = paths.pop() {
                     let profile_string = t!(path.into_os_string().into_string().map_err(
diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs
index 615794958d0..ae72a42973c 100644
--- a/src/bootstrap/format.rs
+++ b/src/bootstrap/format.rs
@@ -218,7 +218,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
                     WalkBuilder::new(first)
                 }
             } else {
-                WalkBuilder::new(first)
+                WalkBuilder::new(src.join(first))
             };
 
             for path in &paths[1..] {
@@ -229,7 +229,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
                         walker.add(path);
                     }
                 } else {
-                    walker.add(path);
+                    walker.add(src.join(path));
                 }
             }
 
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index f753720b353..f4abdf1cc57 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -20,6 +20,7 @@ use std::cell::{Cell, RefCell};
 use std::collections::{HashMap, HashSet};
 use std::env;
 use std::fs::{self, File};
+use std::io;
 use std::io::ErrorKind;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
@@ -1406,7 +1407,7 @@ impl Build {
                 src = t!(fs::canonicalize(src));
             } else {
                 let link = t!(fs::read_link(src));
-                t!(self.config.symlink_file(link, dst));
+                t!(self.symlink_file(link, dst));
                 return;
             }
         }
@@ -1524,6 +1525,14 @@ impl Build {
         iter.map(|e| t!(e)).collect::<Vec<_>>().into_iter()
     }
 
+    fn symlink_file<P: AsRef<Path>, Q: AsRef<Path>>(&self, src: P, link: Q) -> io::Result<()> {
+        #[cfg(unix)]
+        use std::os::unix::fs::symlink as symlink_file;
+        #[cfg(windows)]
+        use std::os::windows::fs::symlink_file;
+        if !self.config.dry_run() { symlink_file(src.as_ref(), link.as_ref()) } else { Ok(()) }
+    }
+
     /// Returns if config.ninja is enabled, and checks for ninja existence,
     /// exiting with a nicer error message if not.
     fn ninja(&self) -> bool {
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index d6e63fb937e..21157b02a78 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -516,7 +516,7 @@ impl Step for Llvm {
 
             let lib_llvm = out_dir.join("build").join("lib").join(lib_name);
             if !lib_llvm.exists() {
-                t!(builder.build.config.symlink_file("libLLVM.dylib", &lib_llvm));
+                t!(builder.symlink_file("libLLVM.dylib", &lib_llvm));
             }
         }
 
diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs
index a027139df23..4480bce99d7 100644
--- a/src/bootstrap/setup.rs
+++ b/src/bootstrap/setup.rs
@@ -21,6 +21,7 @@ pub enum Profile {
     Library,
     Tools,
     User,
+    None,
 }
 
 /// A list of historical hashes of `src/etc/vscode_settings.json`.
@@ -41,7 +42,7 @@ impl Profile {
     pub fn all() -> impl Iterator<Item = Self> {
         use Profile::*;
         // N.B. these are ordered by how they are displayed, not alphabetically
-        [Library, Compiler, Codegen, Tools, User].iter().copied()
+        [Library, Compiler, Codegen, Tools, User, None].iter().copied()
     }
 
     pub fn purpose(&self) -> String {
@@ -52,6 +53,7 @@ impl Profile {
             Codegen => "Contribute to the compiler, and also modify LLVM or codegen",
             Tools => "Contribute to tools which depend on the compiler, but do not modify it directly (e.g. rustdoc, clippy, miri)",
             User => "Install Rust from source",
+            None => "Do not modify `config.toml`"
         }
         .to_string()
     }
@@ -71,6 +73,7 @@ impl Profile {
             Profile::Library => "library",
             Profile::Tools => "tools",
             Profile::User => "user",
+            Profile::None => "none",
         }
     }
 }
@@ -87,6 +90,7 @@ impl FromStr for Profile {
             "tools" | "tool" | "rustdoc" | "clippy" | "miri" | "rustfmt" | "rls" => {
                 Ok(Profile::Tools)
             }
+            "none" => Ok(Profile::None),
             _ => Err(format!("unknown profile: '{}'", s)),
         }
     }
@@ -144,17 +148,8 @@ impl Step for Profile {
 }
 
 pub fn setup(config: &Config, profile: Profile) {
-    let stage_path =
-        ["build", config.build.rustc_target_arg(), "stage1"].join(&MAIN_SEPARATOR.to_string());
-
-    if !rustup_installed() && profile != Profile::User {
-        eprintln!("`rustup` is not installed; cannot link `stage1` toolchain");
-    } else if stage_dir_exists(&stage_path[..]) && !config.dry_run() {
-        attempt_toolchain_link(&stage_path[..]);
-    }
-
-    let suggestions = match profile {
-        Profile::Codegen | Profile::Compiler => &["check", "build", "test"][..],
+    let suggestions: &[&str] = match profile {
+        Profile::Codegen | Profile::Compiler | Profile::None => &["check", "build", "test"],
         Profile::Tools => &[
             "check",
             "build",
@@ -167,11 +162,6 @@ pub fn setup(config: &Config, profile: Profile) {
         Profile::User => &["dist", "build"],
     };
 
-    if !config.dry_run() {
-        t!(install_git_hook_maybe(&config));
-        t!(create_vscode_settings_maybe(&config));
-    }
-
     println!();
 
     println!("To get started, try one of the following commands:");
@@ -190,6 +180,9 @@ pub fn setup(config: &Config, profile: Profile) {
 }
 
 fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) {
+    if profile == Profile::None {
+        return;
+    }
     if path.exists() {
         eprintln!();
         eprintln!(
@@ -217,6 +210,41 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) {
     println!("`x.py` will now use the configuration at {}", include_path.display());
 }
 
+/// Creates a toolchain link for stage1 using `rustup`
+#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
+pub struct Link;
+impl Step for Link {
+    type Output = ();
+    const DEFAULT: bool = true;
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.alias("link")
+    }
+    fn make_run(run: RunConfig<'_>) {
+        if run.builder.config.dry_run() {
+            return;
+        }
+        if let [cmd] = &run.paths[..] {
+            if cmd.assert_single_path().path.as_path().as_os_str() == "link" {
+                run.builder.ensure(Link);
+            }
+        }
+    }
+    fn run(self, builder: &Builder<'_>) -> Self::Output {
+        let config = &builder.config;
+        if config.dry_run() {
+            return;
+        }
+        let stage_path =
+            ["build", config.build.rustc_target_arg(), "stage1"].join(&MAIN_SEPARATOR.to_string());
+
+        if !rustup_installed() {
+            eprintln!("`rustup` is not installed; cannot link `stage1` toolchain");
+        } else if stage_dir_exists(&stage_path[..]) && !config.dry_run() {
+            attempt_toolchain_link(&stage_path[..]);
+        }
+    }
+}
+
 fn rustup_installed() -> bool {
     Command::new("rustup")
         .arg("--version")
@@ -394,6 +422,35 @@ fn prompt_user(prompt: &str) -> io::Result<Option<PromptResult>> {
     }
 }
 
+/// Installs `src/etc/pre-push.sh` as a Git hook
+#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
+pub struct Hook;
+
+impl Step for Hook {
+    type Output = ();
+    const DEFAULT: bool = true;
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.alias("hook")
+    }
+    fn make_run(run: RunConfig<'_>) {
+        if run.builder.config.dry_run() {
+            return;
+        }
+        if let [cmd] = &run.paths[..] {
+            if cmd.assert_single_path().path.as_path().as_os_str() == "hook" {
+                run.builder.ensure(Hook);
+            }
+        }
+    }
+    fn run(self, builder: &Builder<'_>) -> Self::Output {
+        let config = &builder.config;
+        if config.dry_run() {
+            return;
+        }
+        t!(install_git_hook_maybe(&config));
+    }
+}
+
 // install a git hook to automatically run tidy, if they want
 fn install_git_hook_maybe(config: &Config) -> io::Result<()> {
     let git = t!(config.git().args(&["rev-parse", "--git-common-dir"]).output().map(|output| {
@@ -432,6 +489,35 @@ undesirable, simply delete the `pre-push` file from .git/hooks."
     Ok(())
 }
 
+/// Sets up or displays `src/etc/vscode_settings.json`
+#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
+pub struct Vscode;
+
+impl Step for Vscode {
+    type Output = ();
+    const DEFAULT: bool = true;
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.alias("vscode")
+    }
+    fn make_run(run: RunConfig<'_>) {
+        if run.builder.config.dry_run() {
+            return;
+        }
+        if let [cmd] = &run.paths[..] {
+            if cmd.assert_single_path().path.as_path().as_os_str() == "vscode" {
+                run.builder.ensure(Vscode);
+            }
+        }
+    }
+    fn run(self, builder: &Builder<'_>) -> Self::Output {
+        let config = &builder.config;
+        if config.dry_run() {
+            return;
+        }
+        t!(create_vscode_settings_maybe(&config));
+    }
+}
+
 /// Create a `.vscode/settings.json` file for rustc development, or just print it
 fn create_vscode_settings_maybe(config: &Config) -> io::Result<()> {
     let (current_hash, historical_hashes) = SETTINGS_HASHES.split_last().unwrap();
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index d30532ef3c6..3c9a154da9a 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -595,7 +595,7 @@ impl Step for Rustdoc {
             features.push("jemalloc".to_string());
         }
 
-        let cargo = prepare_tool_cargo(
+        let mut cargo = prepare_tool_cargo(
             builder,
             build_compiler,
             Mode::ToolRustc,
@@ -606,6 +606,10 @@ impl Step for Rustdoc {
             features.as_slice(),
         );
 
+        if builder.config.rustc_parallel {
+            cargo.rustflag("--cfg=parallel_compiler");
+        }
+
         let msg = tooling_output(
             Mode::ToolRustc,
             "rustdoc",
diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
index 4cc5d9f8a0d..98bd90210d6 100644
--- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile
+++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
@@ -23,6 +23,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
 
 RUN curl -sL https://nodejs.org/dist/v16.9.0/node-v16.9.0-linux-x64.tar.xz | tar -xJ
 ENV PATH="/node-v16.9.0-linux-x64/bin:${PATH}"
+ENV RUST_CONFIGURE_ARGS="--set rust.validate-mir-opts=3"
+
 # Install es-check
 # Pin its version to prevent unrelated CI failures due to future es-check versions.
 RUN npm install es-check@6.1.1 eslint@8.6.0 -g
@@ -38,7 +40,7 @@ COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/
 
 ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1
 ENV SCRIPT python3 ../x.py --stage 2 test src/tools/expand-yaml-anchors && \
-           python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu --all-targets && \
+           python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \
            python3 ../x.py build --stage 0 src/tools/build-manifest && \
            python3 ../x.py test --stage 0 src/tools/compiletest && \
            python3 ../x.py test --stage 0 core alloc std test proc_macro && \
diff --git a/src/ci/docker/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 94ec2401292..9c550b2d728 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.14.3
\ No newline at end of file
+0.14.4
\ No newline at end of file
diff --git a/src/ci/docker/scripts/fuchsia-test-runner.py b/src/ci/docker/scripts/fuchsia-test-runner.py
index a6d84a3c18a..c3d532c4b27 100755
--- a/src/ci/docker/scripts/fuchsia-test-runner.py
+++ b/src/ci/docker/scripts/fuchsia-test-runner.py
@@ -507,9 +507,8 @@ class TestEnvironment:
     bin/{exe_name}={bin_path}
     lib/{libstd_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libstd_name}
     lib/{libtest_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libtest_name}
-    lib/ld.so.1={sdk_dir}/arch/{target_arch}/sysroot/lib/libc.so
-    lib/libzircon.so={sdk_dir}/arch/{target_arch}/sysroot/lib/libzircon.so
-    lib/libfdio.so={sdk_dir}/arch/{target_arch}/lib/libfdio.so
+    lib/ld.so.1={sdk_dir}/arch/{target_arch}/sysroot/dist/lib/ld.so.1
+    lib/libfdio.so={sdk_dir}/arch/{target_arch}/dist/libfdio.so
     """
 
     TEST_ENV_VARS: ClassVar[List[str]] = [
@@ -844,23 +843,34 @@ class TestEnvironment:
             "--",
             "--build-id-dir",
             os.path.join(self.sdk_dir, ".build-id"),
-            "--build-id-dir",
-            os.path.join(self.libs_dir(), ".build-id"),
         ]
 
-        # Add rust source if it's available
-        if args.rust_src is not None:
+        libs_build_id_path = os.path.join(self.libs_dir(), ".build-id")
+        if os.path.exists(libs_build_id_path):
+            # Add .build-id symbols if installed libs have been stripped into a
+            # .build-id directory
             command += [
-                "--build-dir",
-                args.rust_src,
+                "--build-id-dir",
+                libs_build_id_path,
+            ]
+        else:
+            # If no .build-id directory is detected, then assume that the shared
+            # libs contain their debug symbols
+            command += [
+                f"--symbol-path={self.rust_dir}/lib/rustlib/{self.target}/lib",
             ]
 
+        # Add rust source if it's available
+        rust_src_map = None
+        if args.rust_src is not None:
+            # This matches the remapped prefix used by compiletest. There's no
+            # clear way that we can determine this, so it's hard coded.
+            rust_src_map = f"/rustc/FAKE_PREFIX={args.rust_src}"
+
         # Add fuchsia source if it's available
+        fuchsia_src_map = None
         if args.fuchsia_src is not None:
-            command += [
-                "--build-dir",
-                os.path.join(args.fuchsia_src, "out", "default"),
-            ]
+            fuchsia_src_map = f"./../..={args.fuchsia_src}"
 
         # Load debug symbols for the test binary and automatically attach
         if args.test is not None:
@@ -883,7 +893,28 @@ class TestEnvironment:
                 test_name,
             )
 
+            # The fake-test-src-base directory maps to the suite directory
+            # e.g. tests/ui/foo.rs has a path of rust/fake-test-src-base/foo.rs
+            fake_test_src_base = os.path.join(
+                args.rust_src,
+                "fake-test-src-base",
+            )
+            real_test_src_base = os.path.join(
+                args.rust_src,
+                "tests",
+                args.test.split(os.path.sep)[0],
+            )
+            test_src_map = f"{fake_test_src_base}={real_test_src_base}"
+
             with open(self.zxdb_script_path(), mode="w", encoding="utf-8") as f:
+                print(f"set source-map += {test_src_map}", file=f)
+
+                if rust_src_map is not None:
+                    print(f"set source-map += {rust_src_map}", file=f)
+
+                if fuchsia_src_map is not None:
+                    print(f"set source-map += {fuchsia_src_map}", file=f)
+
                 print(f"attach {test_name[:31]}", file=f)
 
             command += [
@@ -900,6 +931,20 @@ class TestEnvironment:
         # Connect to the running emulator with zxdb
         subprocess.run(command, env=self.ffx_cmd_env(), check=False)
 
+    def syslog(self, args):
+        subprocess.run(
+            [
+                self.tool_path("ffx"),
+                "--config",
+                self.ffx_user_config_path(),
+                "log",
+                "--since",
+                "now",
+            ],
+            env=self.ffx_cmd_env(),
+            check=False,
+        )
+
 
 def start(args):
     test_env = TestEnvironment.from_args(args)
@@ -933,6 +978,12 @@ def debug(args):
     return 0
 
 
+def syslog(args):
+    test_env = TestEnvironment.read_from_file()
+    test_env.syslog(args)
+    return 0
+
+
 def main():
     parser = argparse.ArgumentParser()
 
@@ -1028,6 +1079,11 @@ def main():
     )
     debug_parser.set_defaults(func=debug)
 
+    syslog_parser = subparsers.add_parser(
+        "syslog", help="prints the device syslog"
+    )
+    syslog_parser.set_defaults(func=syslog)
+
     args = parser.parse_args()
     return args.func(args)
 
diff --git a/src/doc/index.md b/src/doc/index.md
index bf08960f338..7c97c16c20b 100644
--- a/src/doc/index.md
+++ b/src/doc/index.md
@@ -4,6 +4,20 @@
 nav {
     display: none;
 }
+body {
+    font-family: serif;
+}
+h1, h2, h3, h4, h5, h6 {
+    font-family: sans-serif;
+}
+h3 {
+    font-size: 1.35rem;
+}
+h4 {
+    font-size: 1.1rem;
+}
+
+/* Formatting for docs search bar */
 #search-input {
     width: calc(100% - 58px);
 }
@@ -21,53 +35,74 @@ nav {
 #search-but:hover, #search-input:focus {
     border-color: #55a9ff;
 }
-h2 {
-    font-size: 18px;
+
+/* Formatting for external link icon */
+svg.external-link {
+  display: inline-block;
+  position: relative;
+  vertical-align: super;
+  width: 0.7rem;
+  height: 0.7rem;
+  padding-left: 2px;
+  top: 3px;
 }
 </style>
 
-Welcome to an overview of the documentation provided by the [Rust project].
-All of these projects are managed by the Docs Team; there are other
-unofficial documentation resources as well!
+Welcome to an overview of the documentation provided by the [Rust
+project]. This page contains links to various helpful references,
+most of which are available offline (if opened with `rustup doc`). Many of these
+resources take the form of "books"; we collectively call these "The Rust
+Bookshelf." Some are large, some are small.
 
-Many of these resources take the form of "books"; we collectively call these
-"The Rust Bookshelf." Some are large, some are small.
+All of these books are managed by the Rust Organization, but other unofficial
+documentation resources are included here as well!
 
-# Learn Rust
+If you're just looking for the standard library reference, here it is:
+[Rust API documentation](std/index.html)
 
-If you'd like to learn Rust, this is the spot for you! All of these resources
+
+## Learning Rust
+
+If you'd like to learn Rust, this is the section for you! All of these resources
 assume that you have programmed before, but not in any specific language:
 
-## The Rust Programming Language
+### The Rust Programming Language
 
-Affectionately nicknamed "the book," [The Rust Programming
-Language](book/index.html) will give you an overview of the language from
-first principles. You'll build a few projects along the way, and by the end,
-you'll have a solid grasp of the language.
+Affectionately nicknamed "the book," [The Rust Programming Language](book/index.html)
+will give you an overview of the language from first principles. You'll build a
+few projects along the way, and by the end, you'll have a solid grasp of how to
+use the language.
 
-## Rust By Example
+### Rust By Example
 
 If reading multiple hundreds of pages about a language isn't your style, then
-[Rust By Example](rust-by-example/index.html) has you covered. While the book talks about code with
-a lot of words, RBE shows off a bunch of code, and keeps the talking to a
-minimum. It also includes exercises!
+[Rust By Example](rust-by-example/index.html) has you covered. RBE shows off a
+bunch of code without using a lot of words. It also includes exercises!
+
+### Rustlings
+
+[Rustlings](https://github.com/rust-lang/rustlings) guides you
+through downloading and setting up the Rust toolchain, then provides an
+interactive tool that teaches you how to solve coding challenges in Rust.
+
+### Rust Playground
 
-## Rustlings
+The [Rust Playground](https://play.rust-lang.org) is a great place
+to try out and share small bits of code, or experiment with some of the most
+popular crates.
 
-[Rustlings](https://github.com/rust-lang/rustlings) guides you through downloading and setting up the Rust toolchain,
-and teaches you the basics of reading and writing Rust syntax. It's an
-alternative to Rust by Example that works with your own environment.
 
-# Use Rust
+## Using Rust
 
-Once you've gotten familiar with the language, these resources can help you
-when you're actually using it day-to-day.
+Once you've gotten familiar with the language, these resources can help you put
+it to work.
 
-## The Standard Library
+### The Standard Library
 
-Rust's standard library has [extensive API documentation](std/index.html),
-with explanations of how to use various things, as well as example code for
-accomplishing various tasks.
+Rust's standard library has [extensive API documentation](std/index.html), with
+explanations of how to use various things, as well as example code for
+accomplishing various tasks. Code examples have a "Run" button on hover that
+opens the sample in the playground.
 
 <div>
   <form action="std/index.html" method="get">
@@ -77,76 +112,143 @@ accomplishing various tasks.
   </form>
 </div>
 
-## The Edition Guide
+### Your Personal Documentation
 
-[The Edition Guide](edition-guide/index.html) describes the Rust editions.
+Whenever you are working in a crate, `cargo doc --open` will generate
+documentation for your project _and_ all its dependencies in their correct
+version, and open it in your browser. Add the flag `--document-private-items` to
+also show items not marked `pub`.
 
-## The Rustc Book
+### The Edition Guide
 
-[The Rustc Book](rustc/index.html) describes the Rust compiler, `rustc`.
+[The Edition Guide](edition-guide/index.html) describes the Rust editions and
+their differences.
 
-## The Cargo Book
+### The `rustc` Book
 
-[The Cargo Book](cargo/index.html) is a guide to Cargo, Rust's build tool and dependency manager.
+[The `rustc` Book](rustc/index.html) describes the Rust compiler, `rustc`.
 
-## The Rustdoc Book
+### The Cargo Book
+
+[The Cargo Book](cargo/index.html) is a guide to Cargo, Rust's build tool and
+dependency manager.
+
+### The Rustdoc Book
 
 [The Rustdoc Book](rustdoc/index.html) describes our documentation tool, `rustdoc`.
 
-## The Clippy Book
+### The Clippy Book
 
 [The Clippy Book](clippy/index.html) describes our static analyzer, Clippy.
 
-## Extended Error Listing
+### Extended Error Listing
 
 Many of Rust's errors come with error codes, and you can request extended
-diagnostics from the compiler on those errors. You can also [read them
-here](error_codes/index.html), if you prefer to read them that way.
+diagnostics from the compiler on those errors (with `rustc --explain`). You can
+also read them here if you prefer: [rustc error codes](error_codes/index.html)
+
 
-# Master Rust
+## Mastering Rust
 
 Once you're quite familiar with the language, you may find these advanced
 resources useful.
 
-## The Reference
+### The Reference
 
-[The Reference](reference/index.html) is not a formal spec, but is more detailed and
-comprehensive than the book.
+[The Reference](reference/index.html) is not a formal spec, but is more detailed
+and comprehensive than the book.
 
-## The Style Guide
+### The Style Guide
 
-[The Rust Style Guide](style-guide/index.html) describes the standard formatting of Rust
-code. Most developers use rustfmt to format their code, and rustfmt's default
-formatting matches this style guide.
+[The Rust Style Guide](style-guide/index.html) describes the standard formatting
+of Rust code. Most developers use `cargo fmt` to invoke `rustfmt` and format the
+code automatically (the result matches this style guide).
 
-## The Rustonomicon
+### The Rustonomicon
 
-[The Rustonomicon](nomicon/index.html) is your guidebook to the dark arts of unsafe
-Rust. It's also sometimes called "the 'nomicon."
+[The Rustonomicon](nomicon/index.html) is your guidebook to the dark arts of
+unsafe Rust. It's also sometimes called "the 'nomicon."
 
-## The Unstable Book
+### The Unstable Book
 
-[The Unstable Book](unstable-book/index.html) has documentation for unstable features.
+[The Unstable Book](unstable-book/index.html) has documentation for unstable
+features.
 
-## The `rustc` Contribution Guide
+### The `rustc` Contribution Guide
 
-[The `rustc` Guide](https://rustc-dev-guide.rust-lang.org/) documents how
-the compiler works and how to contribute to it. This is useful if you want to build
-or modify the Rust compiler from source (e.g. to target something non-standard).
+[The `rustc` Guide](https://rustc-dev-guide.rust-lang.org/)
+documents how the compiler works and how to contribute to it. This is useful if
+you want to build or modify the Rust compiler from source (e.g. to target
+something non-standard).
 
-# Specialize Rust
 
-When using Rust in specific domain areas, consider using the following resources tailored to each domain.
+## Specialized Rust
 
-## Embedded Systems
+When using Rust in specific domains, consider using the following resources
+tailored to each area.
 
-When developing for Bare Metal or Embedded Linux systems, you may find these resources maintained by the [Embedded Working Group] useful.
+### Embedded Systems
+
+When developing for Bare Metal or Embedded Linux systems, you may find these
+resources maintained by the [Embedded Working Group] useful.
 
 [Embedded Working Group]: https://github.com/rust-embedded
 
-### The Embedded Rust Book
+#### The Embedded Rust Book
 
-[The Embedded Rust Book] is targeted at developers familiar with embedded development and familiar with Rust, but have not used Rust for embedded development.
+[The Embedded Rust Book] is targeted at developers familiar with embedded
+development and familiar with Rust, but have not used Rust for embedded
+development.
 
 [The Embedded Rust Book]: embedded-book/index.html
 [Rust project]: https://www.rust-lang.org
+
+<script>
+// check if a given link is external
+function isExternalLink(url) {
+  const tmp = document.createElement('a');
+  tmp.href = url;
+  return tmp.host !== window.location.host;
+}
+
+// Add the `external` class to all <a> tags with external links and append the external link SVG
+function updateExternalAnchors() {
+  /*
+    External link SVG from Font-Awesome
+    CC BY-SA 3.0 https://creativecommons.org/licenses/by-sa/3.0
+    via Wikimedia Commons
+  */
+  const svgText = `<svg
+     class='external-link'
+     xmlns='http://www.w3.org/2000/svg'
+     viewBox='0 -256 1850 1850'
+     width='100%'
+     height='100%'>
+       <g transform='matrix(1,0,0,-1,30,1427)'>
+         <path d='M 1408,608 V 288 Q 1408,169 1323.5,84.5 1239,0 1120,
+           0 H 288 Q 169,0 84.5,84.5 0,169 0,288 v 832 Q 0,1239 84.5,1323.5 169,
+           1408 288,1408 h 704 q 14,0 23,-9 9,-9 9,-23 v -64 q 0,-14 -9,-23 -9,
+           -9 -23,-9 H 288 q -66,0 -113,-47 -47,-47 -47,-113 V 288 q 0,-66 47,
+           -113 47,-47 113,-47 h 832 q 66,0 113,47 47,47 47,113 v 320 q 0,14 9,
+           23 9,9 23,9 h 64 q 14,0 23,-9 9,-9 9,-23 z m 384,864 V 960 q 0,
+           -26 -19,-45 -19,-19 -45,-19 -26,0 -45,19 L 1507,1091 855,439 q -10,
+           -10 -23,-10 -13,0 -23,10 L 695,553 q -10,10 -10,23 0,13 10,23 l 652,
+           652 -176,176 q -19,19 -19,45 0,26 19,45 19,19 45,19 h 512 q 26,0 45,
+           -19 19,-19 19,-45 z' style='fill:currentColor' />
+         </g>
+     </svg>`;
+  let allAnchors = document.getElementsByTagName("a");
+
+  for (var i = 0; i < allAnchors.length; ++i) {
+    let anchor = allAnchors[i];
+    if (isExternalLink(anchor.href)) {
+      anchor.classList.add("external");
+      anchor.innerHTML += svgText;
+    }
+  }
+}
+
+// on page load, update external anchors
+document.addEventListener("DOMContentLoaded", updateExternalAnchors);
+
+</script>
diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md
index 0f165b268ba..63dde2aaedd 100644
--- a/src/doc/rustc/src/platform-support/fuchsia.md
+++ b/src/doc/rustc/src/platform-support/fuchsia.md
@@ -687,7 +687,9 @@ Rust compiler locally. See "[Targeting Fuchsia with a compiler built from source
 for the steps to build locally.
 
 You'll also need to download a copy of the Fuchsia SDK. The current minimum
-supported SDK version is [9.20220726.1.1](https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core/linux-amd64/+/version:9.20220726.1.1).
+supported SDK version is [10.20221207.2.89][minimum_supported_sdk_version].
+
+[minimum_supported_sdk_version]: https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core/linux-amd64/+/version:10.20221207.2.89
 
 Fuchsia's test runner interacts with the Fuchsia emulator and is located at
 `src/ci/docker/scripts/fuchsia-test-runner.py`. We can use it to start our
@@ -697,7 +699,7 @@ test environment with:
 src/ci/docker/scripts/fuchsia-test-runner.py start
     --rust ${RUST_SRC_PATH}/install
     --sdk ${SDK_PATH}
-    --target-triple {x86_64-unknown-fuchsia|aarch64-unknown-fuchsia}
+    --target {x86_64-unknown-fuchsia|aarch64-unknown-fuchsia}
 ```
 
 Where `${RUST_SRC_PATH}/install` is the `prefix` set in `config.toml` and
@@ -717,17 +719,11 @@ run the full `tests/ui` test suite:
     --target x86_64-unknown-fuchsia                                           \
     --run=always --jobs 1                                                     \
     --test-args --target-rustcflags                                           \
-    --test-args -L                                                            \
-    --test-args --target-rustcflags                                           \
-    --test-args ${SDK_PATH}/arch/{x64|arm64}/sysroot/lib                      \
-    --test-args --target-rustcflags                                           \
-    --test-args -L                                                            \
+    --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/sysroot/lib             \
     --test-args --target-rustcflags                                           \
-    --test-args ${SDK_PATH}/arch/{x64|arm64}/lib                              \
+    --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/lib                     \
     --test-args --target-rustcflags                                           \
-    --test-args -Cpanic=abort                                                 \
-    --test-args --target-rustcflags                                           \
-    --test-args -Zpanic_abort_tests                                           \
+    --test-args -Clink-arg=--undefined-version                                \
     --test-args --remote-test-client                                          \
     --test-args src/ci/docker/scripts/fuchsia-test-runner.py                  \
 )
@@ -736,7 +732,18 @@ run the full `tests/ui` test suite:
 *Note: The test suite cannot be run in parallel at the moment, so `x.py`
 must be run with `--jobs 1` to ensure only one test runs at a time.*
 
-When finished, the test runner can be used to stop the test environment:
+By default, `x.py` compiles test binaries with `panic=unwind`. If you built your
+Rust toolchain with `-Cpanic=abort`, you need to tell `x.py` to compile test
+binaries with `panic=abort` as well:
+
+```sh
+    --test-args --target-rustcflags                                           \
+    --test-args -Cpanic=abort                                                 \
+    --test-args --target-rustcflags                                           \
+    --test-args -Zpanic_abort_tests                                           \
+```
+
+When finished testing, the test runner can be used to stop the test environment:
 
 ```sh
 src/ci/docker/scripts/fuchsia-test-runner.py stop
@@ -764,8 +771,9 @@ ${SDK_PATH}/tools/${ARCH}/ffx debug connect -- \
 * `--symbol-path` gets required symbol paths, which are
 necessary for stepping through your program.
 
-The "[displaying source code in `zxdb`](#displaying-source-code-in-zxdb)" section describes how you can
-display Rust and/or Fuchsia source code in your debugging session.
+The "[displaying source code in `zxdb`](#displaying-source-code-in-zxdb)"
+section describes how you can display Rust and/or Fuchsia source code in your
+debugging session.
 
 ### Using `zxdb`
 
@@ -866,6 +874,64 @@ ${SDK_PATH}/tools/${ARCH}/ffx debug connect -- \
  Linking to a Fuchsia checkout can help with debugging Fuchsia libraries,
  such as [fdio].
 
+### Debugging the compiler test suite
+
+Debugging the compiler test suite requires some special configuration:
+
+First, we have to properly configure zxdb so it will be able to find debug
+symbols and source information for our test. The test runner can do this for us
+with:
+
+```sh
+src/ci/docker/scripts/fuchsia-test-runner.py debug                            \
+    --rust-src ${RUST_SRC_PATH}                                               \
+    --fuchsia-src ${FUCHSIA_SRC_PATH}                                         \
+    --test ${TEST}
+```
+
+where `${TEST}` is relative to Rust's `tests` directory (e.g. `ui/abi/...`).
+
+This will start a zxdb session that is properly configured for the specific test
+being run. All three arguments are optional, so you can omit `--fuchsia-src` if
+you don't have it downloaded. Now is a good time to set any desired breakpoints,
+like `b main`.
+
+Next, we have to tell `x.py` not to optimize or strip debug symbols from our
+test suite binaries. We can do this by passing some new arguments to `rustc`
+through our `x.py` invocation. The full invocation is:
+
+```sh
+( \
+    source config-env.sh &&                                                   \
+    ./x.py                                                                    \
+    --config config.toml                                                      \
+    --stage=2                                                                 \
+    test tests/${TEST}                                                        \
+    --target x86_64-unknown-fuchsia                                           \
+    --run=always --jobs 1                                                     \
+    --test-args --target-rustcflags                                           \
+    --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/sysroot/lib             \
+    --test-args --target-rustcflags                                           \
+    --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/lib                     \
+    --test-args --target-rustcflags                                           \
+    --test-args -Clink-arg=--undefined-version                                \
+    --test-args --target-rustcflags                                           \
+    --test-args -Cdebuginfo=2                                                 \
+    --test-args --target-rustcflags                                           \
+    --test-args -Copt-level=0                                                 \
+    --test-args --target-rustcflags                                           \
+    --test-args -Cstrip=none                                                  \
+    --test-args --remote-test-client                                          \
+    --test-args src/ci/docker/scripts/fuchsia-test-runner.py                  \
+)
+```
+
+*If you built your Rust toolchain with `panic=abort`, make sure to include the
+previous flags so your test binaries are also compiled with `panic=abort`.*
+
+Upon running this command, the test suite binary will be run and zxdb will
+attach and load any relevant debug symbols.
+
 [Fuchsia team]: https://team-api.infra.rust-lang.org/v1/teams/fuchsia.json
 [Fuchsia]: https://fuchsia.dev/
 [source tree]: https://fuchsia.dev/fuchsia-src/get-started/learn/build
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index 5e592227d49..c48f7998c5a 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -18,7 +18,6 @@ serde_json = "1.0"
 serde = { version = "1.0", features = ["derive"] }
 smallvec = "1.8.1"
 tempfile = "3"
-thin-vec = "0.2.9"
 tracing = "0.1"
 tracing-tree = "0.2.0"
 
diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs
index 81f67672436..bb62660e194 100644
--- a/src/librustdoc/clean/cfg/tests.rs
+++ b/src/librustdoc/clean/cfg/tests.rs
@@ -4,6 +4,7 @@ use rustc_ast::{LitKind, MetaItemLit, Path, StrStyle};
 use rustc_span::create_default_session_globals_then;
 use rustc_span::symbol::{kw, Ident, Symbol};
 use rustc_span::DUMMY_SP;
+use thin_vec::thin_vec;
 
 fn word_cfg(s: &str) -> Cfg {
     Cfg::Cfg(Symbol::intern(s), None)
@@ -34,7 +35,7 @@ macro_rules! dummy_meta_item_list {
     ($name:ident, [$($list:ident),* $(,)?]) => {
         MetaItem {
             path: Path::from_ident(Ident::from_str(stringify!($name))),
-            kind: MetaItemKind::List(vec![
+            kind: MetaItemKind::List(thin_vec![
                 $(
                     NestedMetaItem::MetaItem(
                         dummy_meta_item_word(stringify!($list)),
@@ -48,7 +49,7 @@ macro_rules! dummy_meta_item_list {
     ($name:ident, [$($list:expr),* $(,)?]) => {
         MetaItem {
             path: Path::from_ident(Ident::from_str(stringify!($name))),
-            kind: MetaItemKind::List(vec![
+            kind: MetaItemKind::List(thin_vec![
                 $(
                     NestedMetaItem::MetaItem($list),
                 )*
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 0c70d31ed60..0e8f0cfc518 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -22,9 +22,9 @@ use rustc_hir::PredicateOrigin;
 use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
 use rustc_middle::middle::resolve_bound_vars as rbv;
-use rustc_middle::ty::fold::ir::TypeFolder;
+use rustc_middle::ty::fold::TypeFolder;
 use rustc_middle::ty::InternalSubsts;
-use rustc_middle::ty::TypeVisitable;
+use rustc_middle::ty::TypeVisitableExt;
 use rustc_middle::ty::{self, AdtKind, DefIdTree, EarlyBinder, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_span::hygiene::{AstPass, MacroKind};
@@ -77,7 +77,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
     // This covers the case where somebody does an import which should pull in an item,
     // but there's already an item with the same namespace and same name. Rust gives
     // priority to the not-imported one, so we should, too.
-    items.extend(doc.items.iter().flat_map(|(item, renamed, import_id)| {
+    items.extend(doc.items.values().flat_map(|(item, renamed, import_id)| {
         // First, lower everything other than imports.
         if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
             return Vec::new();
@@ -90,7 +90,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
         }
         v
     }));
-    items.extend(doc.items.iter().flat_map(|(item, renamed, _)| {
+    items.extend(doc.items.values().flat_map(|(item, renamed, _)| {
         // Now we actually lower the imports, skipping everything else.
         if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind {
             let name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id()));
@@ -1661,7 +1661,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
         }
         TyKind::BareFn(barefn) => BareFunction(Box::new(clean_bare_fn_ty(barefn, cx))),
         // Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s.
-        TyKind::Infer | TyKind::Err | TyKind::Typeof(..) => Infer,
+        TyKind::Infer | TyKind::Err(_) | TyKind::Typeof(..) => Infer,
     }
 }
 
@@ -2114,17 +2114,29 @@ fn get_all_import_attributes<'hir>(
     attributes: &mut Vec<ast::Attribute>,
     is_inline: bool,
 ) {
+    let mut first = true;
     let hir_map = tcx.hir();
     let mut visitor = OneLevelVisitor::new(hir_map, target_def_id);
     let mut visited = FxHashSet::default();
+
     // If the item is an import and has at least a path with two parts, we go into it.
     while let hir::ItemKind::Use(path, _) = item.kind && visited.insert(item.hir_id()) {
-        // We add the attributes from this import into the list.
-        add_without_unwanted_attributes(attributes, hir_map.attrs(item.hir_id()), is_inline);
+        if first {
+            // This is the "original" reexport so we get all its attributes without filtering them.
+            attributes.extend_from_slice(hir_map.attrs(item.hir_id()));
+            first = false;
+        } else {
+            add_without_unwanted_attributes(attributes, hir_map.attrs(item.hir_id()), is_inline);
+        }
 
-        let def_id = if path.segments.len() > 1 {
-            match path.segments[path.segments.len() - 2].res {
+        let def_id = if let [.., parent_segment, _] = &path.segments {
+            match parent_segment.res {
                 hir::def::Res::Def(_, def_id) => def_id,
+                _ if parent_segment.ident.name == kw::Crate => {
+                    // In case the "parent" is the crate, it'll give `Res::Err` so we need to
+                    // circumvent it this way.
+                    tcx.parent(item.owner_id.def_id.to_def_id())
+                }
                 _ => break,
             }
         } else {
@@ -2341,9 +2353,7 @@ fn clean_maybe_renamed_item<'tcx>(
         if let Some(import_id) = import_id &&
             let Some(hir::Node::Item(use_node)) = cx.tcx.hir().find_by_def_id(import_id)
         {
-            // First, we add the attributes from the current import.
-            extra_attrs.extend_from_slice(inline::load_attrs(cx, import_id.to_def_id()));
-            let is_inline = extra_attrs.lists(sym::doc).get_word_attr(sym::inline).is_some();
+            let is_inline = inline::load_attrs(cx, import_id.to_def_id()).lists(sym::doc).get_word_attr(sym::inline).is_some();
             // Then we get all the various imports' attributes.
             get_all_import_attributes(use_node, cx.tcx, item.owner_id.def_id, &mut extra_attrs, is_inline);
             add_without_unwanted_attributes(&mut extra_attrs, inline::load_attrs(cx, def_id), is_inline);
diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs
index ed7683e36fd..ef38ca3c16c 100644
--- a/src/librustdoc/clean/render_macro_matchers.rs
+++ b/src/librustdoc/clean/render_macro_matchers.rs
@@ -63,7 +63,8 @@ fn snippet_equal_to_token(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Option<String
     let snippet = source_map.span_to_snippet(span).ok()?;
 
     // Create a Parser.
-    let sess = ParseSess::new(FilePathMapping::empty());
+    let sess =
+        ParseSess::new(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), FilePathMapping::empty());
     let file_name = source_map.span_to_filename(span);
     let mut parser =
         match rustc_parse::maybe_new_parser_from_source_str(&sess, file_name, snippet.clone()) {
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 5a564c2ac1c..c9c1c2c458a 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -470,6 +470,12 @@ pub(crate) fn get_auto_trait_and_blanket_impls(
     cx: &mut DocContext<'_>,
     item_def_id: DefId,
 ) -> impl Iterator<Item = Item> {
+    // FIXME: To be removed once `parallel_compiler` bugs are fixed!
+    // More information in <https://github.com/rust-lang/rust/pull/106930>.
+    if cfg!(parallel_compiler) {
+        return vec![].into_iter().chain(vec![].into_iter());
+    }
+
     let auto_impls = cx
         .sess()
         .prof
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 5ab7056be44..fbfc58a436b 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -115,8 +115,10 @@ pub(crate) fn new_handler(
     diagnostic_width: Option<usize>,
     unstable_opts: &UnstableOptions,
 ) -> rustc_errors::Handler {
-    let fallback_bundle =
-        rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
+    let fallback_bundle = rustc_errors::fallback_fluent_bundle(
+        rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
+        false,
+    );
     let emitter: Box<dyn Emitter + sync::Send> = match error_format {
         ErrorOutputType::HumanReadable(kind) => {
             let (short, color_config) = kind.unzip();
@@ -254,6 +256,7 @@ pub(crate) fn create_config(
         output_file: None,
         output_dir: None,
         file_loader: None,
+        locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES,
         lint_caps,
         parse_sess_created: None,
         register_lints: Some(Box::new(crate::lint::register_lints)),
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 0eba81c7c1e..8a73d25d3f0 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -96,6 +96,7 @@ pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> {
         output_file: None,
         output_dir: None,
         file_loader: None,
+        locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES,
         lint_caps,
         parse_sess_created: None,
         register_lints: Some(Box::new(crate::lint::register_lints)),
@@ -545,8 +546,10 @@ pub(crate) fn make_test(
             // Any errors in parsing should also appear when the doctest is compiled for real, so just
             // send all the errors that librustc_ast emits directly into a `Sink` instead of stderr.
             let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-            let fallback_bundle =
-                rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
+            let fallback_bundle = rustc_errors::fallback_fluent_bundle(
+                rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
+                false,
+            );
             supports_color = EmitterWriter::stderr(
                 ColorConfig::Auto,
                 None,
@@ -741,8 +744,10 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool {
             // Any errors in parsing should also appear when the doctest is compiled for real, so just
             // send all the errors that librustc_ast emits directly into a `Sink` instead of stderr.
             let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-            let fallback_bundle =
-                rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
+            let fallback_bundle = rustc_errors::fallback_fluent_bundle(
+                rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
+                false,
+            );
 
             let emitter = EmitterWriter::new(
                 Box::new(io::sink()),
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index aa406f30cbe..6bdd9db9bfa 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -775,7 +775,7 @@ pub(crate) fn link_tooltip(did: DefId, fragment: &Option<UrlFragment>, cx: &Cont
     let fqp = fqp.iter().map(|sym| sym.as_str()).join("::");
     if let &Some(UrlFragment::Item(id)) = fragment {
         let name = cx.tcx().item_name(id);
-        let descr = cx.tcx().def_kind(id).descr(id);
+        let descr = cx.tcx().def_descr(id);
         format!("{descr} {fqp}::{name}")
     } else {
         format!("{shortty} {fqp}")
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 9ef0b501c08..89f1ad71134 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -552,10 +552,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> SummaryLine<'a, I> {
 }
 
 fn check_if_allowed_tag(t: &Tag<'_>) -> bool {
-    matches!(
-        t,
-        Tag::Paragraph | Tag::Item | Tag::Emphasis | Tag::Strong | Tag::Link(..) | Tag::BlockQuote
-    )
+    matches!(t, Tag::Paragraph | Tag::Emphasis | Tag::Strong | Tag::Link(..) | Tag::BlockQuote)
 }
 
 fn is_forbidden_tag(t: &Tag<'_>) -> bool {
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 910a7190b58..4fcf0873600 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -20,6 +20,7 @@
 #![allow(clippy::collapsible_if, clippy::collapsible_else_if)]
 #![allow(rustc::potential_query_instability)]
 
+extern crate thin_vec;
 #[macro_use]
 extern crate tracing;
 
diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs
index 03be5e79971..26fbb03a43e 100644
--- a/src/librustdoc/passes/lint/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs
@@ -33,8 +33,10 @@ fn check_rust_syntax(
     code_block: RustCodeBlock,
 ) {
     let buffer = Lrc::new(Lock::new(Buffer::default()));
-    let fallback_bundle =
-        rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
+    let fallback_bundle = rustc_errors::fallback_fluent_bundle(
+        rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
+        false,
+    );
     let emitter = BufferEmitter { buffer: Lrc::clone(&buffer), fallback_bundle };
 
     let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 9c1e5f4a3cd..277201e4de9 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -1,7 +1,7 @@
 //! The Rust AST Visitor. Extracts useful information and massages it into a form
 //! usable for `clean`.
 
-use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LocalDefIdSet};
@@ -26,8 +26,12 @@ pub(crate) struct Module<'hir> {
     pub(crate) where_inner: Span,
     pub(crate) mods: Vec<Module<'hir>>,
     pub(crate) def_id: LocalDefId,
-    // (item, renamed, import_id)
-    pub(crate) items: Vec<(&'hir hir::Item<'hir>, Option<Symbol>, Option<LocalDefId>)>,
+    /// The key is the item `ItemId` and the value is: (item, renamed, import_id).
+    /// We use `FxIndexMap` to keep the insert order.
+    pub(crate) items: FxIndexMap<
+        (LocalDefId, Option<Symbol>),
+        (&'hir hir::Item<'hir>, Option<Symbol>, Option<LocalDefId>),
+    >,
     pub(crate) foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option<Symbol>)>,
 }
 
@@ -38,7 +42,7 @@ impl Module<'_> {
             def_id,
             where_inner,
             mods: Vec::new(),
-            items: Vec::new(),
+            items: FxIndexMap::default(),
             foreigns: Vec::new(),
         }
     }
@@ -136,7 +140,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                 inserted.insert(def_id)
             {
                     let item = self.cx.tcx.hir().expect_item(local_def_id);
-                    top_level_module.items.push((item, None, None));
+                    top_level_module.items.insert((local_def_id, Some(item.ident.name)), (item, None, None));
             }
         }
 
@@ -294,7 +298,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         renamed: Option<Symbol>,
         parent_id: Option<LocalDefId>,
     ) {
-        self.modules.last_mut().unwrap().items.push((item, renamed, parent_id))
+        self.modules
+            .last_mut()
+            .unwrap()
+            .items
+            .insert((item.owner_id.def_id, renamed), (item, renamed, parent_id));
     }
 
     fn visit_item_inner(
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 17b3d0de0897e1c6b8ca347bd39f850bb0a5b9f
+Subproject 9d5b32f503fc099c4064298465add14d4bce11e
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index b4543aa2544..644604a2e3f 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -27,7 +27,7 @@ use rustc_middle::mir::{Rvalue, StatementKind};
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
 use rustc_middle::ty::{
     self, Binder, BoundVariableKind, Clause, EarlyBinder, FnSig, GenericArgKind, List, ParamTy, PredicateKind,
-    ProjectionPredicate, Ty, TyCtxt, TypeVisitable, TypeckResults,
+    ProjectionPredicate, Ty, TyCtxt, TypeVisitableExt, TypeckResults,
 };
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::{symbol::sym, Span, Symbol};
@@ -1022,7 +1022,7 @@ fn binding_ty_auto_deref_stability<'tcx>(
                     ))
                     .is_sized(cx.tcx, cx.param_env.without_caller_bounds()),
             ),
-            TyKind::OpaqueDef(..) | TyKind::Infer | TyKind::Typeof(..) | TyKind::TraitObject(..) | TyKind::Err => {
+            TyKind::OpaqueDef(..) | TyKind::Infer | TyKind::Typeof(..) | TyKind::TraitObject(..) | TyKind::Err(_) => {
                 Position::ReborrowStable(precedence)
             },
         };
@@ -1038,7 +1038,7 @@ fn ty_contains_infer(ty: &hir::Ty<'_>) -> bool {
             if self.0
                 || matches!(
                     ty.kind,
-                    TyKind::OpaqueDef(..) | TyKind::Infer | TyKind::Typeof(_) | TyKind::Err
+                    TyKind::OpaqueDef(..) | TyKind::Infer | TyKind::Typeof(_) | TyKind::Err(_)
                 )
             {
                 self.0 = true;
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index 1cdcccd5f14..b8428d66a5d 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -514,7 +514,7 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) ->
     }
 
     ParamEnv::new(
-        tcx.mk_predicates(ty_predicates.iter().map(|&(p, _)| p).chain(
+        tcx.mk_predicates_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain(
             params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| {
                 tcx.mk_predicate(Binder::dummy(PredicateKind::Clause(Clause::Trait(TraitPredicate {
                     trait_ref: tcx.mk_trait_ref(eq_trait_id, [tcx.mk_param_from_def(param)]),
diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs
index 0b31e20fc87..6fdb7de25cc 100644
--- a/src/tools/clippy/clippy_lints/src/doc.rs
+++ b/src/tools/clippy/clippy_lints/src/doc.rs
@@ -704,8 +704,10 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) {
                 let filename = FileName::anon_source_code(&code);
 
                 let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-                let fallback_bundle =
-                    rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
+                let fallback_bundle = rustc_errors::fallback_fluent_bundle(
+                    rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
+                    false
+                );
                 let emitter = EmitterWriter::new(
                     Box::new(io::sink()),
                     None,
diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
index ddade65c515..b2071f4dcb1 100644
--- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs
+++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
@@ -11,7 +11,7 @@ use rustc_hir::{Closure, Expr, ExprKind, Param, PatKind, Unsafety};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
 use rustc_middle::ty::binding::BindingMode;
-use rustc_middle::ty::{self, EarlyBinder, SubstsRef, Ty, TypeVisitable};
+use rustc_middle::ty::{self, EarlyBinder, SubstsRef, Ty, TypeVisitableExt};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::symbol::sym;
 
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 565c5b7af00..9011f0896a0 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -42,6 +42,7 @@ extern crate rustc_session;
 extern crate rustc_span;
 extern crate rustc_target;
 extern crate rustc_trait_selection;
+extern crate thin_vec;
 
 #[macro_use]
 extern crate clippy_utils;
diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
index 14f161f5102..d7e00047312 100644
--- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
@@ -224,7 +224,7 @@ fn never_loop_expr(expr: &Expr<'_>, ignore_ids: &mut Vec<HirId>, main_loop_id: H
         | ExprKind::Path(_)
         | ExprKind::ConstBlock(_)
         | ExprKind::Lit(_)
-        | ExprKind::Err => NeverLoopResult::Otherwise,
+        | ExprKind::Err(_) => NeverLoopResult::Otherwise,
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
index f587c69f730..b33a2478172 100644
--- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
@@ -341,7 +341,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> {
             ExprKind::ConstBlock(_) |
             ExprKind::Continue(_) |
             ExprKind::DropTemps(_) |
-            ExprKind::Err |
+            ExprKind::Err(_) |
             ExprKind::InlineAsm(_) |
             ExprKind::Let(_) |
             ExprKind::Lit(_) |
diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
index 8ddbacc3d7a..0b0c6adc504 100644
--- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
@@ -173,7 +173,7 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) -
         && let Some(iter_item) = cx.tcx
             .associated_items(iter_trait)
             .find_by_name_and_kind(cx.tcx, Ident::with_dummy_span(Symbol::intern("Item")), AssocKind::Type, iter_trait)
-        && let substs = cx.tcx.intern_substs(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))])
+        && let substs = cx.tcx.mk_substs(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))])
         && let proj_ty = cx.tcx.mk_projection(iter_item.def_id, substs)
         && let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, proj_ty)
     {
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
index 4e5af1c7c71..df26b36b7b3 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -414,7 +414,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
                             }
                         });
 
-                        let new_subst = cx.tcx.mk_substs(
+                        let new_subst = cx.tcx.mk_substs_from_iter(
                             call_substs.iter()
                                 .enumerate()
                                 .map(|(i, t)|
diff --git a/src/tools/clippy/clippy_lints/src/mut_key.rs b/src/tools/clippy/clippy_lints/src/mut_key.rs
index 3cc765108d7..5a533261cad 100644
--- a/src/tools/clippy/clippy_lints/src/mut_key.rs
+++ b/src/tools/clippy/clippy_lints/src/mut_key.rs
@@ -3,7 +3,7 @@ use clippy_utils::{def_path_def_ids, trait_ref_of_method};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::TypeVisitable;
+use rustc_middle::ty::TypeVisitableExt;
 use rustc_middle::ty::{Adt, Array, Ref, Slice, Tuple, Ty};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::def_id::LocalDefId;
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
index 996ea6ed723..da3b6fa9899 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
@@ -18,7 +18,7 @@ use rustc_hir_typeck::expr_use_visitor as euv;
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::mir::FakeReadCause;
-use rustc_middle::ty::{self, TypeVisitable};
+use rustc_middle::ty::{self, TypeVisitableExt};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::kw;
diff --git a/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs b/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs
index 24aeb82a37f..d3de9699fe9 100644
--- a/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs
@@ -49,10 +49,10 @@ fn check_op(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool)
             (arg, arg.span)
         },
         ExprKind::Call(path, [arg])
-            if path_def_id(cx, path).map_or(false, |id| {
-                if match_def_path(cx, id, &paths::FROM_STR_METHOD) {
+            if path_def_id(cx, path).map_or(false, |did| {
+                if match_def_path(cx, did, &paths::FROM_STR_METHOD) {
                     true
-                } else if cx.tcx.lang_items().from_fn() == Some(id) {
+                } else if cx.tcx.is_diagnostic_item(sym::from_fn, did) {
                     !is_copy(cx, typeck.expr_ty(expr))
                 } else {
                     false
diff --git a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
index 398329e455b..2fdd775ad48 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
@@ -134,7 +134,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
                 } else if let Some(target_id) = cx.tcx.lang_items().deref_target() {
                     if let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions(
                         cx.param_env,
-                        cx.tcx.mk_projection(target_id, cx.tcx.intern_substs(&[GenericArg::from(indexed_ty)])),
+                        cx.tcx.mk_projection(target_id, cx.tcx.mk_substs(&[GenericArg::from(indexed_ty)])),
                     ) {
                         if deref_ty == expr_ty {
                             let snip = snippet_with_context(cx, indexed.span, ctxt, "..", &mut app).0;
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs
index 54ac04df1c1..6bdb9aa5a26 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs
@@ -6,7 +6,7 @@ use clippy_utils::sugg;
 use rustc_errors::Applicability;
 use rustc_hir::{self as hir, Expr, GenericArg, Mutability, Path, TyKind};
 use rustc_lint::LateContext;
-use rustc_middle::ty::{self, Ty, TypeVisitable};
+use rustc_middle::ty::{self, Ty, TypeVisitableExt};
 
 /// Checks for `transmute_ptr_to_ref` lint.
 /// Returns `true` if it's triggered, otherwise returns `false`.
diff --git a/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs b/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs
index 871c3fadbba..56207fe767c 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs
@@ -4,7 +4,7 @@ use clippy_utils::sugg;
 use rustc_errors::Applicability;
 use rustc_hir::Expr;
 use rustc_lint::LateContext;
-use rustc_middle::ty::{self, Ty, TypeVisitable};
+use rustc_middle::ty::{self, Ty, TypeVisitableExt};
 
 /// Checks for `useless_transmute` lint.
 /// Returns `true` if it's triggered, otherwise returns `false`.
diff --git a/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs b/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs
index f9b9a66b5fa..f7adc9d3555 100644
--- a/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs
+++ b/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs
@@ -5,7 +5,7 @@ use rustc_errors::Applicability;
 use rustc_hir::{self as hir, def_id::DefId, QPath, TyKind};
 use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::LateContext;
-use rustc_middle::ty::TypeVisitable;
+use rustc_middle::ty::TypeVisitableExt;
 use rustc_span::symbol::sym;
 
 use super::{utils, REDUNDANT_ALLOCATION};
diff --git a/src/tools/clippy/clippy_lints/src/types/vec_box.rs b/src/tools/clippy/clippy_lints/src/types/vec_box.rs
index 7a3c7cd8a99..d3062f3d2e3 100644
--- a/src/tools/clippy/clippy_lints/src/types/vec_box.rs
+++ b/src/tools/clippy/clippy_lints/src/types/vec_box.rs
@@ -7,7 +7,7 @@ use rustc_hir::{self as hir, def_id::DefId, GenericArg, QPath, TyKind};
 use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::LateContext;
 use rustc_middle::ty::layout::LayoutOf;
-use rustc_middle::ty::TypeVisitable;
+use rustc_middle::ty::TypeVisitableExt;
 use rustc_span::symbol::sym;
 
 use super::VEC_BOX;
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs b/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs
index 9f207d32fcf..6e802794f5a 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs
@@ -7,6 +7,7 @@ use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::symbol::sym;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -54,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryOwnedEmptyStrings {
                         );
                 } else {
                     if_chain! {
-                        if Some(fun_def_id) == cx.tcx.lang_items().from_fn();
+                        if cx.tcx.is_diagnostic_item(sym::from_fn, fun_def_id);
                         if let [.., last_arg] = args;
                         if let ExprKind::Lit(spanned) = &last_arg.kind;
                         if let LitKind::Str(symbol, _) = spanned.node;
diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
index 7355260ae4a..06d248204c1 100644
--- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
@@ -12,9 +12,9 @@ use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::DUMMY_SP;
-
 use std::cell::Cell;
 use std::mem;
+use thin_vec::{thin_vec, ThinVec};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -214,7 +214,7 @@ macro_rules! always_pat {
 /// Focus on `focus_idx` in `alternatives`,
 /// attempting to extend it with elements of the same constructor `C`
 /// in `alternatives[focus_idx + 1..]`.
-fn transform_with_focus_on_idx(alternatives: &mut Vec<P<Pat>>, focus_idx: usize) -> bool {
+fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: usize) -> bool {
     // Extract the kind; we'll need to make some changes in it.
     let mut focus_kind = mem::replace(&mut alternatives[focus_idx].kind, PatKind::Wild);
     // We'll focus on `alternatives[focus_idx]`,
@@ -296,7 +296,7 @@ fn extend_with_struct_pat(
     fps1: &mut [ast::PatField],
     rest1: bool,
     start: usize,
-    alternatives: &mut Vec<P<Pat>>,
+    alternatives: &mut ThinVec<P<Pat>>,
 ) -> bool {
     (0..fps1.len()).any(|idx| {
         let pos_in_2 = Cell::new(None); // The element `k`.
@@ -336,9 +336,9 @@ fn extend_with_struct_pat(
 fn extend_with_matching_product(
     targets: &mut [P<Pat>],
     start: usize,
-    alternatives: &mut Vec<P<Pat>>,
+    alternatives: &mut ThinVec<P<Pat>>,
     predicate: impl Fn(&PatKind, &[P<Pat>], usize) -> bool,
-    extract: impl Fn(PatKind) -> Vec<P<Pat>>,
+    extract: impl Fn(PatKind) -> ThinVec<P<Pat>>,
 ) -> bool {
     (0..targets.len()).any(|idx| {
         let tail_or = drain_matching(
@@ -365,14 +365,14 @@ fn take_pat(from: &mut Pat) -> Pat {
 
 /// Extend `target` as an or-pattern with the alternatives
 /// in `tail_or` if there are any and return if there were.
-fn extend_with_tail_or(target: &mut Pat, tail_or: Vec<P<Pat>>) -> bool {
-    fn extend(target: &mut Pat, mut tail_or: Vec<P<Pat>>) {
+fn extend_with_tail_or(target: &mut Pat, tail_or: ThinVec<P<Pat>>) -> bool {
+    fn extend(target: &mut Pat, mut tail_or: ThinVec<P<Pat>>) {
         match target {
             // On an existing or-pattern in the target, append to it.
             Pat { kind: Or(ps), .. } => ps.append(&mut tail_or),
             // Otherwise convert the target to an or-pattern.
             target => {
-                let mut init_or = vec![P(take_pat(target))];
+                let mut init_or = thin_vec![P(take_pat(target))];
                 init_or.append(&mut tail_or);
                 target.kind = Or(init_or);
             },
@@ -391,26 +391,42 @@ fn extend_with_tail_or(target: &mut Pat, tail_or: Vec<P<Pat>>) -> bool {
 // Only elements beginning with `start` are considered for extraction.
 fn drain_matching(
     start: usize,
-    alternatives: &mut Vec<P<Pat>>,
+    alternatives: &mut ThinVec<P<Pat>>,
     predicate: impl Fn(&PatKind) -> bool,
     extract: impl Fn(PatKind) -> P<Pat>,
-) -> Vec<P<Pat>> {
-    let mut tail_or = vec![];
+) -> ThinVec<P<Pat>> {
+    let mut tail_or = ThinVec::new();
     let mut idx = 0;
-    for pat in alternatives.drain_filter(|p| {
-        // Check if we should extract, but only if `idx >= start`.
+
+    // If `ThinVec` had the `drain_filter` method, this loop could be rewritten
+    // like so:
+    // 
+    //   for pat in alternatives.drain_filter(|p| {
+    //       // Check if we should extract, but only if `idx >= start`.
+    //       idx += 1;
+    //       idx > start && predicate(&p.kind)
+    //   }) {
+    //       tail_or.push(extract(pat.into_inner().kind));
+    //   }
+    let mut i = 0;
+    while i < alternatives.len() {
         idx += 1;
-        idx > start && predicate(&p.kind)
-    }) {
-        tail_or.push(extract(pat.into_inner().kind));
+        // Check if we should extract, but only if `idx >= start`.
+	if idx > start && predicate(&alternatives[i].kind) {
+	    let pat = alternatives.remove(i);
+            tail_or.push(extract(pat.into_inner().kind));
+	} else {
+	    i += 1;
+	}
     }
+
     tail_or
 }
 
 fn extend_with_matching(
     target: &mut Pat,
     start: usize,
-    alternatives: &mut Vec<P<Pat>>,
+    alternatives: &mut ThinVec<P<Pat>>,
     predicate: impl Fn(&PatKind) -> bool,
     extract: impl Fn(PatKind) -> P<Pat>,
 ) -> bool {
diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
index a95e7b61374..fede625f72a 100644
--- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs
+++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
@@ -161,7 +161,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
                         }
 
                         if_chain! {
-                            if Some(def_id) == cx.tcx.lang_items().from_fn();
+                            if cx.tcx.is_diagnostic_item(sym::from_fn, def_id);
                             if same_type_and_consts(a, b);
 
                             then {
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index bd7daf0773c..c37e5bb6716 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -588,7 +588,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
                     },
                 }
             },
-            ExprKind::Err => kind!("Err"),
+            ExprKind::Err(_) => kind!("Err"),
             ExprKind::DropTemps(expr) => {
                 bind!(self, expr);
                 kind!("DropTemps({expr})");
diff --git a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs
index 6cf2a955fd5..93e4b023c5c 100644
--- a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs
+++ b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs
@@ -5,7 +5,7 @@ use rustc_hir::{self as hir, HirId, ItemKind, Node};
 use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::layout::LayoutOf as _;
-use rustc_middle::ty::{Adt, Ty, TypeVisitable};
+use rustc_middle::ty::{Adt, Ty, TypeVisitableExt};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::sym;
 
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index 9d0263e93be..d82098523e3 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -144,7 +144,8 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
         (_, Paren(r)) => eq_expr(l, r),
         (Err, Err) => true,
         (Box(l), Box(r)) | (Try(l), Try(r)) | (Await(l), Await(r)) => eq_expr(l, r),
-        (Array(l), Array(r)) | (Tup(l), Tup(r)) => over(l, r, |l, r| eq_expr(l, r)),
+        (Array(l), Array(r)) => over(l, r, |l, r| eq_expr(l, r)),
+        (Tup(l), Tup(r)) => over(l, r, |l, r| eq_expr(l, r)),
         (Repeat(le, ls), Repeat(re, rs)) => eq_expr(le, re) && eq_expr(&ls.value, &rs.value),
         (Call(lc, la), Call(rc, ra)) => eq_expr(lc, rc) && over(la, ra, |l, r| eq_expr(l, r)),
         (
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 8b00ce2cc25..bb8890dcaf9 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -237,7 +237,7 @@ pub fn constant<'tcx>(
         typeck_results,
         param_env: lcx.param_env,
         needed_resolution: false,
-        substs: lcx.tcx.intern_substs(&[]),
+        substs: ty::List::empty(),
     };
     cx.expr(e).map(|cst| (cst, cx.needed_resolution))
 }
@@ -306,7 +306,7 @@ pub fn constant_context<'a, 'tcx>(
         typeck_results,
         param_env: lcx.param_env,
         needed_resolution: false,
-        substs: lcx.tcx.intern_substs(&[]),
+        substs: ty::List::empty(),
     }
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
index 6ff7728374f..ee2f816f181 100644
--- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
+++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
@@ -193,7 +193,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
                 | ExprKind::Ret(_)
                 | ExprKind::InlineAsm(_)
                 | ExprKind::Yield(..)
-                | ExprKind::Err => {
+                | ExprKind::Err(_) => {
                     self.eagerness = ForceNoChange;
                     return;
                 },
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index 2bbe1a19b62..0603755f8a9 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -714,7 +714,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                 }
                 self.hash_pat(pat);
             },
-            ExprKind::Err => {},
+            ExprKind::Err(_) => {},
             ExprKind::Lit(ref l) => {
                 l.node.hash(&mut self.s);
             },
@@ -986,7 +986,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
             TyKind::Typeof(anon_const) => {
                 self.hash_body(anon_const.body);
             },
-            TyKind::Err | TyKind::Infer | TyKind::Never => {},
+            TyKind::Err(_) | TyKind::Infer | TyKind::Never => {},
         }
     }
 
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index b2edd1bbfef..f02f8ecb43d 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -104,7 +104,7 @@ use rustc_middle::ty::fast_reject::SimplifiedType::{
     PtrSimplifiedType, SliceSimplifiedType, StrSimplifiedType, UintSimplifiedType,
 };
 use rustc_middle::ty::{
-    layout::IntegerExt, BorrowKind, ClosureKind, DefIdTree, Ty, TyCtxt, TypeAndMut, TypeVisitable, UpvarCapture,
+    layout::IntegerExt, BorrowKind, ClosureKind, DefIdTree, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, UpvarCapture,
 };
 use rustc_middle::ty::{FloatTy, IntTy, UintTy};
 use rustc_span::hygiene::{ExpnKind, MacroKind};
diff --git a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
index e9dc7351b58..920ce8e655b 100644
--- a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
+++ b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
@@ -4,7 +4,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_index::bit_set::{BitSet, HybridBitSet};
 use rustc_lint::LateContext;
 use rustc_middle::mir::{self, visit::Visitor as _, Mutability};
-use rustc_middle::ty::{self, visit::ir::TypeVisitor, TyCtxt};
+use rustc_middle::ty::{self, visit::TypeVisitor, TyCtxt};
 use rustc_mir_dataflow::{impls::MaybeStorageLive, Analysis, ResultsCursor};
 use std::borrow::Cow;
 use std::ops::ControlFlow;
diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs
index 78fb2e0eb7e..11ca81cfe6c 100644
--- a/src/tools/clippy/clippy_utils/src/sugg.rs
+++ b/src/tools/clippy/clippy_utils/src/sugg.rs
@@ -157,7 +157,7 @@ impl<'a> Sugg<'a> {
             | hir::ExprKind::Ret(..)
             | hir::ExprKind::Struct(..)
             | hir::ExprKind::Tup(..)
-            | hir::ExprKind::Err => Sugg::NonParen(get_snippet(expr.span)),
+            | hir::ExprKind::Err(_) => Sugg::NonParen(get_snippet(expr.span)),
             hir::ExprKind::DropTemps(inner) => Self::hir_from_snippet(inner, get_snippet),
             hir::ExprKind::Assign(lhs, rhs, _) => {
                 Sugg::BinOp(AssocOp::Assign, get_snippet(lhs.span), get_snippet(rhs.span))
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 2ed301fcc22..f8ec4bb5493 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -17,8 +17,8 @@ use rustc_lint::LateContext;
 use rustc_middle::mir::interpret::{ConstValue, Scalar};
 use rustc_middle::ty::{
     self, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, DefIdTree, FnSig, IntTy, List, ParamEnv, Predicate,
-    PredicateKind, Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, ir::TypeVisitor, UintTy,
-    VariantDef, VariantDiscr,
+    PredicateKind, Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, UintTy,
+    VariantDef, VariantDiscr, TypeVisitableExt,
 };
 use rustc_middle::ty::{GenericArg, GenericArgKind};
 use rustc_span::symbol::Ident;
@@ -237,7 +237,7 @@ pub fn implements_trait_with_env<'tcx>(
         kind: TypeVariableOriginKind::MiscVariable,
         span: DUMMY_SP,
     };
-    let ty_params = tcx.mk_substs(
+    let ty_params = tcx.mk_substs_from_iter(
         ty_params
             .into_iter()
             .map(|arg| arg.unwrap_or_else(|| infcx.next_ty_var(orig).into())),
@@ -847,7 +847,7 @@ pub fn for_each_top_level_late_bound_region<B>(
                 ControlFlow::Continue(())
             }
         }
-        fn visit_binder<T: TypeVisitable<'tcx>>(&mut self, t: &Binder<'tcx, T>) -> ControlFlow<Self::BreakTy> {
+        fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) -> ControlFlow<Self::BreakTy> {
             self.index += 1;
             let res = t.super_visit_with(self);
             self.index -= 1;
@@ -1065,7 +1065,7 @@ pub fn make_projection<'tcx>(
         tcx,
         container_id,
         assoc_ty,
-        tcx.mk_substs(substs.into_iter().map(Into::into)),
+        tcx.mk_substs_from_iter(substs.into_iter().map(Into::into)),
     )
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs
index 00073bcd82a..d27a20bd4df 100644
--- a/src/tools/clippy/clippy_utils/src/visitors.rs
+++ b/src/tools/clippy/clippy_utils/src/visitors.rs
@@ -665,7 +665,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
             | ExprKind::Path(_)
             | ExprKind::Continue(_)
             | ExprKind::InlineAsm(_)
-            | ExprKind::Err => (),
+            | ExprKind::Err(_) => (),
         }
         ControlFlow::Continue(())
     }
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index e45835efe74..9ac849aecf1 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -209,7 +209,10 @@ fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
     // Separate the output with an empty line
     eprintln!();
 
-    let fallback_bundle = rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
+    let fallback_bundle = rustc_errors::fallback_fluent_bundle(
+        rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
+        false
+    );
     let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr(
         rustc_errors::ColorConfig::Auto,
         None,
diff --git a/src/tools/clippy/tests/ui/missing_doc_impl.stderr b/src/tools/clippy/tests/ui/missing_doc_impl.stderr
index f22fa19dbca..b410f56e167 100644
--- a/src/tools/clippy/tests/ui/missing_doc_impl.stderr
+++ b/src/tools/clippy/tests/ui/missing_doc_impl.stderr
@@ -51,13 +51,13 @@ LL | |     fn foo_with_impl(&self) {}
 LL | | }
    | |_^
 
-error: missing documentation for an associated function
+error: missing documentation for a method
   --> $DIR/missing_doc_impl.rs:44:5
    |
 LL |     fn foo(&self);
    |     ^^^^^^^^^^^^^^
 
-error: missing documentation for an associated function
+error: missing documentation for a method
   --> $DIR/missing_doc_impl.rs:45:5
    |
 LL |     fn foo_with_impl(&self) {}
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index deed6fbd439..0db043a4fca 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -16,7 +16,7 @@ regex = "1.0"
 serde = { version = "1.0", features = ["derive"] }
 serde_json = "1.0"
 rustfix = "0.6.0"
-lazy_static = "1.0"
+once_cell = "1.16.0"
 walkdir = "2"
 glob = "0.3.0"
 lazycell = "1.3.0"
@@ -25,5 +25,5 @@ lazycell = "1.3.0"
 libc = "0.2"
 
 [target.'cfg(windows)'.dependencies]
-miow = "0.3"
+miow = "0.5"
 winapi = { version = "0.3", features = ["winerror"] }
diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs
index 054235ec16d..c33e66e02ac 100644
--- a/src/tools/compiletest/src/errors.rs
+++ b/src/tools/compiletest/src/errors.rs
@@ -7,7 +7,7 @@ use std::io::BufReader;
 use std::path::Path;
 use std::str::FromStr;
 
-use lazy_static::lazy_static;
+use once_cell::sync::Lazy;
 use regex::Regex;
 use tracing::*;
 
@@ -117,10 +117,8 @@ fn parse_expected(
     //     //~^^^^^
     //     //[cfg1]~
     //     //[cfg1,cfg2]~^^
-    lazy_static! {
-        static ref RE: Regex =
-            Regex::new(r"//(?:\[(?P<cfgs>[\w,]+)])?~(?P<adjust>\||\^*)").unwrap();
-    }
+    static RE: Lazy<Regex> =
+        Lazy::new(|| Regex::new(r"//(?:\[(?P<cfgs>[\w,]+)])?~(?P<adjust>\||\^*)").unwrap());
 
     let captures = RE.captures(line)?;
 
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index c648b2f12f1..1760c29ec66 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -588,7 +588,8 @@ fn modified_tests(config: &Config, dir: &Path) -> Result<Vec<PathBuf>, String> {
     let full_paths = {
         let mut full_paths: Vec<PathBuf> = all_paths
             .into_iter()
-            .map(|f| fs::canonicalize(&f).unwrap().with_extension("").with_extension("rs"))
+            .map(|f| PathBuf::from(f).with_extension("").with_extension("rs"))
+            .filter_map(|f| if Path::new(&f).exists() { f.canonicalize().ok() } else { None })
             .collect();
         full_paths.dedup();
         full_paths.sort_unstable();
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 51c9a27c83d..7824ef81d7a 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -32,7 +32,7 @@ use std::process::{Child, Command, ExitStatus, Output, Stdio};
 use std::str;
 
 use glob::glob;
-use lazy_static::lazy_static;
+use once_cell::sync::Lazy;
 use tracing::*;
 
 use crate::extract_gdb_version;
@@ -52,9 +52,8 @@ fn disable_error_reporting<F: FnOnce() -> R, R>(f: F) -> R {
     use winapi::um::errhandlingapi::SetErrorMode;
     use winapi::um::winbase::SEM_NOGPFAULTERRORBOX;
 
-    lazy_static! {
-        static ref LOCK: Mutex<()> = Mutex::new(());
-    }
+    static LOCK: Mutex<()> = Mutex::new(());
+
     // Error mode is a global variable, so lock it so only one thread will change it
     let _lock = LOCK.lock().unwrap();
 
@@ -2848,11 +2847,10 @@ impl<'test> TestCx<'test> {
         // the form <crate-name1>.<crate-disambiguator1>-in-<crate-name2>.<crate-disambiguator2>,
         // remove all crate-disambiguators.
         fn remove_crate_disambiguator_from_cgu(cgu: &str) -> String {
-            lazy_static! {
-                static ref RE: Regex =
-                    Regex::new(r"^[^\.]+(?P<d1>\.[[:alnum:]]+)(-in-[^\.]+(?P<d2>\.[[:alnum:]]+))?")
-                        .unwrap();
-            }
+            static RE: Lazy<Regex> = Lazy::new(|| {
+                Regex::new(r"^[^\.]+(?P<d1>\.[[:alnum:]]+)(-in-[^\.]+(?P<d2>\.[[:alnum:]]+))?")
+                    .unwrap()
+            });
 
             let captures =
                 RE.captures(cgu).unwrap_or_else(|| panic!("invalid cgu name encountered: {}", cgu));
@@ -3170,12 +3168,12 @@ impl<'test> TestCx<'test> {
                 // 'uploaded "$TEST_BUILD_DIR/<test_executable>, waiting for result"'
                 // is printed to stdout by the client and then captured in the ProcRes,
                 // so it needs to be removed when comparing the run-pass test execution output
-                lazy_static! {
-                    static ref REMOTE_TEST_RE: Regex = Regex::new(
+                static REMOTE_TEST_RE: Lazy<Regex> = Lazy::new(|| {
+                    Regex::new(
                         "^uploaded \"\\$TEST_BUILD_DIR(/[[:alnum:]_\\-.]+)+\", waiting for result\n"
                     )
-                    .unwrap();
-                }
+                    .unwrap()
+                });
                 REMOTE_TEST_RE
                     .replace(
                         &self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout),
@@ -3620,10 +3618,8 @@ impl<'test> TestCx<'test> {
         // with placeholders as we do not want tests needing updated when compiler source code
         // changes.
         // eg. $SRC_DIR/libcore/mem.rs:323:14 becomes $SRC_DIR/libcore/mem.rs:LL:COL
-        lazy_static! {
-            static ref SRC_DIR_RE: Regex =
-                Regex::new("SRC_DIR(.+):\\d+:\\d+(: \\d+:\\d+)?").unwrap();
-        }
+        static SRC_DIR_RE: Lazy<Regex> =
+            Lazy::new(|| Regex::new("SRC_DIR(.+):\\d+:\\d+(: \\d+:\\d+)?").unwrap());
 
         normalized = SRC_DIR_RE.replace_all(&normalized, "SRC_DIR$1:LL:COL").into_owned();
 
@@ -3634,19 +3630,17 @@ impl<'test> TestCx<'test> {
         // since they duplicate actual errors and make the output hard to read.
         // This mirrors the regex in src/tools/tidy/src/style.rs, please update
         // both if either are changed.
-        lazy_static! {
-            static ref ANNOTATION_RE: Regex = Regex::new("\\s*//(\\[.*\\])?~.*").unwrap();
-        }
+        static ANNOTATION_RE: Lazy<Regex> =
+            Lazy::new(|| Regex::new("\\s*//(\\[.*\\])?~.*").unwrap());
 
         normalized = ANNOTATION_RE.replace_all(&normalized, "").into_owned();
 
         // This code normalizes various hashes in v0 symbol mangling that is
         // emitted in the ui and mir-opt tests.
-        lazy_static! {
-            static ref V0_CRATE_HASH_PREFIX_RE: Regex =
-                Regex::new(r"_R.*?Cs[0-9a-zA-Z]+_").unwrap();
-            static ref V0_CRATE_HASH_RE: Regex = Regex::new(r"Cs[0-9a-zA-Z]+_").unwrap();
-        }
+        static V0_CRATE_HASH_PREFIX_RE: Lazy<Regex> =
+            Lazy::new(|| Regex::new(r"_R.*?Cs[0-9a-zA-Z]+_").unwrap());
+        static V0_CRATE_HASH_RE: Lazy<Regex> =
+            Lazy::new(|| Regex::new(r"Cs[0-9a-zA-Z]+_").unwrap());
 
         const V0_CRATE_HASH_PLACEHOLDER: &str = r"CsCRATE_HASH_";
         if V0_CRATE_HASH_PREFIX_RE.is_match(&normalized) {
@@ -3655,10 +3649,9 @@ impl<'test> TestCx<'test> {
                 V0_CRATE_HASH_RE.replace_all(&normalized, V0_CRATE_HASH_PLACEHOLDER).into_owned();
         }
 
-        lazy_static! {
-            static ref V0_BACK_REF_PREFIX_RE: Regex = Regex::new(r"\(_R.*?B[0-9a-zA-Z]_").unwrap();
-            static ref V0_BACK_REF_RE: Regex = Regex::new(r"B[0-9a-zA-Z]_").unwrap();
-        }
+        static V0_BACK_REF_PREFIX_RE: Lazy<Regex> =
+            Lazy::new(|| Regex::new(r"\(_R.*?B[0-9a-zA-Z]_").unwrap());
+        static V0_BACK_REF_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"B[0-9a-zA-Z]_").unwrap());
 
         const V0_BACK_REF_PLACEHOLDER: &str = r"B<REF>_";
         if V0_BACK_REF_PREFIX_RE.is_match(&normalized) {
@@ -3681,21 +3674,23 @@ impl<'test> TestCx<'test> {
     /// Replaces backslashes in paths with forward slashes, and replaces CRLF line endings
     /// with LF.
     fn normalize_platform_differences(output: &str) -> String {
-        lazy_static! {
-            /// Used to find Windows paths.
-            ///
-            /// It's not possible to detect paths in the error messages generally, but this is a
-            /// decent enough heuristic.
-            static ref PATH_BACKSLASH_RE: Regex = Regex::new(r#"(?x)
+        /// Used to find Windows paths.
+        ///
+        /// It's not possible to detect paths in the error messages generally, but this is a
+        /// decent enough heuristic.
+        static PATH_BACKSLASH_RE: Lazy<Regex> = Lazy::new(|| {
+            Regex::new(
+                r#"(?x)
                 (?:
                   # Match paths that don't include spaces.
                   (?:\\[\pL\pN\.\-_']+)+\.\pL+
                 |
                   # If the path starts with a well-known root, then allow spaces.
                   \$(?:DIR|SRC_DIR|TEST_BUILD_DIR|BUILD_DIR|LIB_DIR)(?:\\[\pL\pN\.\-_' ]+)+
-                )"#
-            ).unwrap();
-        }
+                )"#,
+            )
+            .unwrap()
+        });
 
         let output = output.replace(r"\\", r"\");
 
diff --git a/src/tools/error_index_generator/Cargo.toml b/src/tools/error_index_generator/Cargo.toml
index f4dac6e947e..76c2e330b21 100644
--- a/src/tools/error_index_generator/Cargo.toml
+++ b/src/tools/error_index_generator/Cargo.toml
@@ -5,6 +5,7 @@ edition = "2021"
 
 [dependencies]
 mdbook = { version = "0.4", default-features = false, features = ["search"] }
+rustc_error_codes = { version = "0.0.0", path = "../../../compiler/rustc_error_codes" }
 
 [[bin]]
 name = "error_index_generator"
diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs
index 98eda97e236..f984275b164 100644
--- a/src/tools/error_index_generator/main.rs
+++ b/src/tools/error_index_generator/main.rs
@@ -2,9 +2,6 @@
 
 extern crate rustc_driver;
 
-// We use the function we generate from `register_diagnostics!`.
-use crate::error_codes::error_codes;
-
 use std::env;
 use std::error::Error;
 use std::fs::{self, File};
@@ -17,22 +14,6 @@ use std::str::FromStr;
 use mdbook::book::{parse_summary, BookItem, Chapter};
 use mdbook::{Config, MDBook};
 
-macro_rules! register_diagnostics {
-    ($($error_code:ident: $message:expr,)+ ; $($undocumented:ident,)* ) => {
-        pub fn error_codes() -> Vec<(&'static str, Option<&'static str>)> {
-            let mut errors: Vec<(&str, Option<&str>)> = vec![
-                $((stringify!($error_code), Some($message)),)+
-                $((stringify!($undocumented), None),)+
-            ];
-            errors.sort();
-            errors
-        }
-    }
-}
-
-#[path = "../../../compiler/rustc_error_codes/src/error_codes.rs"]
-mod error_codes;
-
 enum OutputFormat {
     HTML,
     Markdown,
@@ -55,11 +36,8 @@ fn render_markdown(output_path: &Path) -> Result<(), Box<dyn Error>> {
 
     write!(output_file, "# Rust Compiler Error Index\n")?;
 
-    for (err_code, description) in error_codes().iter() {
-        match description {
-            Some(ref desc) => write!(output_file, "## {}\n{}\n", err_code, desc)?,
-            None => {}
-        }
+    for (err_code, description) in rustc_error_codes::DIAGNOSTICS.iter() {
+        write!(output_file, "## {}\n{}\n", err_code, description)?
     }
 
     Ok(())
@@ -105,27 +83,23 @@ This page lists all the error codes emitted by the Rust compiler.
 "
     );
 
-    let err_codes = error_codes();
+    let err_codes = rustc_error_codes::DIAGNOSTICS;
     let mut chapters = Vec::with_capacity(err_codes.len());
 
     for (err_code, explanation) in err_codes.iter() {
-        if let Some(explanation) = explanation {
-            introduction.push_str(&format!(" * [{0}](./{0}.html)\n", err_code));
-
-            let content = add_rust_attribute_on_codeblock(explanation);
-            chapters.push(BookItem::Chapter(Chapter {
-                name: err_code.to_string(),
-                content: format!("# Error code {}\n\n{}\n", err_code, content),
-                number: None,
-                sub_items: Vec::new(),
-                // We generate it into the `error_codes` folder.
-                path: Some(PathBuf::from(&format!("{}.html", err_code))),
-                source_path: None,
-                parent_names: Vec::new(),
-            }));
-        } else {
-            introduction.push_str(&format!(" * {}\n", err_code));
-        }
+        introduction.push_str(&format!(" * [{0}](./{0}.html)\n", err_code));
+
+        let content = add_rust_attribute_on_codeblock(explanation);
+        chapters.push(BookItem::Chapter(Chapter {
+            name: err_code.to_string(),
+            content: format!("# Error code {}\n\n{}\n", err_code, content),
+            number: None,
+            sub_items: Vec::new(),
+            // We generate it into the `error_codes` folder.
+            path: Some(PathBuf::from(&format!("{}.html", err_code))),
+            source_path: None,
+            parent_names: Vec::new(),
+        }));
     }
 
     let mut config = Config::from_str(include_str!("book_config.toml"))?;
diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs
index c6f55410e44..a1f675a3b40 100644
--- a/src/tools/jsondoclint/src/validator.rs
+++ b/src/tools/jsondoclint/src/validator.rs
@@ -71,6 +71,19 @@ impl<'a> Validator<'a> {
         }
     }
 
+    fn check_items(&mut self, id: &Id, items: &[Id]) {
+        let mut visited_ids = HashSet::with_capacity(items.len());
+
+        for item in items {
+            if !visited_ids.insert(item) {
+                self.fail(
+                    id,
+                    ErrorKind::Custom(format!("Duplicated entry in `items` field: `{item:?}`")),
+                );
+            }
+        }
+    }
+
     fn check_item(&mut self, id: &'a Id) {
         if let Some(item) = &self.krate.index.get(id) {
             item.links.values().for_each(|id| self.add_any_id(id));
@@ -83,9 +96,9 @@ impl<'a> Validator<'a> {
                 ItemEnum::Enum(x) => self.check_enum(x),
                 ItemEnum::Variant(x) => self.check_variant(x, id),
                 ItemEnum::Function(x) => self.check_function(x),
-                ItemEnum::Trait(x) => self.check_trait(x),
+                ItemEnum::Trait(x) => self.check_trait(x, id),
                 ItemEnum::TraitAlias(x) => self.check_trait_alias(x),
-                ItemEnum::Impl(x) => self.check_impl(x),
+                ItemEnum::Impl(x) => self.check_impl(x, id),
                 ItemEnum::Typedef(x) => self.check_typedef(x),
                 ItemEnum::OpaqueTy(x) => self.check_opaque_ty(x),
                 ItemEnum::Constant(x) => self.check_constant(x),
@@ -94,7 +107,7 @@ impl<'a> Validator<'a> {
                 ItemEnum::Macro(x) => self.check_macro(x),
                 ItemEnum::ProcMacro(x) => self.check_proc_macro(x),
                 ItemEnum::Primitive(x) => self.check_primitive_type(x),
-                ItemEnum::Module(x) => self.check_module(x),
+                ItemEnum::Module(x) => self.check_module(x, id),
                 // FIXME: Why don't these have their own structs?
                 ItemEnum::ExternCrate { .. } => {}
                 ItemEnum::AssocConst { type_, default: _ } => self.check_type(type_),
@@ -112,7 +125,8 @@ impl<'a> Validator<'a> {
     }
 
     // Core checkers
-    fn check_module(&mut self, module: &'a Module) {
+    fn check_module(&mut self, module: &'a Module, id: &Id) {
+        self.check_items(id, &module.items);
         module.items.iter().for_each(|i| self.add_mod_item_id(i));
     }
 
@@ -181,7 +195,8 @@ impl<'a> Validator<'a> {
         self.check_fn_decl(&x.decl);
     }
 
-    fn check_trait(&mut self, x: &'a Trait) {
+    fn check_trait(&mut self, x: &'a Trait, id: &Id) {
+        self.check_items(id, &x.items);
         self.check_generics(&x.generics);
         x.items.iter().for_each(|i| self.add_trait_item_id(i));
         x.bounds.iter().for_each(|i| self.check_generic_bound(i));
@@ -193,7 +208,8 @@ impl<'a> Validator<'a> {
         x.params.iter().for_each(|i| self.check_generic_bound(i));
     }
 
-    fn check_impl(&mut self, x: &'a Impl) {
+    fn check_impl(&mut self, x: &'a Impl, id: &Id) {
+        self.check_items(id, &x.items);
         self.check_generics(&x.generics);
         if let Some(path) = &x.trait_ {
             self.check_path(path, PathKind::Trait);
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 461add9f508..53ec1ba0821 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-f715e430aac0de131e2ad21804013ea405722a66
+c4e0cd966062ca67daed20775f4e8a60c28e57df
diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs
index ebb71b57ae3..8443e907938 100644
--- a/src/tools/miri/src/eval.rs
+++ b/src/tools/miri/src/eval.rs
@@ -363,7 +363,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
                 tcx,
                 ty::ParamEnv::reveal_all(),
                 start_id,
-                tcx.intern_substs(&[ty::subst::GenericArg::from(main_ret_ty)]),
+                tcx.mk_substs(&[ty::subst::GenericArg::from(main_ret_ty)]),
             )
             .unwrap()
             .unwrap();
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
index c82c274524a..f21b4f84c4c 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
@@ -173,7 +173,7 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty, krate: CrateId) -> Result<Lay
 
             // let pointee = tcx.normalize_erasing_regions(param_env, pointee);
             // if pointee.is_sized(tcx.at(DUMMY_SP), param_env) {
-            //     return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr)));
+            //     return Ok(tcx.mk_layout(LayoutS::scalar(cx, data_ptr)));
             // }
 
             let unsized_part = struct_tail_erasing_lifetimes(db, pointee.clone());
diff --git a/src/tools/rustfmt/src/chains.rs b/src/tools/rustfmt/src/chains.rs
index 39b8d687809..cbe523c6c3c 100644
--- a/src/tools/rustfmt/src/chains.rs
+++ b/src/tools/rustfmt/src/chains.rs
@@ -74,6 +74,8 @@ use crate::utils::{
     rewrite_ident, trimmed_last_line_width, wrap_str,
 };
 
+use thin_vec::ThinVec;
+
 /// Provides the original input contents from the span
 /// of a chain element with trailing spaces trimmed.
 fn format_overflow_style(span: Span, context: &RewriteContext<'_>) -> Option<String> {
@@ -168,7 +170,7 @@ enum ChainItemKind {
     MethodCall(
         ast::PathSegment,
         Vec<ast::GenericArg>,
-        Vec<ptr::P<ast::Expr>>,
+        ThinVec<ptr::P<ast::Expr>>,
     ),
     StructField(symbol::Ident),
     TupleField(symbol::Ident, bool),
diff --git a/src/tools/rustfmt/src/closures.rs b/src/tools/rustfmt/src/closures.rs
index 8fd0fcf8f5c..340113866c4 100644
--- a/src/tools/rustfmt/src/closures.rs
+++ b/src/tools/rustfmt/src/closures.rs
@@ -1,5 +1,6 @@
 use rustc_ast::{ast, ptr};
 use rustc_span::Span;
+use thin_vec::thin_vec;
 
 use crate::attr::get_attrs_from_stmt;
 use crate::config::lists::*;
@@ -150,7 +151,7 @@ fn rewrite_closure_with_block(
     }
 
     let block = ast::Block {
-        stmts: vec![ast::Stmt {
+        stmts: thin_vec![ast::Stmt {
             id: ast::NodeId::root(),
             kind: ast::StmtKind::Expr(ptr::P(body.clone())),
             span: body.span,
diff --git a/src/tools/rustfmt/src/lib.rs b/src/tools/rustfmt/src/lib.rs
index 0c27bcacfb8..b27405efdb7 100644
--- a/src/tools/rustfmt/src/lib.rs
+++ b/src/tools/rustfmt/src/lib.rs
@@ -23,6 +23,7 @@ extern crate rustc_expand;
 extern crate rustc_parse;
 extern crate rustc_session;
 extern crate rustc_span;
+extern crate thin_vec;
 
 // Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta
 // files.
diff --git a/src/tools/rustfmt/src/modules.rs b/src/tools/rustfmt/src/modules.rs
index 7a0d1736c59..af9a154a6ae 100644
--- a/src/tools/rustfmt/src/modules.rs
+++ b/src/tools/rustfmt/src/modules.rs
@@ -6,6 +6,7 @@ use rustc_ast::ast;
 use rustc_ast::visit::Visitor;
 use rustc_span::symbol::{self, sym, Symbol};
 use rustc_span::Span;
+use thin_vec::ThinVec;
 use thiserror::Error;
 
 use crate::attr::MetaVisitor;
@@ -25,7 +26,7 @@ type FileModMap<'ast> = BTreeMap<FileName, Module<'ast>>;
 #[derive(Debug, Clone)]
 pub(crate) struct Module<'a> {
     ast_mod_kind: Option<Cow<'a, ast::ModKind>>,
-    pub(crate) items: Cow<'a, Vec<rustc_ast::ptr::P<ast::Item>>>,
+    pub(crate) items: Cow<'a, ThinVec<rustc_ast::ptr::P<ast::Item>>>,
     inner_attr: ast::AttrVec,
     pub(crate) span: Span,
 }
@@ -34,7 +35,7 @@ impl<'a> Module<'a> {
     pub(crate) fn new(
         mod_span: Span,
         ast_mod_kind: Option<Cow<'a, ast::ModKind>>,
-        mod_items: Cow<'a, Vec<rustc_ast::ptr::P<ast::Item>>>,
+        mod_items: Cow<'a, ThinVec<rustc_ast::ptr::P<ast::Item>>>,
         mod_attrs: Cow<'a, ast::AttrVec>,
     ) -> Self {
         let inner_attr = mod_attrs
@@ -157,7 +158,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
                     Module::new(
                         module_item.item.span,
                         Some(Cow::Owned(sub_mod_kind.clone())),
-                        Cow::Owned(vec![]),
+                        Cow::Owned(ThinVec::new()),
                         Cow::Owned(ast::AttrVec::new()),
                     ),
                 )?;
@@ -169,7 +170,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
     /// Visit modules defined inside macro calls.
     fn visit_mod_outside_ast(
         &mut self,
-        items: Vec<rustc_ast::ptr::P<ast::Item>>,
+        items: ThinVec<rustc_ast::ptr::P<ast::Item>>,
     ) -> Result<(), ModuleResolutionError> {
         for item in items {
             if is_cfg_if(&item) {
@@ -184,7 +185,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
                     Module::new(
                         span,
                         Some(Cow::Owned(sub_mod_kind.clone())),
-                        Cow::Owned(vec![]),
+                        Cow::Owned(ThinVec::new()),
                         Cow::Owned(ast::AttrVec::new()),
                     ),
                 )?;
@@ -210,7 +211,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
                     Module::new(
                         span,
                         Some(Cow::Borrowed(sub_mod_kind)),
-                        Cow::Owned(vec![]),
+                        Cow::Owned(ThinVec::new()),
                         Cow::Borrowed(&item.attrs),
                     ),
                 )?;
diff --git a/src/tools/rustfmt/src/parse/parser.rs b/src/tools/rustfmt/src/parse/parser.rs
index e0bd065518b..7ab042506bd 100644
--- a/src/tools/rustfmt/src/parse/parser.rs
+++ b/src/tools/rustfmt/src/parse/parser.rs
@@ -6,6 +6,7 @@ use rustc_ast::{ast, ptr};
 use rustc_errors::Diagnostic;
 use rustc_parse::{new_parser_from_file, parser::Parser as RawParser};
 use rustc_span::{sym, Span};
+use thin_vec::ThinVec;
 
 use crate::attr::first_attr_value_str_by_name;
 use crate::parse::session::ParseSess;
@@ -109,7 +110,7 @@ impl<'a> Parser<'a> {
         sess: &'a ParseSess,
         path: &Path,
         span: Span,
-    ) -> Result<(ast::AttrVec, Vec<ptr::P<ast::Item>>, Span), ParserError> {
+    ) -> Result<(ast::AttrVec, ThinVec<ptr::P<ast::Item>>, Span), ParserError> {
         let result = catch_unwind(AssertUnwindSafe(|| {
             let mut parser = new_parser_from_file(sess.inner(), path, Some(span));
             match parser.parse_mod(&TokenKind::Eof) {
diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs
index 9014026b0aa..a64963db6a7 100644
--- a/src/tools/rustfmt/src/parse/session.rs
+++ b/src/tools/rustfmt/src/parse/session.rs
@@ -123,8 +123,10 @@ fn default_handler(
     let emitter = if hide_parse_errors {
         silent_emitter()
     } else {
-        let fallback_bundle =
-            rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
+        let fallback_bundle = rustc_errors::fallback_fluent_bundle(
+            rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
+            false,
+        );
         Box::new(EmitterWriter::stderr(
             color_cfg,
             Some(source_map.clone()),
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 4c93f8a16b6..bddfdcfaf19 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -120,6 +120,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "dissimilar",
     "dlmalloc",
     "either",
+    "elsa",
     "ena",
     "expect-test",
     "fallible-iterator", // dependency of `thorin`
diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs
index dd2fd1911f2..c60caa0d49c 100644
--- a/src/tools/tidy/src/error_codes.rs
+++ b/src/tools/tidy/src/error_codes.rs
@@ -31,7 +31,7 @@ const IGNORE_DOCTEST_CHECK: &[&str] = &["E0464", "E0570", "E0601", "E0602", "E06
 
 // Error codes that don't yet have a UI test. This list will eventually be removed.
 const IGNORE_UI_TEST_CHECK: &[&str] =
-    &["E0461", "E0465", "E0476", "E0514", "E0554", "E0640", "E0717", "E0729"];
+    &["E0461", "E0465", "E0514", "E0554", "E0640", "E0717", "E0729"];
 
 macro_rules! verbose_print {
     ($verbose:expr, $($fmt:tt)*) => {
@@ -45,7 +45,7 @@ pub fn check(root_path: &Path, search_paths: &[&Path], verbose: bool, bad: &mut
     let mut errors = Vec::new();
 
     // Stage 1: create list
-    let error_codes = extract_error_codes(root_path, &mut errors, verbose);
+    let error_codes = extract_error_codes(root_path, &mut errors);
     println!("Found {} error codes", error_codes.len());
     println!("Highest error code: `{}`", error_codes.iter().max().unwrap());
 
@@ -65,18 +65,17 @@ pub fn check(root_path: &Path, search_paths: &[&Path], verbose: bool, bad: &mut
 }
 
 /// Stage 1: Parses a list of error codes from `error_codes.rs`.
-fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>, verbose: bool) -> Vec<String> {
+fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>) -> Vec<String> {
     let path = root_path.join(Path::new(ERROR_CODES_PATH));
     let file =
         fs::read_to_string(&path).unwrap_or_else(|e| panic!("failed to read `{path:?}`: {e}"));
 
     let mut error_codes = Vec::new();
-    let mut reached_undocumented_codes = false;
 
     for line in file.lines() {
         let line = line.trim();
 
-        if !reached_undocumented_codes && line.starts_with('E') {
+        if line.starts_with('E') {
             let split_line = line.split_once(':');
 
             // Extract the error code from the line, emitting a fatal error if it is not in a correct format.
@@ -111,23 +110,6 @@ fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>, verbose: bool
             }
 
             error_codes.push(err_code);
-        } else if reached_undocumented_codes && line.starts_with('E') {
-            let err_code = match line.split_once(',') {
-                None => line,
-                Some((err_code, _)) => err_code,
-            }
-            .to_string();
-
-            verbose_print!(verbose, "warning: Error code `{}` is undocumented.", err_code);
-
-            if error_codes.contains(&err_code) {
-                errors.push(format!("Found duplicate error code: `{}`", err_code));
-            }
-
-            error_codes.push(err_code);
-        } else if line == ";" {
-            // Once we reach the undocumented error codes, adapt to different syntax.
-            reached_undocumented_codes = true;
         }
     }
 
diff --git a/tests/mir-opt/casts.redundant.InstCombine.diff b/tests/mir-opt/casts.redundant.InstCombine.diff
new file mode 100644
index 00000000000..528a8e5a90f
--- /dev/null
+++ b/tests/mir-opt/casts.redundant.InstCombine.diff
@@ -0,0 +1,25 @@
+- // MIR for `redundant` before InstCombine
++ // MIR for `redundant` after InstCombine
+  
+  fn redundant(_1: *const &u8) -> *const &u8 {
+      debug x => _1;                       // in scope 0 at $DIR/casts.rs:+0:30: +0:31
+      let mut _0: *const &u8;              // return place in scope 0 at $DIR/casts.rs:+0:51: +0:64
+      let mut _2: *const &u8;              // in scope 0 at $DIR/casts.rs:+1:5: +1:55
+      let mut _3: *const &u8;              // in scope 0 at $DIR/casts.rs:+1:36: +1:37
+      scope 1 (inlined generic_cast::<&u8, &u8>) { // at $DIR/casts.rs:6:5: 6:38
+          debug x => _3;                   // in scope 1 at $DIR/casts.rs:10:23: 10:24
+      }
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $DIR/casts.rs:+1:5: +1:55
+          StorageLive(_3);                 // scope 0 at $DIR/casts.rs:+1:36: +1:37
+          _3 = _1;                         // scope 0 at $DIR/casts.rs:+1:36: +1:37
+-         _2 = _3 as *const &u8 (PtrToPtr); // scope 1 at $DIR/casts.rs:11:5: 11:18
++         _2 = _3;                         // scope 1 at $DIR/casts.rs:11:5: 11:18
+          StorageDead(_3);                 // scope 0 at $DIR/casts.rs:+1:37: +1:38
+          _0 = _2;                         // scope 0 at $DIR/casts.rs:+1:5: +1:55
+          StorageDead(_2);                 // scope 0 at $DIR/casts.rs:+2:1: +2:2
+          return;                          // scope 0 at $DIR/casts.rs:+2:2: +2:2
+      }
+  }
+  
diff --git a/tests/mir-opt/casts.redundant.PreCodegen.after.mir b/tests/mir-opt/casts.redundant.PreCodegen.after.mir
new file mode 100644
index 00000000000..21a470ea300
--- /dev/null
+++ b/tests/mir-opt/casts.redundant.PreCodegen.after.mir
@@ -0,0 +1,14 @@
+// MIR for `redundant` after PreCodegen
+
+fn redundant(_1: *const &u8) -> *const &u8 {
+    debug x => _1;                       // in scope 0 at $DIR/casts.rs:+0:30: +0:31
+    let mut _0: *const &u8;              // return place in scope 0 at $DIR/casts.rs:+0:51: +0:64
+    scope 1 (inlined generic_cast::<&u8, &u8>) { // at $DIR/casts.rs:6:5: 6:38
+        debug x => _1;                   // in scope 1 at $DIR/casts.rs:10:23: 10:24
+    }
+
+    bb0: {
+        _0 = _1;                         // scope 0 at $DIR/casts.rs:+1:5: +1:55
+        return;                          // scope 0 at $DIR/casts.rs:+2:2: +2:2
+    }
+}
diff --git a/tests/mir-opt/casts.roundtrip.PreCodegen.after.mir b/tests/mir-opt/casts.roundtrip.PreCodegen.after.mir
new file mode 100644
index 00000000000..0c793984ceb
--- /dev/null
+++ b/tests/mir-opt/casts.roundtrip.PreCodegen.after.mir
@@ -0,0 +1,15 @@
+// MIR for `roundtrip` after PreCodegen
+
+fn roundtrip(_1: *const u8) -> *const u8 {
+    debug x => _1;                       // in scope 0 at $DIR/casts.rs:+0:18: +0:19
+    let mut _0: *const u8;               // return place in scope 0 at $DIR/casts.rs:+0:35: +0:44
+    let mut _2: *mut u8;                 // in scope 0 at $DIR/casts.rs:+1:5: +1:17
+
+    bb0: {
+        StorageLive(_2);                 // scope 0 at $DIR/casts.rs:+1:5: +1:17
+        _2 = _1 as *mut u8 (PtrToPtr);   // scope 0 at $DIR/casts.rs:+1:5: +1:17
+        _0 = move _2 as *const u8 (Pointer(MutToConstPointer)); // scope 0 at $DIR/casts.rs:+1:5: +1:17
+        StorageDead(_2);                 // scope 0 at $DIR/casts.rs:+1:16: +1:17
+        return;                          // scope 0 at $DIR/casts.rs:+2:2: +2:2
+    }
+}
diff --git a/tests/mir-opt/casts.rs b/tests/mir-opt/casts.rs
new file mode 100644
index 00000000000..259c462da3d
--- /dev/null
+++ b/tests/mir-opt/casts.rs
@@ -0,0 +1,17 @@
+#![crate_type = "lib"]
+
+// EMIT_MIR casts.redundant.InstCombine.diff
+// EMIT_MIR casts.redundant.PreCodegen.after.mir
+pub fn redundant<'a, 'b: 'a>(x: *const &'a u8) -> *const &'a u8 {
+    generic_cast::<&'a u8, &'b u8>(x) as *const &'a u8
+}
+
+#[inline]
+fn generic_cast<T, U>(x: *const T) -> *const U {
+    x as *const U
+}
+
+// EMIT_MIR casts.roundtrip.PreCodegen.after.mir
+pub fn roundtrip(x: *const u8) -> *const u8 {
+    x as *mut u8 as *const u8
+}
diff --git a/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.diff
new file mode 100644
index 00000000000..c4002d65e5d
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.diff
@@ -0,0 +1,82 @@
+- // MIR for `multiple` before DataflowConstProp
++ // MIR for `multiple` after DataflowConstProp
+  
+  fn multiple(_1: bool, _2: u8) -> () {
+      debug x => _1;                       // in scope 0 at $DIR/enum.rs:+0:13: +0:14
+      debug i => _2;                       // in scope 0 at $DIR/enum.rs:+0:22: +0:23
+      let mut _0: ();                      // return place in scope 0 at $DIR/enum.rs:+0:29: +0:29
+      let _3: std::option::Option<u8>;     // in scope 0 at $DIR/enum.rs:+1:9: +1:10
+      let mut _4: bool;                    // in scope 0 at $DIR/enum.rs:+1:16: +1:17
+      let mut _5: u8;                      // in scope 0 at $DIR/enum.rs:+2:14: +2:15
+      let mut _7: isize;                   // in scope 0 at $DIR/enum.rs:+9:23: +9:30
+      scope 1 {
+          debug e => _3;                   // in scope 1 at $DIR/enum.rs:+1:9: +1:10
+          let _6: u8;                      // in scope 1 at $DIR/enum.rs:+9:9: +9:10
+          let _8: u8;                      // in scope 1 at $DIR/enum.rs:+9:28: +9:29
+          scope 2 {
+              debug x => _6;               // in scope 2 at $DIR/enum.rs:+9:9: +9:10
+              let _9: u8;                  // in scope 2 at $DIR/enum.rs:+11:9: +11:10
+              scope 4 {
+                  debug y => _9;           // in scope 4 at $DIR/enum.rs:+11:9: +11:10
+              }
+          }
+          scope 3 {
+              debug i => _8;               // in scope 3 at $DIR/enum.rs:+9:28: +9:29
+          }
+      }
+  
+      bb0: {
+          StorageLive(_3);                 // scope 0 at $DIR/enum.rs:+1:9: +1:10
+          StorageLive(_4);                 // scope 0 at $DIR/enum.rs:+1:16: +1:17
+          _4 = _1;                         // scope 0 at $DIR/enum.rs:+1:16: +1:17
+          switchInt(move _4) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/enum.rs:+1:16: +1:17
+      }
+  
+      bb1: {
+          StorageLive(_5);                 // scope 0 at $DIR/enum.rs:+2:14: +2:15
+          _5 = _2;                         // scope 0 at $DIR/enum.rs:+2:14: +2:15
+          _3 = Option::<u8>::Some(move _5); // scope 0 at $DIR/enum.rs:+2:9: +2:16
+          StorageDead(_5);                 // scope 0 at $DIR/enum.rs:+2:15: +2:16
+          goto -> bb3;                     // scope 0 at $DIR/enum.rs:+1:13: +5:6
+      }
+  
+      bb2: {
+          _3 = Option::<u8>::None;         // scope 0 at $DIR/enum.rs:+4:9: +4:13
+          goto -> bb3;                     // scope 0 at $DIR/enum.rs:+1:13: +5:6
+      }
+  
+      bb3: {
+          StorageDead(_4);                 // scope 0 at $DIR/enum.rs:+5:5: +5:6
+          StorageLive(_6);                 // scope 1 at $DIR/enum.rs:+9:9: +9:10
+          _7 = discriminant(_3);           // scope 1 at $DIR/enum.rs:+9:19: +9:20
+          switchInt(move _7) -> [0: bb4, 1: bb6, otherwise: bb5]; // scope 1 at $DIR/enum.rs:+9:13: +9:20
+      }
+  
+      bb4: {
+          _6 = const 0_u8;                 // scope 1 at $DIR/enum.rs:+9:45: +9:46
+          goto -> bb7;                     // scope 1 at $DIR/enum.rs:+9:45: +9:46
+      }
+  
+      bb5: {
+          unreachable;                     // scope 1 at $DIR/enum.rs:+9:19: +9:20
+      }
+  
+      bb6: {
+          StorageLive(_8);                 // scope 1 at $DIR/enum.rs:+9:28: +9:29
+          _8 = ((_3 as Some).0: u8);       // scope 1 at $DIR/enum.rs:+9:28: +9:29
+          _6 = _8;                         // scope 3 at $DIR/enum.rs:+9:34: +9:35
+          StorageDead(_8);                 // scope 1 at $DIR/enum.rs:+9:34: +9:35
+          goto -> bb7;                     // scope 1 at $DIR/enum.rs:+9:34: +9:35
+      }
+  
+      bb7: {
+          StorageLive(_9);                 // scope 2 at $DIR/enum.rs:+11:9: +11:10
+          _9 = _6;                         // scope 2 at $DIR/enum.rs:+11:13: +11:14
+          _0 = const ();                   // scope 0 at $DIR/enum.rs:+0:29: +12:2
+          StorageDead(_9);                 // scope 2 at $DIR/enum.rs:+12:1: +12:2
+          StorageDead(_6);                 // scope 1 at $DIR/enum.rs:+12:1: +12:2
+          StorageDead(_3);                 // scope 0 at $DIR/enum.rs:+12:1: +12:2
+          return;                          // scope 0 at $DIR/enum.rs:+12:2: +12:2
+      }
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/enum.rs b/tests/mir-opt/dataflow-const-prop/enum.rs
index 7ea405bd9c4..79a20d7ef45 100644
--- a/tests/mir-opt/dataflow-const-prop/enum.rs
+++ b/tests/mir-opt/dataflow-const-prop/enum.rs
@@ -46,7 +46,23 @@ fn mutate_discriminant() -> u8 {
     )
 }
 
+// EMIT_MIR enum.multiple.DataflowConstProp.diff
+fn multiple(x: bool, i: u8) {
+    let e = if x {
+        Some(i)
+    } else {
+        None
+    };
+    // The dataflow state must have:
+    //   discriminant(e) => Top
+    //   (e as Some).0 => Top
+    let x = match e { Some(i) => i, None => 0 };
+    // Therefore, `x` should be `Top` here, and no replacement shall happen.
+    let y = x;
+}
+
 fn main() {
     simple();
     mutate_discriminant();
+    multiple(false, 5);
 }
diff --git a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff
index 1fb65e65845..22bdc35d694 100644
--- a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff
+++ b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff
@@ -45,8 +45,10 @@
   
       bb3: {
           StorageLive(_4);                 // scope 1 at $DIR/enum.rs:+2:29: +2:30
-          _4 = ((_1 as V1).0: i32);        // scope 1 at $DIR/enum.rs:+2:29: +2:30
-          _2 = _4;                         // scope 3 at $DIR/enum.rs:+2:35: +2:36
+-         _4 = ((_1 as V1).0: i32);        // scope 1 at $DIR/enum.rs:+2:29: +2:30
+-         _2 = _4;                         // scope 3 at $DIR/enum.rs:+2:35: +2:36
++         _4 = const 0_i32;                // scope 1 at $DIR/enum.rs:+2:29: +2:30
++         _2 = const 0_i32;                // scope 3 at $DIR/enum.rs:+2:35: +2:36
           StorageDead(_4);                 // scope 1 at $DIR/enum.rs:+2:35: +2:36
           goto -> bb4;                     // scope 1 at $DIR/enum.rs:+2:35: +2:36
       }
diff --git a/tests/mir-opt/issue_41110.main.ElaborateDrops.after.mir b/tests/mir-opt/issue_41110.main.ElaborateDrops.after.mir
deleted file mode 100644
index c2ea3ac502f..00000000000
--- a/tests/mir-opt/issue_41110.main.ElaborateDrops.after.mir
+++ /dev/null
@@ -1,70 +0,0 @@
-// MIR for `main` after ElaborateDrops
-
-fn main() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/issue_41110.rs:+0:11: +0:11
-    let _1: ();                          // in scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
-    let mut _2: S;                       // in scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
-    let mut _3: S;                       // in scope 0 at $DIR/issue_41110.rs:+1:21: +1:27
-    let mut _4: S;                       // in scope 0 at $DIR/issue_41110.rs:+1:21: +1:22
-    let mut _5: bool;                    // in scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
-    scope 1 {
-        debug x => _1;                   // in scope 1 at $DIR/issue_41110.rs:+1:9: +1:10
-    }
-
-    bb0: {
-        _5 = const false;                // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
-        StorageLive(_1);                 // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
-        StorageLive(_2);                 // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
-        _5 = const true;                 // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
-        _2 = S;                          // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
-        StorageLive(_3);                 // scope 0 at $DIR/issue_41110.rs:+1:21: +1:27
-        StorageLive(_4);                 // scope 0 at $DIR/issue_41110.rs:+1:21: +1:22
-        _4 = S;                          // scope 0 at $DIR/issue_41110.rs:+1:21: +1:22
-        _3 = S::id(move _4) -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue_41110.rs:+1:21: +1:27
-                                         // mir::Constant
-                                         // + span: $DIR/issue_41110.rs:8:23: 8:25
-                                         // + literal: Const { ty: fn(S) -> S {S::id}, val: Value(<ZST>) }
-    }
-
-    bb1: {
-        StorageDead(_4);                 // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27
-        _5 = const false;                // scope 0 at $DIR/issue_41110.rs:+1:13: +1:28
-        _1 = S::other(move _2, move _3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:28
-                                         // mir::Constant
-                                         // + span: $DIR/issue_41110.rs:8:15: 8:20
-                                         // + literal: Const { ty: fn(S, S) {S::other}, val: Value(<ZST>) }
-    }
-
-    bb2: {
-        StorageDead(_3);                 // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
-        _5 = const false;                // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
-        StorageDead(_2);                 // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
-        _0 = const ();                   // scope 0 at $DIR/issue_41110.rs:+0:11: +2:2
-        StorageDead(_1);                 // scope 0 at $DIR/issue_41110.rs:+2:1: +2:2
-        return;                          // scope 0 at $DIR/issue_41110.rs:+2:2: +2:2
-    }
-
-    bb3 (cleanup): {
-        goto -> bb5;                     // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
-    }
-
-    bb4 (cleanup): {
-        goto -> bb5;                     // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27
-    }
-
-    bb5 (cleanup): {
-        goto -> bb8;                     // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
-    }
-
-    bb6 (cleanup): {
-        resume;                          // scope 0 at $DIR/issue_41110.rs:+0:1: +2:2
-    }
-
-    bb7 (cleanup): {
-        drop(_2) -> bb6;                 // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
-    }
-
-    bb8 (cleanup): {
-        switchInt(_5) -> [0: bb6, otherwise: bb7]; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
-    }
-}
diff --git a/tests/mir-opt/issue_41110.main.ElaborateDrops.diff b/tests/mir-opt/issue_41110.main.ElaborateDrops.diff
new file mode 100644
index 00000000000..7ac75b51a37
--- /dev/null
+++ b/tests/mir-opt/issue_41110.main.ElaborateDrops.diff
@@ -0,0 +1,75 @@
+- // MIR for `main` before ElaborateDrops
++ // MIR for `main` after ElaborateDrops
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/issue_41110.rs:+0:11: +0:11
+      let _1: ();                          // in scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
+      let mut _2: S;                       // in scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
+      let mut _3: S;                       // in scope 0 at $DIR/issue_41110.rs:+1:21: +1:27
+      let mut _4: S;                       // in scope 0 at $DIR/issue_41110.rs:+1:21: +1:22
++     let mut _5: bool;                    // in scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
+      scope 1 {
+          debug x => _1;                   // in scope 1 at $DIR/issue_41110.rs:+1:9: +1:10
+      }
+  
+      bb0: {
++         _5 = const false;                // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
+          StorageLive(_1);                 // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
+          StorageLive(_2);                 // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
++         _5 = const true;                 // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
+          _2 = S;                          // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
+          StorageLive(_3);                 // scope 0 at $DIR/issue_41110.rs:+1:21: +1:27
+          StorageLive(_4);                 // scope 0 at $DIR/issue_41110.rs:+1:21: +1:22
+          _4 = S;                          // scope 0 at $DIR/issue_41110.rs:+1:21: +1:22
+          _3 = S::id(move _4) -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue_41110.rs:+1:21: +1:27
+                                           // mir::Constant
+                                           // + span: $DIR/issue_41110.rs:8:23: 8:25
+                                           // + literal: Const { ty: fn(S) -> S {S::id}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+          StorageDead(_4);                 // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27
++         _5 = const false;                // scope 0 at $DIR/issue_41110.rs:+1:13: +1:28
+          _1 = S::other(move _2, move _3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:28
+                                           // mir::Constant
+                                           // + span: $DIR/issue_41110.rs:8:15: 8:20
+                                           // + literal: Const { ty: fn(S, S) {S::other}, val: Value(<ZST>) }
+      }
+  
+      bb2: {
+          StorageDead(_3);                 // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
++         _5 = const false;                // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
+          StorageDead(_2);                 // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
+          _0 = const ();                   // scope 0 at $DIR/issue_41110.rs:+0:11: +2:2
+          StorageDead(_1);                 // scope 0 at $DIR/issue_41110.rs:+2:1: +2:2
+          return;                          // scope 0 at $DIR/issue_41110.rs:+2:2: +2:2
+      }
+  
+      bb3 (cleanup): {
+-         drop(_3) -> bb5;                 // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
++         goto -> bb5;                     // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
+      }
+  
+      bb4 (cleanup): {
+-         drop(_4) -> bb5;                 // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27
++         goto -> bb5;                     // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27
+      }
+  
+      bb5 (cleanup): {
+-         drop(_2) -> bb6;                 // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
++         goto -> bb8;                     // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
+      }
+  
+      bb6 (cleanup): {
+          resume;                          // scope 0 at $DIR/issue_41110.rs:+0:1: +2:2
++     }
++ 
++     bb7 (cleanup): {
++         drop(_2) -> bb6;                 // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
++     }
++ 
++     bb8 (cleanup): {
++         switchInt(_5) -> [0: bb6, otherwise: bb7]; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
+      }
+  }
+  
diff --git a/tests/mir-opt/issue_41110.rs b/tests/mir-opt/issue_41110.rs
index 638dc601ec8..e1067ce53e4 100644
--- a/tests/mir-opt/issue_41110.rs
+++ b/tests/mir-opt/issue_41110.rs
@@ -3,14 +3,14 @@
 // check that we don't emit multiple drop flags when they are not needed.
 
 
-// EMIT_MIR issue_41110.main.ElaborateDrops.after.mir
+// EMIT_MIR issue_41110.main.ElaborateDrops.diff
 fn main() {
     let x = S.other(S.id());
 }
 
 // no_mangle to make sure this gets instantiated even in an executable.
 #[no_mangle]
-// EMIT_MIR issue_41110.test.ElaborateDrops.after.mir
+// EMIT_MIR issue_41110.test.ElaborateDrops.diff
 pub fn test() {
     let u = S;
     let mut v = S;
diff --git a/tests/mir-opt/issue_41110.test.ElaborateDrops.after.mir b/tests/mir-opt/issue_41110.test.ElaborateDrops.after.mir
deleted file mode 100644
index 82989c3f071..00000000000
--- a/tests/mir-opt/issue_41110.test.ElaborateDrops.after.mir
+++ /dev/null
@@ -1,101 +0,0 @@
-// MIR for `test` after ElaborateDrops
-
-fn test() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/issue_41110.rs:+0:15: +0:15
-    let _1: S;                           // in scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
-    let _3: ();                          // in scope 0 at $DIR/issue_41110.rs:+3:5: +3:12
-    let mut _4: S;                       // in scope 0 at $DIR/issue_41110.rs:+3:10: +3:11
-    let mut _5: S;                       // in scope 0 at $DIR/issue_41110.rs:+4:9: +4:10
-    let mut _6: bool;                    // in scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
-    scope 1 {
-        debug u => _1;                   // in scope 1 at $DIR/issue_41110.rs:+1:9: +1:10
-        let mut _2: S;                   // in scope 1 at $DIR/issue_41110.rs:+2:9: +2:14
-        scope 2 {
-            debug v => _2;               // in scope 2 at $DIR/issue_41110.rs:+2:9: +2:14
-        }
-    }
-
-    bb0: {
-        _6 = const false;                // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
-        StorageLive(_1);                 // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
-        _6 = const true;                 // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
-        _1 = S;                          // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
-        StorageLive(_2);                 // scope 1 at $DIR/issue_41110.rs:+2:9: +2:14
-        _2 = S;                          // scope 1 at $DIR/issue_41110.rs:+2:17: +2:18
-        StorageLive(_3);                 // scope 2 at $DIR/issue_41110.rs:+3:5: +3:12
-        StorageLive(_4);                 // scope 2 at $DIR/issue_41110.rs:+3:10: +3:11
-        _4 = move _2;                    // scope 2 at $DIR/issue_41110.rs:+3:10: +3:11
-        _3 = std::mem::drop::<S>(move _4) -> [return: bb1, unwind: bb7]; // scope 2 at $DIR/issue_41110.rs:+3:5: +3:12
-                                         // mir::Constant
-                                         // + span: $DIR/issue_41110.rs:17:5: 17:9
-                                         // + literal: Const { ty: fn(S) {std::mem::drop::<S>}, val: Value(<ZST>) }
-    }
-
-    bb1: {
-        StorageDead(_4);                 // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12
-        StorageDead(_3);                 // scope 2 at $DIR/issue_41110.rs:+3:12: +3:13
-        StorageLive(_5);                 // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
-        _6 = const false;                // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
-        _5 = move _1;                    // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
-        goto -> bb12;                    // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
-    }
-
-    bb2: {
-        goto -> bb3;                     // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
-    }
-
-    bb3: {
-        StorageDead(_5);                 // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
-        _0 = const ();                   // scope 0 at $DIR/issue_41110.rs:+0:15: +5:2
-        drop(_2) -> [return: bb4, unwind: bb9]; // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2
-    }
-
-    bb4: {
-        StorageDead(_2);                 // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2
-        goto -> bb5;                     // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
-    }
-
-    bb5: {
-        _6 = const false;                // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
-        StorageDead(_1);                 // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
-        return;                          // scope 0 at $DIR/issue_41110.rs:+5:2: +5:2
-    }
-
-    bb6 (cleanup): {
-        goto -> bb8;                     // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
-    }
-
-    bb7 (cleanup): {
-        goto -> bb8;                     // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12
-    }
-
-    bb8 (cleanup): {
-        goto -> bb9;                     // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2
-    }
-
-    bb9 (cleanup): {
-        goto -> bb14;                    // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
-    }
-
-    bb10 (cleanup): {
-        resume;                          // scope 0 at $DIR/issue_41110.rs:+0:1: +5:2
-    }
-
-    bb11 (cleanup): {
-        _2 = move _5;                    // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
-        goto -> bb6;                     // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
-    }
-
-    bb12: {
-        _2 = move _5;                    // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
-        goto -> bb2;                     // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
-    }
-
-    bb13 (cleanup): {
-        drop(_1) -> bb10;                // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
-    }
-
-    bb14 (cleanup): {
-        switchInt(_6) -> [0: bb10, otherwise: bb13]; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
-    }
-}
diff --git a/tests/mir-opt/issue_41110.test.ElaborateDrops.diff b/tests/mir-opt/issue_41110.test.ElaborateDrops.diff
new file mode 100644
index 00000000000..79e3d073be5
--- /dev/null
+++ b/tests/mir-opt/issue_41110.test.ElaborateDrops.diff
@@ -0,0 +1,109 @@
+- // MIR for `test` before ElaborateDrops
++ // MIR for `test` after ElaborateDrops
+  
+  fn test() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/issue_41110.rs:+0:15: +0:15
+      let _1: S;                           // in scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
+      let _3: ();                          // in scope 0 at $DIR/issue_41110.rs:+3:5: +3:12
+      let mut _4: S;                       // in scope 0 at $DIR/issue_41110.rs:+3:10: +3:11
+      let mut _5: S;                       // in scope 0 at $DIR/issue_41110.rs:+4:9: +4:10
++     let mut _6: bool;                    // in scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
+      scope 1 {
+          debug u => _1;                   // in scope 1 at $DIR/issue_41110.rs:+1:9: +1:10
+          let mut _2: S;                   // in scope 1 at $DIR/issue_41110.rs:+2:9: +2:14
+          scope 2 {
+              debug v => _2;               // in scope 2 at $DIR/issue_41110.rs:+2:9: +2:14
+          }
+      }
+  
+      bb0: {
++         _6 = const false;                // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
+          StorageLive(_1);                 // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
++         _6 = const true;                 // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
+          _1 = S;                          // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
+          StorageLive(_2);                 // scope 1 at $DIR/issue_41110.rs:+2:9: +2:14
+          _2 = S;                          // scope 1 at $DIR/issue_41110.rs:+2:17: +2:18
+          StorageLive(_3);                 // scope 2 at $DIR/issue_41110.rs:+3:5: +3:12
+          StorageLive(_4);                 // scope 2 at $DIR/issue_41110.rs:+3:10: +3:11
+          _4 = move _2;                    // scope 2 at $DIR/issue_41110.rs:+3:10: +3:11
+          _3 = std::mem::drop::<S>(move _4) -> [return: bb1, unwind: bb7]; // scope 2 at $DIR/issue_41110.rs:+3:5: +3:12
+                                           // mir::Constant
+                                           // + span: $DIR/issue_41110.rs:17:5: 17:9
+                                           // + literal: Const { ty: fn(S) {std::mem::drop::<S>}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+          StorageDead(_4);                 // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12
+          StorageDead(_3);                 // scope 2 at $DIR/issue_41110.rs:+3:12: +3:13
+          StorageLive(_5);                 // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
++         _6 = const false;                // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
+          _5 = move _1;                    // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
+-         replace(_2 <- move _5) -> [return: bb2, unwind: bb6]; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
++         goto -> bb12;                    // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
+      }
+  
+      bb2: {
+-         drop(_5) -> [return: bb3, unwind: bb8]; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
++         goto -> bb3;                     // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
+      }
+  
+      bb3: {
+          StorageDead(_5);                 // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
+          _0 = const ();                   // scope 0 at $DIR/issue_41110.rs:+0:15: +5:2
+          drop(_2) -> [return: bb4, unwind: bb9]; // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2
+      }
+  
+      bb4: {
+          StorageDead(_2);                 // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2
+-         drop(_1) -> bb5;                 // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
++         goto -> bb5;                     // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
+      }
+  
+      bb5: {
++         _6 = const false;                // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
+          StorageDead(_1);                 // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
+          return;                          // scope 0 at $DIR/issue_41110.rs:+5:2: +5:2
+      }
+  
+      bb6 (cleanup): {
+          drop(_5) -> bb8;                 // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
+      }
+  
+      bb7 (cleanup): {
+-         drop(_4) -> bb8;                 // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12
++         goto -> bb8;                     // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12
+      }
+  
+      bb8 (cleanup): {
+-         drop(_2) -> bb9;                 // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2
++         goto -> bb9;                     // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2
+      }
+  
+      bb9 (cleanup): {
+-         drop(_1) -> bb10;                // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
++         goto -> bb14;                    // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
+      }
+  
+      bb10 (cleanup): {
+          resume;                          // scope 0 at $DIR/issue_41110.rs:+0:1: +5:2
++     }
++ 
++     bb11 (cleanup): {
++         _2 = move _5;                    // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
++         goto -> bb10;                    // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
++     }
++ 
++     bb12: {
++         _2 = move _5;                    // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
++         goto -> bb2;                     // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
++     }
++ 
++     bb13 (cleanup): {
++         drop(_1) -> bb10;                // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
++     }
++ 
++     bb14 (cleanup): {
++         switchInt(_6) -> [0: bb10, otherwise: bb13]; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
+      }
+  }
+  
diff --git a/tests/mir-opt/issue_41888.main.ElaborateDrops.after.mir b/tests/mir-opt/issue_41888.main.ElaborateDrops.after.mir
deleted file mode 100644
index 00504273245..00000000000
--- a/tests/mir-opt/issue_41888.main.ElaborateDrops.after.mir
+++ /dev/null
@@ -1,152 +0,0 @@
-// MIR for `main` after ElaborateDrops
-
-fn main() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/issue_41888.rs:+0:11: +0:11
-    let _1: E;                           // in scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
-    let mut _2: bool;                    // in scope 0 at $DIR/issue_41888.rs:+2:8: +2:14
-    let mut _3: E;                       // in scope 0 at $DIR/issue_41888.rs:+3:13: +3:20
-    let mut _4: K;                       // in scope 0 at $DIR/issue_41888.rs:+3:18: +3:19
-    let mut _5: isize;                   // in scope 0 at $DIR/issue_41888.rs:+4:16: +4:24
-    let mut _7: bool;                    // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    let mut _8: bool;                    // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    let mut _9: bool;                    // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    let mut _10: isize;                  // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    let mut _11: isize;                  // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    scope 1 {
-        debug e => _1;                   // in scope 1 at $DIR/issue_41888.rs:+1:9: +1:10
-        scope 2 {
-            debug _k => _6;              // in scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
-            let _6: K;                   // in scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
-        }
-    }
-
-    bb0: {
-        _9 = const false;                // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
-        _7 = const false;                // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
-        _8 = const false;                // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
-        StorageLive(_1);                 // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
-        StorageLive(_2);                 // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14
-        _2 = cond() -> [return: bb1, unwind: bb11]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14
-                                         // mir::Constant
-                                         // + span: $DIR/issue_41888.rs:8:8: 8:12
-                                         // + literal: Const { ty: fn() -> bool {cond}, val: Value(<ZST>) }
-    }
-
-    bb1: {
-        switchInt(move _2) -> [0: bb7, otherwise: bb2]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14
-    }
-
-    bb2: {
-        StorageLive(_3);                 // scope 1 at $DIR/issue_41888.rs:+3:13: +3:20
-        StorageLive(_4);                 // scope 1 at $DIR/issue_41888.rs:+3:18: +3:19
-        _4 = K;                          // scope 1 at $DIR/issue_41888.rs:+3:18: +3:19
-        _3 = E::F(move _4);              // scope 1 at $DIR/issue_41888.rs:+3:13: +3:20
-        StorageDead(_4);                 // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
-        goto -> bb14;                    // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-    }
-
-    bb3: {
-        goto -> bb4;                     // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
-    }
-
-    bb4: {
-        StorageDead(_3);                 // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
-        _5 = discriminant(_1);           // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24
-        switchInt(move _5) -> [0: bb5, otherwise: bb6]; // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24
-    }
-
-    bb5: {
-        StorageLive(_6);                 // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
-        _9 = const false;                // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
-        _6 = move ((_1 as F).0: K);      // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
-        _0 = const ();                   // scope 2 at $DIR/issue_41888.rs:+4:29: +7:10
-        StorageDead(_6);                 // scope 1 at $DIR/issue_41888.rs:+7:9: +7:10
-        goto -> bb8;                     // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10
-    }
-
-    bb6: {
-        _0 = const ();                   // scope 1 at $DIR/issue_41888.rs:+7:10: +7:10
-        goto -> bb8;                     // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10
-    }
-
-    bb7: {
-        _0 = const ();                   // scope 1 at $DIR/issue_41888.rs:+8:6: +8:6
-        goto -> bb8;                     // scope 1 at $DIR/issue_41888.rs:+2:5: +8:6
-    }
-
-    bb8: {
-        StorageDead(_2);                 // scope 1 at $DIR/issue_41888.rs:+8:5: +8:6
-        goto -> bb20;                    // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-
-    bb9: {
-        _7 = const false;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-        _8 = const false;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-        _9 = const false;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-        StorageDead(_1);                 // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-        return;                          // scope 0 at $DIR/issue_41888.rs:+9:2: +9:2
-    }
-
-    bb10 (cleanup): {
-        goto -> bb11;                    // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
-    }
-
-    bb11 (cleanup): {
-        goto -> bb12;                    // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-
-    bb12 (cleanup): {
-        resume;                          // scope 0 at $DIR/issue_41888.rs:+0:1: +9:2
-    }
-
-    bb13 (cleanup): {
-        _7 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-        _8 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-        _9 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-        _1 = move _3;                    // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-        goto -> bb10;                    // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-    }
-
-    bb14: {
-        _7 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-        _8 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-        _9 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-        _1 = move _3;                    // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-        goto -> bb3;                     // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-    }
-
-    bb15: {
-        _7 = const false;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-        goto -> bb9;                     // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-
-    bb16 (cleanup): {
-        goto -> bb12;                    // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-
-    bb17: {
-        drop(_1) -> [return: bb15, unwind: bb12]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-
-    bb18 (cleanup): {
-        drop(_1) -> bb12;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-
-    bb19: {
-        _10 = discriminant(_1);          // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-        switchInt(move _10) -> [0: bb15, otherwise: bb17]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-
-    bb20: {
-        switchInt(_7) -> [0: bb15, otherwise: bb19]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-
-    bb21 (cleanup): {
-        _11 = discriminant(_1);          // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-        switchInt(move _11) -> [0: bb16, otherwise: bb18]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-
-    bb22 (cleanup): {
-        switchInt(_7) -> [0: bb12, otherwise: bb21]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-}
diff --git a/tests/mir-opt/issue_41888.main.ElaborateDrops.diff b/tests/mir-opt/issue_41888.main.ElaborateDrops.diff
new file mode 100644
index 00000000000..257f0b1e6e8
--- /dev/null
+++ b/tests/mir-opt/issue_41888.main.ElaborateDrops.diff
@@ -0,0 +1,158 @@
+- // MIR for `main` before ElaborateDrops
++ // MIR for `main` after ElaborateDrops
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/issue_41888.rs:+0:11: +0:11
+      let _1: E;                           // in scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
+      let mut _2: bool;                    // in scope 0 at $DIR/issue_41888.rs:+2:8: +2:14
+      let mut _3: E;                       // in scope 0 at $DIR/issue_41888.rs:+3:13: +3:20
+      let mut _4: K;                       // in scope 0 at $DIR/issue_41888.rs:+3:18: +3:19
+      let mut _5: isize;                   // in scope 0 at $DIR/issue_41888.rs:+4:16: +4:24
++     let mut _7: bool;                    // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     let mut _8: bool;                    // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     let mut _9: bool;                    // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     let mut _10: isize;                  // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     let mut _11: isize;                  // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+      scope 1 {
+          debug e => _1;                   // in scope 1 at $DIR/issue_41888.rs:+1:9: +1:10
+          scope 2 {
+              debug _k => _6;              // in scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
+              let _6: K;                   // in scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
+          }
+      }
+  
+      bb0: {
++         _9 = const false;                // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
++         _7 = const false;                // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
++         _8 = const false;                // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
+          StorageLive(_1);                 // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
+          StorageLive(_2);                 // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14
+          _2 = cond() -> [return: bb1, unwind: bb11]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14
+                                           // mir::Constant
+                                           // + span: $DIR/issue_41888.rs:8:8: 8:12
+                                           // + literal: Const { ty: fn() -> bool {cond}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+          switchInt(move _2) -> [0: bb7, otherwise: bb2]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14
+      }
+  
+      bb2: {
+          StorageLive(_3);                 // scope 1 at $DIR/issue_41888.rs:+3:13: +3:20
+          StorageLive(_4);                 // scope 1 at $DIR/issue_41888.rs:+3:18: +3:19
+          _4 = K;                          // scope 1 at $DIR/issue_41888.rs:+3:18: +3:19
+          _3 = E::F(move _4);              // scope 1 at $DIR/issue_41888.rs:+3:13: +3:20
+          StorageDead(_4);                 // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
+-         replace(_1 <- move _3) -> [return: bb3, unwind: bb10]; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++         goto -> bb14;                    // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
+      }
+  
+      bb3: {
+-         drop(_3) -> [return: bb4, unwind: bb11]; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
++         goto -> bb4;                     // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
+      }
+  
+      bb4: {
+          StorageDead(_3);                 // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
+          _5 = discriminant(_1);           // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24
+          switchInt(move _5) -> [0: bb5, otherwise: bb6]; // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24
+      }
+  
+      bb5: {
+          StorageLive(_6);                 // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
++         _9 = const false;                // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
+          _6 = move ((_1 as F).0: K);      // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
+          _0 = const ();                   // scope 2 at $DIR/issue_41888.rs:+4:29: +7:10
+          StorageDead(_6);                 // scope 1 at $DIR/issue_41888.rs:+7:9: +7:10
+          goto -> bb8;                     // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10
+      }
+  
+      bb6: {
+          _0 = const ();                   // scope 1 at $DIR/issue_41888.rs:+7:10: +7:10
+          goto -> bb8;                     // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10
+      }
+  
+      bb7: {
+          _0 = const ();                   // scope 1 at $DIR/issue_41888.rs:+8:6: +8:6
+          goto -> bb8;                     // scope 1 at $DIR/issue_41888.rs:+2:5: +8:6
+      }
+  
+      bb8: {
+          StorageDead(_2);                 // scope 1 at $DIR/issue_41888.rs:+8:5: +8:6
+-         drop(_1) -> bb9;                 // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++         goto -> bb20;                    // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+      }
+  
+      bb9: {
++         _7 = const false;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++         _8 = const false;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++         _9 = const false;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+          StorageDead(_1);                 // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+          return;                          // scope 0 at $DIR/issue_41888.rs:+9:2: +9:2
+      }
+  
+      bb10 (cleanup): {
+          drop(_3) -> bb11;                // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
+      }
+  
+      bb11 (cleanup): {
+-         drop(_1) -> bb12;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++         goto -> bb12;                    // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+      }
+  
+      bb12 (cleanup): {
+          resume;                          // scope 0 at $DIR/issue_41888.rs:+0:1: +9:2
++     }
++ 
++     bb13 (cleanup): {
++         _7 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++         _8 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++         _9 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++         _1 = move _3;                    // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++         goto -> bb12;                    // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++     }
++ 
++     bb14: {
++         _7 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++         _8 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++         _9 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++         _1 = move _3;                    // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++         goto -> bb3;                     // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++     }
++ 
++     bb15: {
++         _7 = const false;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++         goto -> bb9;                     // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     }
++ 
++     bb16 (cleanup): {
++         goto -> bb12;                    // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     }
++ 
++     bb17: {
++         drop(_1) -> [return: bb15, unwind: bb12]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     }
++ 
++     bb18 (cleanup): {
++         drop(_1) -> bb12;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     }
++ 
++     bb19: {
++         _10 = discriminant(_1);          // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++         switchInt(move _10) -> [0: bb15, otherwise: bb17]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     }
++ 
++     bb20: {
++         switchInt(_7) -> [0: bb15, otherwise: bb19]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     }
++ 
++     bb21 (cleanup): {
++         _11 = discriminant(_1);          // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++         switchInt(move _11) -> [0: bb16, otherwise: bb18]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     }
++ 
++     bb22 (cleanup): {
++         switchInt(_7) -> [0: bb12, otherwise: bb21]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+      }
+  }
+  
diff --git a/tests/mir-opt/issue_41888.rs b/tests/mir-opt/issue_41888.rs
index c1046c14dbf..0f10c0a1d09 100644
--- a/tests/mir-opt/issue_41888.rs
+++ b/tests/mir-opt/issue_41888.rs
@@ -2,7 +2,7 @@
 // check that we clear the "ADT master drop flag" even when there are
 // no fields to be dropped.
 
-// EMIT_MIR issue_41888.main.ElaborateDrops.after.mir
+// EMIT_MIR issue_41888.main.ElaborateDrops.diff
 fn main() {
     let e;
     if cond() {
diff --git a/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
index 3aa57d58908..8dac53c2a62 100644
--- a/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
+++ b/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
@@ -27,6 +27,8 @@ use std::any::Any;
 struct TheBackend;
 
 impl CodegenBackend for TheBackend {
+    fn locale_resource(&self) -> &'static str { "" }
+
     fn codegen_crate<'a, 'tcx>(
         &self,
         tcx: TyCtxt<'tcx>,
diff --git a/tests/run-make-fulldeps/issue-19371/foo.rs b/tests/run-make-fulldeps/issue-19371/foo.rs
index 5bb38fc02af..53ec79e477b 100644
--- a/tests/run-make-fulldeps/issue-19371/foo.rs
+++ b/tests/run-make-fulldeps/issue-19371/foo.rs
@@ -53,6 +53,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
         output_file: Some(output),
         output_dir: None,
         file_loader: None,
+        locale_resources: &[],
         lint_caps: Default::default(),
         parse_sess_created: None,
         register_lints: None,
diff --git a/tests/run-make/translation/Makefile b/tests/run-make/translation/Makefile
index 20e86c7f9a0..5b0b331ca46 100644
--- a/tests/run-make/translation/Makefile
+++ b/tests/run-make/translation/Makefile
@@ -6,8 +6,10 @@ include ../../run-make-fulldeps/tools.mk
 
 SYSROOT:=$(shell $(RUSTC) --print sysroot)
 FAKEROOT=$(TMPDIR)/fakeroot
+RUSTC_LOG:=rustc_error_messages
+export RUSTC_TRANSLATION_NO_DEBUG_ASSERT:=1
 
-all: normal custom sysroot
+all: normal custom missing broken sysroot sysroot-invalid sysroot-missing
 
 # Check that the test works normally, using the built-in fallback bundle.
 normal: test.rs
@@ -32,6 +34,7 @@ broken: test.rs broken.ftl
 # identifier by making a local copy of the sysroot and adding the custom locale
 # to it.
 sysroot: test.rs working.ftl
+	rm -rf $(FAKEROOT)
 	mkdir $(FAKEROOT)
 	ln -s $(SYSROOT)/* $(FAKEROOT)
 	rm -f $(FAKEROOT)/lib
@@ -51,12 +54,12 @@ sysroot: test.rs working.ftl
 # found. This test might start failing if there actually exists a Klingon
 # translation of rustc's error messages.
 sysroot-missing: 
-	$(RUSTC) $< -Ztranslate-lang=tlh 2>&1 || grep "missing locale directory"
+	$(RUSTC) $< -Ztranslate-lang=tlh 2>&1 | grep "missing locale directory"
 
-# Check that the compiler errors out when the sysroot requested cannot be
-# found. This test might start failing if there actually exists a Klingon
-# translation of rustc's error messages.
+# Check that the compiler errors out when the directory for the locale in the
+# sysroot is actually a file.
 sysroot-invalid: test.rs working.ftl
+	rm -rf $(FAKEROOT)
 	mkdir $(FAKEROOT)
 	ln -s $(SYSROOT)/* $(FAKEROOT)
 	rm -f $(FAKEROOT)/lib
@@ -68,5 +71,6 @@ sysroot-invalid: test.rs working.ftl
 	rm -f $(FAKEROOT)/lib/rustlib/src
 	mkdir $(FAKEROOT)/lib/rustlib/src
 	ln -s $(SYSROOT)/lib/rustlib/src/* $(FAKEROOT)/lib/rustlib/src
-	touch $(FAKEROOT)/share/locale/zh-CN/
-	$(RUSTC) $< --sysroot $(FAKEROOT) -Ztranslate-lang=zh-CN 2>&1 || grep "`\$sysroot/share/locales/\$locale` is not a directory"
+	mkdir -p $(FAKEROOT)/share/locale
+	touch $(FAKEROOT)/share/locale/zh-CN
+	$(RUSTC) $< --sysroot $(FAKEROOT) -Ztranslate-lang=zh-CN 2>&1 | grep "`\$sysroot/share/locales/\$locale` is not a directory"
diff --git a/tests/rustdoc-gui/help-page.goml b/tests/rustdoc-gui/help-page.goml
index 5f4c1ba2f85..6e2321a6963 100644
--- a/tests/rustdoc-gui/help-page.goml
+++ b/tests/rustdoc-gui/help-page.goml
@@ -68,5 +68,4 @@ size: (1000, 1000) // Popover only appears when the screen width is >700px.
 assert-false: "#help"
 click: "#help-button > a"
 click: ".popover a[href='https://doc.rust-lang.org/rustdoc/']"
-wait-for: 2000
-assert-document-property: {"URL": "https://doc.rust-lang.org/rustdoc/"}
+wait-for-document-property: {"URL": "https://doc.rust-lang.org/rustdoc/"}
diff --git a/tests/rustdoc-ui/auxiliary/panic-handler.rs b/tests/rustdoc-ui/auxiliary/panic-handler.rs
new file mode 100644
index 00000000000..0aaaeee1051
--- /dev/null
+++ b/tests/rustdoc-ui/auxiliary/panic-handler.rs
@@ -0,0 +1,9 @@
+// compile-flags: -C panic=abort
+
+#![no_std]
+#![no_main]
+
+#[panic_handler]
+fn panic(_: &core::panic::PanicInfo) -> ! {
+    loop {}
+}
diff --git a/tests/rustdoc-ui/issue-107918.rs b/tests/rustdoc-ui/issue-107918.rs
new file mode 100644
index 00000000000..13788df0fc9
--- /dev/null
+++ b/tests/rustdoc-ui/issue-107918.rs
@@ -0,0 +1,12 @@
+// aux-build:panic-handler.rs
+// compile-flags: --document-private-items
+// build-pass
+// ignore-windows
+
+#![no_std]
+#![no_main]
+
+#[panic_handler]
+fn panic(_: &core::panic::PanicInfo) -> ! {
+    loop {}
+}
diff --git a/tests/rustdoc-ui/proc_macro_bug.rs b/tests/rustdoc-ui/proc_macro_bug.rs
new file mode 100644
index 00000000000..e384e4863ad
--- /dev/null
+++ b/tests/rustdoc-ui/proc_macro_bug.rs
@@ -0,0 +1,12 @@
+// regression test for failing to pass `--crate-type proc-macro` to rustdoc
+// when documenting a proc macro crate https://github.com/rust-lang/rust/pull/107291
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro_derive(DeriveA)]
+//~^ ERROR the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type
+pub fn a_derive(input: TokenStream) -> TokenStream {
+    input
+}
diff --git a/tests/rustdoc-ui/proc_macro_bug.stderr b/tests/rustdoc-ui/proc_macro_bug.stderr
new file mode 100644
index 00000000000..5b048097c49
--- /dev/null
+++ b/tests/rustdoc-ui/proc_macro_bug.stderr
@@ -0,0 +1,8 @@
+error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type
+  --> $DIR/proc_macro_bug.rs:8:1
+   |
+LL | #[proc_macro_derive(DeriveA)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/rustdoc-ui/unable-fulfill-trait.stderr b/tests/rustdoc-ui/unable-fulfill-trait.stderr
index a16b5b6eb2f..72f35cb9224 100644
--- a/tests/rustdoc-ui/unable-fulfill-trait.stderr
+++ b/tests/rustdoc-ui/unable-fulfill-trait.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/unable-fulfill-trait.rs:4:17
    |
 LL |     field1: dyn Bar<'a, 'b,>,
diff --git a/tests/rustdoc-ui/z-help.stdout b/tests/rustdoc-ui/z-help.stdout
index 8d0155151b8..6aa9785f44e 100644
--- a/tests/rustdoc-ui/z-help.stdout
+++ b/tests/rustdoc-ui/z-help.stdout
@@ -1,76 +1,76 @@
-    -Z                          allow-features=val -- only allow the listed language features to be enabled in code (comma separated)
-    -Z                       always-encode-mir=val -- encode MIR of all functions into the crate metadata (default: no)
-    -Z                            asm-comments=val -- generate comments into the assembly (may change behavior) (default: no)
-    -Z                       assert-incr-state=val -- assert that the incremental cache is in given state: either `loaded` or `not-loaded`.
-    -Z               assume-incomplete-release=val -- make cfg(version) treat the current version as incomplete (default: no)
-    -Z                      binary-dep-depinfo=val -- include artifacts (sysroot, crate dependencies) used during compilation in dep-info (default: no)
-    -Z                             box-noalias=val -- emit noalias metadata for box (default: yes)
-    -Z                       branch-protection=val -- set options for branch target identification and pointer authentication on AArch64
-    -Z                           cf-protection=val -- instrument control-flow architecture protection
-    -Z               cgu-partitioning-strategy=val -- the codegen unit partitioning strategy to use
-    -Z                         codegen-backend=val -- the backend to use
-    -Z                             combine-cgu=val -- combine CGUs into a single one
-    -Z                              crate-attr=val -- inject the given attribute in the crate
-    -Z                debug-info-for-profiling=val -- emit discriminators and other data necessary for AutoFDO
-    -Z                            debug-macros=val -- emit line numbers debug info inside macros (default: no)
-    -Z                 deduplicate-diagnostics=val -- deduplicate identical diagnostics (default: yes)
-    -Z                  dep-info-omit-d-target=val -- in dep-info output, omit targets for tracking dependencies of the dep-info files themselves (default: no)
-    -Z                               dep-tasks=val -- print tasks that execute and the color their dep node gets (requires debug build) (default: no)
-    -Z                        diagnostic-width=val -- set the current output width for diagnostic truncation
-    -Z                                 dlltool=val -- import library generation tool (windows-gnu only)
-    -Z                 dont-buffer-diagnostics=val -- emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) (default: no)
-    -Z                           drop-tracking=val -- enables drop tracking in generators (default: no)
-    -Z                       drop-tracking-mir=val -- enables drop tracking on MIR in generators (default: no)
-    -Z                        dual-proc-macros=val -- load proc macros for both target and host, but only link to the target (default: no)
-    -Z                          dump-dep-graph=val -- dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv) (default: no)
-    -Z                  dump-drop-tracking-cfg=val -- dump drop-tracking control-flow graph as a `.dot` file (default: no)
-    -Z                                dump-mir=val -- dump MIR state to file.
+    -Z                        allow-features=val -- only allow the listed language features to be enabled in code (comma separated)
+    -Z                     always-encode-mir=val -- encode MIR of all functions into the crate metadata (default: no)
+    -Z                          asm-comments=val -- generate comments into the assembly (may change behavior) (default: no)
+    -Z                     assert-incr-state=val -- assert that the incremental cache is in given state: either `loaded` or `not-loaded`.
+    -Z             assume-incomplete-release=val -- make cfg(version) treat the current version as incomplete (default: no)
+    -Z                    binary-dep-depinfo=val -- include artifacts (sysroot, crate dependencies) used during compilation in dep-info (default: no)
+    -Z                           box-noalias=val -- emit noalias metadata for box (default: yes)
+    -Z                     branch-protection=val -- set options for branch target identification and pointer authentication on AArch64
+    -Z                         cf-protection=val -- instrument control-flow architecture protection
+    -Z             cgu-partitioning-strategy=val -- the codegen unit partitioning strategy to use
+    -Z                       codegen-backend=val -- the backend to use
+    -Z                           combine-cgu=val -- combine CGUs into a single one
+    -Z                            crate-attr=val -- inject the given attribute in the crate
+    -Z              debug-info-for-profiling=val -- emit discriminators and other data necessary for AutoFDO
+    -Z                          debug-macros=val -- emit line numbers debug info inside macros (default: no)
+    -Z               deduplicate-diagnostics=val -- deduplicate identical diagnostics (default: yes)
+    -Z                dep-info-omit-d-target=val -- in dep-info output, omit targets for tracking dependencies of the dep-info files themselves (default: no)
+    -Z                             dep-tasks=val -- print tasks that execute and the color their dep node gets (requires debug build) (default: no)
+    -Z                      diagnostic-width=val -- set the current output width for diagnostic truncation
+    -Z                               dlltool=val -- import library generation tool (windows-gnu only)
+    -Z               dont-buffer-diagnostics=val -- emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) (default: no)
+    -Z                         drop-tracking=val -- enables drop tracking in generators (default: no)
+    -Z                     drop-tracking-mir=val -- enables drop tracking on MIR in generators (default: no)
+    -Z                      dual-proc-macros=val -- load proc macros for both target and host, but only link to the target (default: no)
+    -Z                        dump-dep-graph=val -- dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv) (default: no)
+    -Z                dump-drop-tracking-cfg=val -- dump drop-tracking control-flow graph as a `.dot` file (default: no)
+    -Z                              dump-mir=val -- dump MIR state to file.
         `val` is used to select which passes and functions to dump. For example:
         `all` matches all passes and functions,
         `foo` matches all passes for functions whose name contains 'foo',
         `foo & ConstProp` only the 'ConstProp' pass for function names containing 'foo',
         `foo | bar` all passes for function names containing 'foo' or 'bar'.
-    -Z                       dump-mir-dataflow=val -- in addition to `.mir` files, create graphviz `.dot` files with dataflow results (default: no)
-    -Z                            dump-mir-dir=val -- the directory the MIR is dumped into (default: `mir_dump`)
-    -Z            dump-mir-exclude-pass-number=val -- exclude the pass number when dumping MIR (used in tests) (default: no)
-    -Z                       dump-mir-graphviz=val -- in addition to `.mir` files, create graphviz `.dot` files (and with `-Z instrument-coverage`, also create a `.dot` file for the MIR-derived coverage graph) (default: no)
-    -Z                       dump-mir-spanview=val -- in addition to `.mir` files, create `.html` files to view spans for all `statement`s (including terminators), only `terminator` spans, or computed `block` spans (one span encompassing a block's terminator and all statements). If `-Z instrument-coverage` is also enabled, create an additional `.html` file showing the computed coverage spans.
-    -Z                         dump-mono-stats=val -- output statistics about monomorphization collection
-    -Z                  dump-mono-stats-format=val -- the format to use for -Z dump-mono-stats (`markdown` (default) or `json`)
-    -Z                           dwarf-version=val -- version of DWARF debug information to emit (default: 2 or 4, depending on platform)
-    -Z                               dylib-lto=val -- enables LTO for dylib crate type
-    -Z                        emit-stack-sizes=val -- emit a section containing stack size metadata (default: no)
-    -Z                           emit-thin-lto=val -- emit the bc module with thin LTO info (default: yes)
-    -Z               export-executable-symbols=val -- export symbols from executables, as if they were dynamic libraries
-    -Z                   extra-const-ub-checks=val -- turns on more checks to detect const UB, which can be slow (default: no)
-    -Z                             fewer-names=val -- reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) (default: no)
-    -Z              force-unstable-if-unmarked=val -- force all crates to be `rustc_private` unstable (default: no)
-    -Z                                    fuel=val -- set the optimization fuel quota for a crate
-    -Z                       function-sections=val -- whether each function should go in its own section
-    -Z                    future-incompat-test=val -- forces all lints to be future incompatible, used for internal testing (default: no)
-    -Z                                  gcc-ld=val -- implementation of ld used by cc
-    -Z                      graphviz-dark-mode=val -- use dark-themed colors in graphviz output (default: no)
-    -Z                           graphviz-font=val -- use the given `fontname` in graphviz output; can be overridden by setting environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)
-    -Z                               hir-stats=val -- print some statistics about AST and HIR (default: no)
-    -Z                human-readable-cgu-names=val -- generate human-readable, predictable names for codegen units (default: no)
-    -Z                        identify-regions=val -- display unnamed regions as `'<id>`, using a non-ident unique id (default: no)
-    -Z                incremental-ignore-spans=val -- ignore spans during ICH computation -- used for testing (default: no)
-    -Z                        incremental-info=val -- print high-level information about incremental reuse (or the lack thereof) (default: no)
-    -Z              incremental-relative-spans=val -- hash spans relative to their parent item for incr. comp. (default: no)
-    -Z                  incremental-verify-ich=val -- verify incr. comp. hashes of green query instances (default: no)
-    -Z                      inline-in-all-cgus=val -- control whether `#[inline]` functions are in all CGUs
-    -Z                             inline-llvm=val -- enable LLVM inlining (default: yes)
-    -Z                              inline-mir=val -- enable MIR inlining (default: no)
-    -Z               inline-mir-hint-threshold=val -- inlining threshold for functions with inline hint (default: 100)
-    -Z                    inline-mir-threshold=val -- a default MIR inlining threshold (default: 50)
-    -Z                             input-stats=val -- gather statistics about the input (default: no)
-    -Z                     instrument-coverage=val -- instrument the generated code to support LLVM source-based code coverage reports (note, the compiler build config must include `profiler = true`); implies `-C symbol-mangling-version=v0`. Optional values are:
+    -Z                     dump-mir-dataflow=val -- in addition to `.mir` files, create graphviz `.dot` files with dataflow results (default: no)
+    -Z                          dump-mir-dir=val -- the directory the MIR is dumped into (default: `mir_dump`)
+    -Z          dump-mir-exclude-pass-number=val -- exclude the pass number when dumping MIR (used in tests) (default: no)
+    -Z                     dump-mir-graphviz=val -- in addition to `.mir` files, create graphviz `.dot` files (and with `-Z instrument-coverage`, also create a `.dot` file for the MIR-derived coverage graph) (default: no)
+    -Z                     dump-mir-spanview=val -- in addition to `.mir` files, create `.html` files to view spans for all `statement`s (including terminators), only `terminator` spans, or computed `block` spans (one span encompassing a block's terminator and all statements). If `-Z instrument-coverage` is also enabled, create an additional `.html` file showing the computed coverage spans.
+    -Z                       dump-mono-stats=val -- output statistics about monomorphization collection
+    -Z                dump-mono-stats-format=val -- the format to use for -Z dump-mono-stats (`markdown` (default) or `json`)
+    -Z                         dwarf-version=val -- version of DWARF debug information to emit (default: 2 or 4, depending on platform)
+    -Z                             dylib-lto=val -- enables LTO for dylib crate type
+    -Z                      emit-stack-sizes=val -- emit a section containing stack size metadata (default: no)
+    -Z                         emit-thin-lto=val -- emit the bc module with thin LTO info (default: yes)
+    -Z             export-executable-symbols=val -- export symbols from executables, as if they were dynamic libraries
+    -Z                 extra-const-ub-checks=val -- turns on more checks to detect const UB, which can be slow (default: no)
+    -Z                           fewer-names=val -- reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) (default: no)
+    -Z            force-unstable-if-unmarked=val -- force all crates to be `rustc_private` unstable (default: no)
+    -Z                                  fuel=val -- set the optimization fuel quota for a crate
+    -Z                     function-sections=val -- whether each function should go in its own section
+    -Z                  future-incompat-test=val -- forces all lints to be future incompatible, used for internal testing (default: no)
+    -Z                                gcc-ld=val -- implementation of ld used by cc
+    -Z                    graphviz-dark-mode=val -- use dark-themed colors in graphviz output (default: no)
+    -Z                         graphviz-font=val -- use the given `fontname` in graphviz output; can be overridden by setting environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)
+    -Z                             hir-stats=val -- print some statistics about AST and HIR (default: no)
+    -Z              human-readable-cgu-names=val -- generate human-readable, predictable names for codegen units (default: no)
+    -Z                      identify-regions=val -- display unnamed regions as `'<id>`, using a non-ident unique id (default: no)
+    -Z              incremental-ignore-spans=val -- ignore spans during ICH computation -- used for testing (default: no)
+    -Z                      incremental-info=val -- print high-level information about incremental reuse (or the lack thereof) (default: no)
+    -Z            incremental-relative-spans=val -- hash spans relative to their parent item for incr. comp. (default: no)
+    -Z                incremental-verify-ich=val -- verify incr. comp. hashes of green query instances (default: no)
+    -Z                    inline-in-all-cgus=val -- control whether `#[inline]` functions are in all CGUs
+    -Z                           inline-llvm=val -- enable LLVM inlining (default: yes)
+    -Z                            inline-mir=val -- enable MIR inlining (default: no)
+    -Z             inline-mir-hint-threshold=val -- inlining threshold for functions with inline hint (default: 100)
+    -Z                  inline-mir-threshold=val -- a default MIR inlining threshold (default: 50)
+    -Z                           input-stats=val -- gather statistics about the input (default: no)
+    -Z                   instrument-coverage=val -- instrument the generated code to support LLVM source-based code coverage reports (note, the compiler build config must include `profiler = true`); implies `-C symbol-mangling-version=v0`. Optional values are:
         `=all` (implicit value)
         `=except-unused-generics`
         `=except-unused-functions`
         `=off` (default)
-    -Z                       instrument-mcount=val -- insert function instrument code for mcount-based tracing (default: no)
-    -Z                         instrument-xray=val -- insert function instrument code for XRay-based tracing (default: no)
+    -Z                     instrument-mcount=val -- insert function instrument code for mcount-based tracing (default: no)
+    -Z                       instrument-xray=val -- insert function instrument code for XRay-based tracing (default: no)
          Optional extra settings:
          `=always`
          `=never`
@@ -79,125 +79,125 @@
          `=skip-entry`
          `=skip-exit`
          Multiple options can be combined with commas.
-    -Z                       keep-hygiene-data=val -- keep hygiene data after analysis (default: no)
-    -Z                             layout-seed=val -- seed layout randomization
-    -Z                   link-native-libraries=val -- link native libraries in the linker invocation (default: yes)
-    -Z                               link-only=val -- link the `.rlink` file generated by `-Z no-link` (default: no)
-    -Z                            llvm-plugins=val -- a list LLVM plugins to enable (space separated)
-    -Z                         llvm-time-trace=val -- generate JSON tracing data file from LLVM data (default: no)
-    -Z                         location-detail=val -- what location details should be tracked when using caller_location, either `none`, or a comma separated list of location details, for which valid options are `file`, `line`, and `column` (default: `file,line,column`)
-    -Z                                      ls=val -- list the symbols defined by a library crate (default: no)
-    -Z                         macro-backtrace=val -- show macro backtraces (default: no)
-    -Z             maximal-hir-to-mir-coverage=val -- save as much information as possible about the correspondence between MIR and HIR as source scopes (default: no)
-    -Z                         merge-functions=val -- control the operation of the MergeFunctions LLVM pass, taking the same values as the target option of the same name
-    -Z                              meta-stats=val -- gather metadata statistics (default: no)
-    -Z                          mir-emit-retag=val -- emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 (default: no)
-    -Z                       mir-enable-passes=val -- use like `-Zmir-enable-passes=+DestProp,-InstCombine`. Forces the specified passes to be enabled, overriding all other checks. Passes that are not specified are enabled or disabled by other flags as usual.
-    -Z                           mir-opt-level=val -- MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)
-    -Z        mir-pretty-relative-line-numbers=val -- use line numbers relative to the function in mir pretty printing
-    -Z                         move-size-limit=val -- the size at which the `large_assignments` lint starts to be emitted
-    -Z                         mutable-noalias=val -- emit noalias metadata for mutable references (default: yes)
-    -Z                               nll-facts=val -- dump facts from NLL analysis into side files (default: no)
-    -Z                           nll-facts-dir=val -- the directory the NLL facts are dumped into (default: `nll-facts`)
-    -Z                             no-analysis=val -- parse and expand the source, but run no analysis
-    -Z                              no-codegen=val -- run all passes except codegen; no output
-    -Z              no-generate-arange-section=val -- omit DWARF address ranges that give faster lookups
-    -Z                          no-jump-tables=val -- disable the jump tables and lookup tables that can be generated from a switch case lowering
-    -Z                           no-leak-check=val -- disable the 'leak check' for subtyping; unsound, but useful for tests
-    -Z                                 no-link=val -- compile without linking
-    -Z                        no-parallel-llvm=val -- run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)
-    -Z                     no-profiler-runtime=val -- prevent automatic injection of the profiler_builtins crate
-    -Z                 no-unique-section-names=val -- do not use unique names for text and data sections when -Z function-sections is used
-    -Z                          normalize-docs=val -- normalize associated items in rustdoc when generating documentation
-    -Z                                     oom=val -- panic strategy for out-of-memory handling
-    -Z                  osx-rpath-install-name=val -- pass `-install_name @rpath/...` to the macOS linker (default: no)
-    -Z                     packed-bundled-libs=val -- change rlib format to store native libraries as archives
-    -Z                       panic-abort-tests=val -- support compiling tests with panic=abort (default: no)
-    -Z                           panic-in-drop=val -- panic strategy for panics in drops
-    -Z                              parse-only=val -- parse only; do not compile, assemble, or link (default: no)
-    -Z                              perf-stats=val -- print some performance-related statistics (default: no)
-    -Z pick-stable-methods-before-any-unstable=val -- try to pick stable methods first before picking any unstable methods (default: yes)
-    -Z                                     plt=val -- whether to use the PLT when calling into shared libraries;
+    -Z                     keep-hygiene-data=val -- keep hygiene data after analysis (default: no)
+    -Z                           layout-seed=val -- seed layout randomization
+    -Z                       link-directives=val -- honor #[link] directives in the compiled crate (default: yes)
+    -Z                 link-native-libraries=val -- link native libraries in the linker invocation (default: yes)
+    -Z                             link-only=val -- link the `.rlink` file generated by `-Z no-link` (default: no)
+    -Z                          llvm-plugins=val -- a list LLVM plugins to enable (space separated)
+    -Z                       llvm-time-trace=val -- generate JSON tracing data file from LLVM data (default: no)
+    -Z                       location-detail=val -- what location details should be tracked when using caller_location, either `none`, or a comma separated list of location details, for which valid options are `file`, `line`, and `column` (default: `file,line,column`)
+    -Z                                    ls=val -- list the symbols defined by a library crate (default: no)
+    -Z                       macro-backtrace=val -- show macro backtraces (default: no)
+    -Z           maximal-hir-to-mir-coverage=val -- save as much information as possible about the correspondence between MIR and HIR as source scopes (default: no)
+    -Z                       merge-functions=val -- control the operation of the MergeFunctions LLVM pass, taking the same values as the target option of the same name
+    -Z                            meta-stats=val -- gather metadata statistics (default: no)
+    -Z                        mir-emit-retag=val -- emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 (default: no)
+    -Z                     mir-enable-passes=val -- use like `-Zmir-enable-passes=+DestProp,-InstCombine`. Forces the specified passes to be enabled, overriding all other checks. Passes that are not specified are enabled or disabled by other flags as usual.
+    -Z                         mir-opt-level=val -- MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)
+    -Z      mir-pretty-relative-line-numbers=val -- use line numbers relative to the function in mir pretty printing
+    -Z                       move-size-limit=val -- the size at which the `large_assignments` lint starts to be emitted
+    -Z                       mutable-noalias=val -- emit noalias metadata for mutable references (default: yes)
+    -Z                             nll-facts=val -- dump facts from NLL analysis into side files (default: no)
+    -Z                         nll-facts-dir=val -- the directory the NLL facts are dumped into (default: `nll-facts`)
+    -Z                           no-analysis=val -- parse and expand the source, but run no analysis
+    -Z                            no-codegen=val -- run all passes except codegen; no output
+    -Z            no-generate-arange-section=val -- omit DWARF address ranges that give faster lookups
+    -Z                        no-jump-tables=val -- disable the jump tables and lookup tables that can be generated from a switch case lowering
+    -Z                         no-leak-check=val -- disable the 'leak check' for subtyping; unsound, but useful for tests
+    -Z                               no-link=val -- compile without linking
+    -Z                      no-parallel-llvm=val -- run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)
+    -Z                   no-profiler-runtime=val -- prevent automatic injection of the profiler_builtins crate
+    -Z               no-unique-section-names=val -- do not use unique names for text and data sections when -Z function-sections is used
+    -Z                        normalize-docs=val -- normalize associated items in rustdoc when generating documentation
+    -Z                                   oom=val -- panic strategy for out-of-memory handling
+    -Z                osx-rpath-install-name=val -- pass `-install_name @rpath/...` to the macOS linker (default: no)
+    -Z                   packed-bundled-libs=val -- change rlib format to store native libraries as archives
+    -Z                     panic-abort-tests=val -- support compiling tests with panic=abort (default: no)
+    -Z                         panic-in-drop=val -- panic strategy for panics in drops
+    -Z                            parse-only=val -- parse only; do not compile, assemble, or link (default: no)
+    -Z                            perf-stats=val -- print some performance-related statistics (default: no)
+    -Z                                   plt=val -- whether to use the PLT when calling into shared libraries;
         only has effect for PIC code on systems with ELF binaries
         (default: PLT is disabled if full relro is enabled)
-    -Z                                polonius=val -- enable polonius-based borrow-checker (default: no)
-    -Z                            polymorphize=val -- perform polymorphization analysis
-    -Z                            pre-link-arg=val -- a single extra argument to prepend the linker invocation (can be used several times)
-    -Z                           pre-link-args=val -- extra arguments to prepend to the linker invocation (space separated)
-    -Z           precise-enum-drop-elaboration=val -- use a more precise version of drop elaboration for matches on enums (default: yes). This results in better codegen, but has caused miscompilations on some tier 2 platforms. See #77382 and #74551.
-    -Z                              print-fuel=val -- make rustc print the total optimization fuel used by a crate
-    -Z                       print-llvm-passes=val -- print the LLVM optimization passes being run (default: no)
-    -Z                        print-mono-items=val -- print the result of the monomorphization collection pass
-    -Z                        print-type-sizes=val -- print layout information for each type encountered (default: no)
-    -Z                    proc-macro-backtrace=val -- show backtraces for panics during proc-macro execution (default: no)
-    -Z           proc-macro-execution-strategy=val -- how to run proc-macro code (default: same-thread)
-    -Z                                 profile=val -- insert profiling code (default: no)
-    -Z                        profile-closures=val -- profile size of closures
-    -Z                            profile-emit=val -- file path to emit profiling data at runtime when using 'profile' (default based on relative source path)
-    -Z                      profile-sample-use=val -- use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO)
-    -Z                        profiler-runtime=val -- name of the profiler runtime crate to automatically inject (default: `profiler_builtins`)
-    -Z                         query-dep-graph=val -- enable queries of the dependency graph for regression testing (default: no)
-    -Z                        randomize-layout=val -- randomize the layout of types (default: no)
-    -Z                   relax-elf-relocations=val -- whether ELF relocations can be relaxed
-    -Z                             relro-level=val -- choose which RELRO level to use
-    -Z                        remap-cwd-prefix=val -- remap paths under the current working directory to this path prefix
-    -Z                     report-delayed-bugs=val -- immediately print bugs registered with `delay_span_bug` (default: no)
-    -Z                               sanitizer=val -- use a sanitizer
-    -Z          sanitizer-memory-track-origins=val -- enable origins tracking in MemorySanitizer
-    -Z                       sanitizer-recover=val -- enable recovery for selected sanitizers
-    -Z                  saturating-float-casts=val -- make float->int casts UB-free: numbers outside the integer type's range are clipped to the max/min integer respectively, and NaN is mapped to 0 (default: yes)
-    -Z                            self-profile=val -- run the self profiler and output the raw event data
-    -Z                    self-profile-counter=val -- counter used by the self profiler (default: `wall-time`), one of:
+    -Z                              polonius=val -- enable polonius-based borrow-checker (default: no)
+    -Z                          polymorphize=val -- perform polymorphization analysis
+    -Z                          pre-link-arg=val -- a single extra argument to prepend the linker invocation (can be used several times)
+    -Z                         pre-link-args=val -- extra arguments to prepend to the linker invocation (space separated)
+    -Z         precise-enum-drop-elaboration=val -- use a more precise version of drop elaboration for matches on enums (default: yes). This results in better codegen, but has caused miscompilations on some tier 2 platforms. See #77382 and #74551.
+    -Z                            print-fuel=val -- make rustc print the total optimization fuel used by a crate
+    -Z                     print-llvm-passes=val -- print the LLVM optimization passes being run (default: no)
+    -Z                      print-mono-items=val -- print the result of the monomorphization collection pass
+    -Z                      print-type-sizes=val -- print layout information for each type encountered (default: no)
+    -Z                  proc-macro-backtrace=val -- show backtraces for panics during proc-macro execution (default: no)
+    -Z         proc-macro-execution-strategy=val -- how to run proc-macro code (default: same-thread)
+    -Z                               profile=val -- insert profiling code (default: no)
+    -Z                      profile-closures=val -- profile size of closures
+    -Z                          profile-emit=val -- file path to emit profiling data at runtime when using 'profile' (default based on relative source path)
+    -Z                    profile-sample-use=val -- use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO)
+    -Z                      profiler-runtime=val -- name of the profiler runtime crate to automatically inject (default: `profiler_builtins`)
+    -Z                       query-dep-graph=val -- enable queries of the dependency graph for regression testing (default: no)
+    -Z                      randomize-layout=val -- randomize the layout of types (default: no)
+    -Z                 relax-elf-relocations=val -- whether ELF relocations can be relaxed
+    -Z                           relro-level=val -- choose which RELRO level to use
+    -Z                      remap-cwd-prefix=val -- remap paths under the current working directory to this path prefix
+    -Z                   report-delayed-bugs=val -- immediately print bugs registered with `delay_span_bug` (default: no)
+    -Z                             sanitizer=val -- use a sanitizer
+    -Z        sanitizer-memory-track-origins=val -- enable origins tracking in MemorySanitizer
+    -Z                     sanitizer-recover=val -- enable recovery for selected sanitizers
+    -Z                saturating-float-casts=val -- make float->int casts UB-free: numbers outside the integer type's range are clipped to the max/min integer respectively, and NaN is mapped to 0 (default: yes)
+    -Z                          self-profile=val -- run the self profiler and output the raw event data
+    -Z                  self-profile-counter=val -- counter used by the self profiler (default: `wall-time`), one of:
         `wall-time` (monotonic clock, i.e. `std::time::Instant`)
         `instructions:u` (retired instructions, userspace-only)
         `instructions-minus-irqs:u` (subtracting hardware interrupt counts for extra accuracy)
-    -Z                     self-profile-events=val -- specify the events recorded by the self profiler;
+    -Z                   self-profile-events=val -- specify the events recorded by the self profiler;
         for example: `-Z self-profile-events=default,query-keys`
         all options: none, all, default, generic-activity, query-provider, query-cache-hit
                      query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm, artifact-sizes
-    -Z                          share-generics=val -- make the current crate share its generic instantiations
-    -Z                               show-span=val -- show spans for compiler debugging (expr|pat|ty)
-    -Z         simulate-remapped-rust-src-base=val -- simulate the effect of remap-debuginfo = true at bootstrapping by remapping path to rust's source base directory. only meant for testing purposes
-    -Z                              span-debug=val -- forward proc_macro::Span's `Debug` impl to `Span`
-    -Z                       span-free-formats=val -- exclude spans when debug-printing compiler state (default: no)
-    -Z                    split-dwarf-inlining=val -- provide minimal debug info in the object/executable to facilitate online symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF
-    -Z                        split-dwarf-kind=val -- split dwarf variant (only if -Csplit-debuginfo is enabled and on relevant platform)
+    -Z                        share-generics=val -- make the current crate share its generic instantiations
+    -Z                             show-span=val -- show spans for compiler debugging (expr|pat|ty)
+    -Z       simulate-remapped-rust-src-base=val -- simulate the effect of remap-debuginfo = true at bootstrapping by remapping path to rust's source base directory. only meant for testing purposes
+    -Z                            span-debug=val -- forward proc_macro::Span's `Debug` impl to `Span`
+    -Z                     span-free-formats=val -- exclude spans when debug-printing compiler state (default: no)
+    -Z                  split-dwarf-inlining=val -- provide minimal debug info in the object/executable to facilitate online symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF
+    -Z                      split-dwarf-kind=val -- split dwarf variant (only if -Csplit-debuginfo is enabled and on relevant platform)
         (default: `split`)
 
         `split`: sections which do not require relocation are written into a DWARF object (`.dwo`)
                  file which is ignored by the linker
         `single`: sections which do not require relocation are written into object file but ignored
                   by the linker
-    -Z                      src-hash-algorithm=val -- hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)
-    -Z                         stack-protector=val -- control stack smash protection strategy (`rustc --print stack-protector-strategies` for details)
-    -Z                      strict-init-checks=val -- control if mem::uninitialized and mem::zeroed panic on more UB
-    -Z                                   strip=val -- tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)
-    -Z                 symbol-mangling-version=val -- which mangling version to use for symbol names ('legacy' (default) or 'v0')
-    -Z                                   teach=val -- show extended diagnostic help (default: no)
-    -Z                               temps-dir=val -- the directory the intermediate files are written to
-    -Z                           terminal-urls=val -- use the OSC 8 hyperlink terminal specification to print hyperlinks in the compiler output
-    -Z                                 thinlto=val -- enable ThinLTO when possible
-    -Z                           thir-unsafeck=val -- use the THIR unsafety checker (default: no)
-    -Z                                 threads=val -- use a thread pool with N threads
-    -Z                        time-llvm-passes=val -- measure time of each LLVM pass (default: no)
-    -Z                             time-passes=val -- measure time of each rustc pass (default: no)
-    -Z                   tiny-const-eval-limit=val -- sets a tiny, non-configurable limit for const eval; useful for compiler tests
-    -Z                               tls-model=val -- choose the TLS model to use (`rustc --print tls-models` for details)
-    -Z                            trace-macros=val -- for every macro invocation, print its name and arguments (default: no)
-    -Z                       track-diagnostics=val -- tracks where in rustc a diagnostic was emitted
-    -Z                            trait-solver=val -- specify the trait solver mode used by rustc (default: classic)
-    -Z                translate-additional-ftl=val -- additional fluent translation to preferentially use (for testing translation)
-    -Z        translate-directionality-markers=val -- emit directionality isolation markers in translated diagnostics
-    -Z                          translate-lang=val -- language identifier for diagnostic output
-    -Z   translate-remapped-path-to-local-path=val -- translate remapped paths into local paths when possible (default: yes)
-    -Z                        trap-unreachable=val -- generate trap instructions for unreachable intrinsics (default: use target setting, usually yes)
-    -Z                        treat-err-as-bug=val -- treat error number `val` that occurs as bug
-    -Z                   trim-diagnostic-paths=val -- in diagnostics, use heuristics to shorten paths referring to items
-    -Z                                tune-cpu=val -- select processor to schedule for (`rustc --print target-cpus` for details)
-    -Z                              ui-testing=val -- emit compiler diagnostics in a form suitable for UI testing (default: no)
-    -Z            uninit-const-chunk-threshold=val -- allow generating const initializers with mixed init/uninit chunks, and set the maximum number of chunks for which this is allowed (default: 16)
-    -Z          unleash-the-miri-inside-of-you=val -- take the brakes off const evaluation. NOTE: this is unsound (default: no)
-    -Z                                unpretty=val -- present the input source, unstable (and less-pretty) variants;
+    -Z                    src-hash-algorithm=val -- hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)
+    -Z                       stack-protector=val -- control stack smash protection strategy (`rustc --print stack-protector-strategies` for details)
+    -Z                    strict-init-checks=val -- control if mem::uninitialized and mem::zeroed panic on more UB
+    -Z                                 strip=val -- tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)
+    -Z               symbol-mangling-version=val -- which mangling version to use for symbol names ('legacy' (default) or 'v0')
+    -Z                                 teach=val -- show extended diagnostic help (default: no)
+    -Z                             temps-dir=val -- the directory the intermediate files are written to
+    -Z                         terminal-urls=val -- use the OSC 8 hyperlink terminal specification to print hyperlinks in the compiler output
+    -Z                               thinlto=val -- enable ThinLTO when possible
+    -Z                         thir-unsafeck=val -- use the THIR unsafety checker (default: no)
+    -Z                               threads=val -- use a thread pool with N threads
+    -Z                      time-llvm-passes=val -- measure time of each LLVM pass (default: no)
+    -Z                           time-passes=val -- measure time of each rustc pass (default: no)
+    -Z                 tiny-const-eval-limit=val -- sets a tiny, non-configurable limit for const eval; useful for compiler tests
+    -Z                             tls-model=val -- choose the TLS model to use (`rustc --print tls-models` for details)
+    -Z                          trace-macros=val -- for every macro invocation, print its name and arguments (default: no)
+    -Z                     track-diagnostics=val -- tracks where in rustc a diagnostic was emitted
+    -Z                          trait-solver=val -- specify the trait solver mode used by rustc (default: classic)
+    -Z              translate-additional-ftl=val -- additional fluent translation to preferentially use (for testing translation)
+    -Z      translate-directionality-markers=val -- emit directionality isolation markers in translated diagnostics
+    -Z                        translate-lang=val -- language identifier for diagnostic output
+    -Z translate-remapped-path-to-local-path=val -- translate remapped paths into local paths when possible (default: yes)
+    -Z                      trap-unreachable=val -- generate trap instructions for unreachable intrinsics (default: use target setting, usually yes)
+    -Z                      treat-err-as-bug=val -- treat error number `val` that occurs as bug
+    -Z                 trim-diagnostic-paths=val -- in diagnostics, use heuristics to shorten paths referring to items
+    -Z                              tune-cpu=val -- select processor to schedule for (`rustc --print target-cpus` for details)
+    -Z                            ui-testing=val -- emit compiler diagnostics in a form suitable for UI testing (default: no)
+    -Z          uninit-const-chunk-threshold=val -- allow generating const initializers with mixed init/uninit chunks, and set the maximum number of chunks for which this is allowed (default: 16)
+    -Z        unleash-the-miri-inside-of-you=val -- take the brakes off const evaluation. NOTE: this is unsound (default: no)
+    -Z                              unpretty=val -- present the input source, unstable (and less-pretty) variants;
         `normal`, `identified`,
         `expanded`, `expanded,identified`,
         `expanded,hygiene` (with internal representations),
@@ -207,11 +207,11 @@
         `hir,typed` (HIR with types for each node),
         `hir-tree` (dump the raw HIR),
         `mir` (the MIR), or `mir-cfg` (graphviz formatted MIR)
-    -Z                        unsound-mir-opts=val -- enable unsound and buggy MIR optimizations (default: no)
-    -Z                        unstable-options=val -- adds unstable command line options to rustc interface (default: no)
-    -Z                       use-ctors-section=val -- use legacy .ctors section for initializers rather than .init_array
-    -Z                            validate-mir=val -- validate MIR after each transformation
-    -Z                                 verbose=val -- in general, enable more debug printouts (default: no)
-    -Z                          verify-llvm-ir=val -- verify LLVM IR (default: no)
-    -Z            virtual-function-elimination=val -- enables dead virtual function elimination optimization. Requires `-Clto[=[fat,yes]]`
-    -Z                         wasi-exec-model=val -- whether to build a wasi command or reactor
+    -Z                      unsound-mir-opts=val -- enable unsound and buggy MIR optimizations (default: no)
+    -Z                      unstable-options=val -- adds unstable command line options to rustc interface (default: no)
+    -Z                     use-ctors-section=val -- use legacy .ctors section for initializers rather than .init_array
+    -Z                          validate-mir=val -- validate MIR after each transformation
+    -Z                               verbose=val -- in general, enable more debug printouts (default: no)
+    -Z                        verify-llvm-ir=val -- verify LLVM IR (default: no)
+    -Z          virtual-function-elimination=val -- enables dead virtual function elimination optimization. Requires `-Clto[=[fat,yes]]`
+    -Z                       wasi-exec-model=val -- whether to build a wasi command or reactor
diff --git a/tests/rustdoc/intra-doc/basic.rs b/tests/rustdoc/intra-doc/basic.rs
index e2d3ef425cb..96e21137b2d 100644
--- a/tests/rustdoc/intra-doc/basic.rs
+++ b/tests/rustdoc/intra-doc/basic.rs
@@ -2,7 +2,9 @@
 // @has - '//a/@href' 'struct.ThisType.html'
 // @has - '//a/@title' 'struct basic::ThisType'
 // @has - '//a/@href' 'struct.ThisType.html#method.this_method'
-// @has - '//a/@title' 'associated function basic::ThisType::this_method'
+// @has - '//a/@title' 'method basic::ThisType::this_method'
+// @has - '//a/@href' 'struct.ThisType.html#method.this_assoc_fn'
+// @has - '//a/@title' 'associated function basic::ThisType::this_assoc_fn'
 // @has - '//a/@href' 'enum.ThisEnum.html'
 // @has - '//a/@title' 'enum basic::ThisEnum'
 // @has - '//a/@href' 'enum.ThisEnum.html#variant.ThisVariant'
@@ -10,7 +12,9 @@
 // @has - '//a/@href' 'trait.ThisTrait.html'
 // @has - '//a/@title' 'trait basic::ThisTrait'
 // @has - '//a/@href' 'trait.ThisTrait.html#tymethod.this_associated_method'
-// @has - '//a/@title' 'associated function basic::ThisTrait::this_associated_method'
+// @has - '//a/@title' 'method basic::ThisTrait::this_associated_method'
+// @has - '//a/@href' 'trait.ThisTrait.html#tymethod.this_associated_fn'
+// @has - '//a/@title' 'associated function basic::ThisTrait::this_associated_fn'
 // @has - '//a/@href' 'trait.ThisTrait.html#associatedtype.ThisAssociatedType'
 // @has - '//a/@title' 'associated type basic::ThisTrait::ThisAssociatedType'
 // @has - '//a/@href' 'trait.ThisTrait.html#associatedconstant.THIS_ASSOCIATED_CONST'
@@ -37,11 +41,13 @@
 //!
 //! * [`ThisType`](ThisType)
 //! * [`ThisType::this_method`](ThisType::this_method)
+//! * [`ThisType::this_assoc_fn`](ThisType::this_assoc_fn)
 //! * [`ThisEnum`](ThisEnum)
 //! * [`ThisEnum::ThisVariant`](ThisEnum::ThisVariant)
 //! * [`ThisEnum::ThisVariantCtor`](ThisEnum::ThisVariantCtor)
 //! * [`ThisTrait`](ThisTrait)
 //! * [`ThisTrait::this_associated_method`](ThisTrait::this_associated_method)
+//! * [`ThisTrait::this_associated_fn`](ThisTrait::this_associated_fn)
 //! * [`ThisTrait::ThisAssociatedType`](ThisTrait::ThisAssociatedType)
 //! * [`ThisTrait::THIS_ASSOCIATED_CONST`](ThisTrait::THIS_ASSOCIATED_CONST)
 //! * [`ThisAlias`](ThisAlias)
@@ -68,13 +74,15 @@ macro_rules! this_macro {
 pub struct ThisType;
 
 impl ThisType {
-    pub fn this_method() {}
+    pub fn this_assoc_fn() {}
+    pub fn this_method(self) {}
 }
 pub enum ThisEnum { ThisVariant, ThisVariantCtor(u32), }
 pub trait ThisTrait {
     type ThisAssociatedType;
     const THIS_ASSOCIATED_CONST: u8;
-    fn this_associated_method();
+    fn this_associated_fn();
+    fn this_associated_method(&self);
 }
 pub type ThisAlias = Result<(), ()>;
 pub union ThisUnion { this_field: usize, }
diff --git a/tests/rustdoc/issue-108281.rs b/tests/rustdoc/issue-108281.rs
new file mode 100644
index 00000000000..8e1b6ba88a6
--- /dev/null
+++ b/tests/rustdoc/issue-108281.rs
@@ -0,0 +1,25 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/108281>.
+// It ensures that the attributes on the first reexport are not duplicated.
+
+#![crate_name = "foo"]
+
+// @has 'foo/index.html'
+
+#[doc(hidden)]
+pub fn bar() {}
+mod sub {
+    pub fn public() {}
+}
+
+// @matches - '//*[@class="desc docblock-short"]' '^Displayed$'
+/// Displayed
+#[doc(inline)]
+pub use crate::bar as Bar;
+// @matches - '//*[@class="desc docblock-short"]' '^Hello\sDisplayed$'
+#[doc(inline)]
+/// Hello
+pub use crate::Bar as Bar2;
+
+// @matches - '//*[@class="desc docblock-short"]' '^Public$'
+/// Public
+pub use crate::sub::public as Public;
diff --git a/tests/rustdoc/item-desc-list-at-start.item-table.html b/tests/rustdoc/item-desc-list-at-start.item-table.html
new file mode 100644
index 00000000000..72bde573cea
--- /dev/null
+++ b/tests/rustdoc/item-desc-list-at-start.item-table.html
@@ -0,0 +1 @@
+<ul class="item-table"><li><div class="item-name"><a class="constant" href="constant.MY_CONSTANT.html" title="constant item_desc_list_at_start::MY_CONSTANT">MY_CONSTANT</a></div><div class="desc docblock-short">Groups: <code>SamplePatternSGIS</code>, <code>SamplePatternEXT</code></div></li></ul>
\ No newline at end of file
diff --git a/tests/rustdoc/item-desc-list-at-start.rs b/tests/rustdoc/item-desc-list-at-start.rs
new file mode 100644
index 00000000000..d88c61d333e
--- /dev/null
+++ b/tests/rustdoc/item-desc-list-at-start.rs
@@ -0,0 +1,9 @@
+// @has item_desc_list_at_start/index.html
+// @count - '//ul[@class="item-table"]/li/div/li' 0
+// @count - '//ul[@class="item-table"]/li' 1
+// @snapshot item-table - '//ul[@class="item-table"]'
+
+// based on https://docs.rs/gl_constants/0.1.1/src/gl_constants/lib.rs.html#16
+
+/// * Groups: `SamplePatternSGIS`, `SamplePatternEXT`
+pub const MY_CONSTANT: usize = 0;
diff --git a/tests/rustdoc/reexports-of-same-name.rs b/tests/rustdoc/reexports-of-same-name.rs
new file mode 100644
index 00000000000..fe6f1b38ca6
--- /dev/null
+++ b/tests/rustdoc/reexports-of-same-name.rs
@@ -0,0 +1,26 @@
+// This test ensures that there are 4 imports as expected:
+// * 2 for `Foo`
+// * 2 for `Bar`
+
+#![crate_name = "foo"]
+
+// @has 'foo/index.html'
+
+pub mod nested {
+    /// Foo the struct
+    pub struct Foo {}
+
+    #[allow(non_snake_case)]
+    /// Foo the function
+    pub fn Foo() {}
+}
+
+// @count - '//*[@id="main-content"]//code' 'pub use nested::Foo;' 2
+// @has - '//*[@id="reexport.Foo"]//a[@href="nested/struct.Foo.html"]' 'Foo'
+// @has - '//*[@id="reexport.Foo-1"]//a[@href="nested/fn.Foo.html"]' 'Foo'
+pub use nested::Foo;
+
+// @count - '//*[@id="main-content"]//code' 'pub use Foo as Bar;' 2
+// @has - '//*[@id="reexport.Bar"]//a[@href="nested/struct.Foo.html"]' 'Foo'
+// @has - '//*[@id="reexport.Bar-1"]//a[@href="nested/fn.Foo.html"]' 'Foo'
+pub use Foo as Bar;
diff --git a/tests/ui-fulldeps/create-dir-all-bare.rs b/tests/ui-fulldeps/create-dir-all-bare.rs
deleted file mode 100644
index 4554680ec24..00000000000
--- a/tests/ui-fulldeps/create-dir-all-bare.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-// run-pass
-
-use std::env;
-use std::fs;
-use std::path::PathBuf;
-
-fn main() {
-    let path = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap());
-    env::set_current_dir(&path).unwrap();
-    fs::create_dir_all("create-dir-all-bare").unwrap();
-}
diff --git a/tests/ui-fulldeps/fluent-messages/duplicate.ftl b/tests/ui-fulldeps/fluent-messages/duplicate.ftl
new file mode 100644
index 00000000000..871550b231a
--- /dev/null
+++ b/tests/ui-fulldeps/fluent-messages/duplicate.ftl
@@ -0,0 +1,3 @@
+no_crate_a_b_key = Value
+
+no_crate_a_b_key = Another Value
diff --git a/tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl b/tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl
index 016cbeef662..3088b1f8dc8 100644
--- a/tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl
+++ b/tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl
@@ -1,2 +1,2 @@
-label_with_hyphens_some_slug = hi
+no_crate_some_slug = hi
     .label-has-hyphens = test
diff --git a/tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl b/tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl
index 9bd035c1bba..0a64e3894bd 100644
--- a/tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl
+++ b/tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl
@@ -1,2 +1,2 @@
 with-hyphens = 1234
-test-crate_foo = abcd
+no-crate_foo = abcd
diff --git a/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl b/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl
index 0cd8229b230..4c6514a9770 100644
--- a/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl
+++ b/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl
@@ -1 +1 @@
-missing_message_ref = {message}
+no_crate_missing_message_ref = {message}
diff --git a/tests/ui-fulldeps/fluent-messages/missing-message.ftl b/tests/ui-fulldeps/fluent-messages/missing-message.ftl
index 74b2aa1d44d..61f56fd4d57 100644
--- a/tests/ui-fulldeps/fluent-messages/missing-message.ftl
+++ b/tests/ui-fulldeps/fluent-messages/missing-message.ftl
@@ -1 +1 @@
-missing_message =
+no_crate_missing_message =
diff --git a/tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl b/tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl
index 86ba9a268f3..a64c85094f1 100644
--- a/tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl
+++ b/tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl
@@ -1 +1 @@
-slug_with_hyphens_this-slug-has-hyphens = hi
+no_crate_this-slug-has-hyphens = hi
diff --git a/tests/ui-fulldeps/fluent-messages/test.rs b/tests/ui-fulldeps/fluent-messages/test.rs
index 74303e97dba..66575eb8e30 100644
--- a/tests/ui-fulldeps/fluent-messages/test.rs
+++ b/tests/ui-fulldeps/fluent-messages/test.rs
@@ -21,87 +21,74 @@ pub enum SubdiagnosticMessage {
 mod missing_absolute {
     use super::fluent_messages;
 
-    fluent_messages! {
-        missing_absolute => "/definitely_does_not_exist.ftl",
-//~^ ERROR could not open Fluent resource
-    }
+    fluent_messages! { "/definitely_does_not_exist.ftl" }
+    //~^ ERROR could not open Fluent resource
 }
 
 mod missing_relative {
     use super::fluent_messages;
 
-    fluent_messages! {
-        missing_relative => "../definitely_does_not_exist.ftl",
-//~^ ERROR could not open Fluent resource
-    }
+    fluent_messages! { "../definitely_does_not_exist.ftl" }
+    //~^ ERROR could not open Fluent resource
 }
 
 mod missing_message {
     use super::fluent_messages;
 
-    fluent_messages! {
-        missing_message => "./missing-message.ftl",
-//~^ ERROR could not parse Fluent resource
-    }
+    fluent_messages! { "./missing-message.ftl" }
+    //~^ ERROR could not parse Fluent resource
 }
 
 mod duplicate {
     use super::fluent_messages;
 
-    fluent_messages! {
-//~^ ERROR the name `a_b_key` is defined multiple times
-        a => "./duplicate-a.ftl",
-        a_b => "./duplicate-a-b.ftl",
-//~^ ERROR overrides existing message: `a_b_key`
-    }
+    fluent_messages! { "./duplicate.ftl" }
+    //~^ ERROR overrides existing message: `no_crate_a_b_key`
 }
 
 mod slug_with_hyphens {
     use super::fluent_messages;
 
-    fluent_messages! {
-        slug_with_hyphens => "./slug-with-hyphens.ftl",
-//~^ ERROR name `slug_with_hyphens_this-slug-has-hyphens` contains a '-' character
-    }
+    fluent_messages! { "./slug-with-hyphens.ftl" }
+    //~^ ERROR name `no_crate_this-slug-has-hyphens` contains a '-' character
 }
 
 mod label_with_hyphens {
     use super::fluent_messages;
 
-    fluent_messages! {
-        label_with_hyphens => "./label-with-hyphens.ftl",
-//~^ ERROR attribute `label-has-hyphens` contains a '-' character
-    }
+    fluent_messages! { "./label-with-hyphens.ftl" }
+    //~^ ERROR attribute `label-has-hyphens` contains a '-' character
 }
 
 mod valid {
     use super::fluent_messages;
 
-    fluent_messages! {
-        valid => "./valid.ftl",
-    }
+    fluent_messages! { "./valid.ftl" }
 
-    use self::fluent_generated::{DEFAULT_LOCALE_RESOURCES, valid_key};
+    mod test_generated {
+        use super::{fluent_generated::no_crate_key, DEFAULT_LOCALE_RESOURCE};
+    }
 }
 
 mod missing_crate_name {
     use super::fluent_messages;
 
-    fluent_messages! {
-        test_crate => "./missing-crate-name.ftl",
-//~^ ERROR name `test-crate_foo` contains a '-' character
-//~| ERROR name `with-hyphens` contains a '-' character
-//~| ERROR name `with-hyphens` does not start with the crate name
-    }
+    fluent_messages! { "./missing-crate-name.ftl" }
+    //~^ ERROR name `no-crate_foo` contains a '-' character
+    //~| ERROR name `with-hyphens` contains a '-' character
+    //~| ERROR name `with-hyphens` does not start with the crate name
 
-    use self::fluent_generated::{DEFAULT_LOCALE_RESOURCES, test_crate_foo, with_hyphens};
+    mod test_generated {
+        use super::{
+            fluent_generated::{no_crate_foo, with_hyphens},
+            DEFAULT_LOCALE_RESOURCE,
+        };
+    }
 }
 
 mod missing_message_ref {
     use super::fluent_messages;
 
-    fluent_messages! {
-        missing => "./missing-message-ref.ftl"
-//~^ ERROR referenced message `message` does not exist
-    }
+    fluent_messages! { "./missing-message-ref.ftl" }
+    //~^ ERROR referenced message `message` does not exist
 }
diff --git a/tests/ui-fulldeps/fluent-messages/test.stderr b/tests/ui-fulldeps/fluent-messages/test.stderr
index 2631b0a6232..c7961ed22f2 100644
--- a/tests/ui-fulldeps/fluent-messages/test.stderr
+++ b/tests/ui-fulldeps/fluent-messages/test.stderr
@@ -1,106 +1,87 @@
 error: could not open Fluent resource
-  --> $DIR/test.rs:25:29
+  --> $DIR/test.rs:24:24
    |
-LL |         missing_absolute => "/definitely_does_not_exist.ftl",
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fluent_messages! { "/definitely_does_not_exist.ftl" }
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: os-specific message
 
 error: could not open Fluent resource
-  --> $DIR/test.rs:34:29
+  --> $DIR/test.rs:31:24
    |
-LL |         missing_relative => "../definitely_does_not_exist.ftl",
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fluent_messages! { "../definitely_does_not_exist.ftl" }
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: os-specific message
 
 error: could not parse Fluent resource
-  --> $DIR/test.rs:43:28
+  --> $DIR/test.rs:38:24
    |
-LL |         missing_message => "./missing-message.ftl",
-   |                            ^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fluent_messages! { "./missing-message.ftl" }
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: see additional errors emitted
 
-error: expected a message field for "missing_message"
+error: expected a message field for "no_crate_missing_message"
  --> ./missing-message.ftl:1:1
   |
-1 | missing_message =
-  | ^^^^^^^^^^^^^^^^^
+1 | no_crate_missing_message =
+  | ^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
 
-error: overrides existing message: `a_b_key`
-  --> $DIR/test.rs:54:16
+error: overrides existing message: `no_crate_a_b_key`
+  --> $DIR/test.rs:45:24
    |
-LL |         a_b => "./duplicate-a-b.ftl",
-   |                ^^^^^^^^^^^^^^^^^^^^^
-   |
-help: previously defined in this resource
-  --> $DIR/test.rs:53:14
-   |
-LL |         a => "./duplicate-a.ftl",
-   |              ^^^^^^^^^^^^^^^^^^^
-
-error[E0428]: the name `a_b_key` is defined multiple times
-  --> $DIR/test.rs:51:5
-   |
-LL |     fluent_messages! {
-   |     ^^^^^^^^^^^^^^^^
-   |     |
-   |     `a_b_key` redefined here
-   |     previous definition of the value `a_b_key` here
-   |
-   = note: os-specific message
-   = note: os-specific message
+LL |     fluent_messages! { "./duplicate.ftl" }
+   |                        ^^^^^^^^^^^^^^^^^
 
-error: name `slug_with_hyphens_this-slug-has-hyphens` contains a '-' character
-  --> $DIR/test.rs:63:30
+error: name `no_crate_this-slug-has-hyphens` contains a '-' character
+  --> $DIR/test.rs:52:24
    |
-LL |         slug_with_hyphens => "./slug-with-hyphens.ftl",
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fluent_messages! { "./slug-with-hyphens.ftl" }
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: replace any '-'s with '_'s
 
 error: attribute `label-has-hyphens` contains a '-' character
-  --> $DIR/test.rs:72:31
+  --> $DIR/test.rs:59:24
    |
-LL |         label_with_hyphens => "./label-with-hyphens.ftl",
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fluent_messages! { "./label-with-hyphens.ftl" }
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: replace any '-'s with '_'s
 
 error: name `with-hyphens` contains a '-' character
-  --> $DIR/test.rs:91:23
+  --> $DIR/test.rs:76:24
    |
-LL |         test_crate => "./missing-crate-name.ftl",
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fluent_messages! { "./missing-crate-name.ftl" }
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: replace any '-'s with '_'s
 
 error: name `with-hyphens` does not start with the crate name
-  --> $DIR/test.rs:91:23
+  --> $DIR/test.rs:76:24
    |
-LL |         test_crate => "./missing-crate-name.ftl",
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fluent_messages! { "./missing-crate-name.ftl" }
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: prepend `test_crate_` to the slug name: `test_crate_with_hyphens`
+   = help: prepend `no_crate_` to the slug name: `no_crate_with_hyphens`
 
-error: name `test-crate_foo` contains a '-' character
-  --> $DIR/test.rs:91:23
+error: name `no-crate_foo` contains a '-' character
+  --> $DIR/test.rs:76:24
    |
-LL |         test_crate => "./missing-crate-name.ftl",
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fluent_messages! { "./missing-crate-name.ftl" }
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: replace any '-'s with '_'s
 
-error: referenced message `message` does not exist (in message `missing_message_ref`)
-  --> $DIR/test.rs:104:20
+error: referenced message `message` does not exist (in message `no_crate_missing_message_ref`)
+  --> $DIR/test.rs:92:24
    |
-LL |         missing => "./missing-message-ref.ftl"
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fluent_messages! { "./missing-message-ref.ftl" }
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: you may have meant to use a variable reference (`{$message}`)
 
-error: aborting due to 11 previous errors
+error: aborting due to 10 previous errors
 
-For more information about this error, try `rustc --explain E0428`.
diff --git a/tests/ui-fulldeps/fluent-messages/valid.ftl b/tests/ui-fulldeps/fluent-messages/valid.ftl
index 54927430600..598473adb68 100644
--- a/tests/ui-fulldeps/fluent-messages/valid.ftl
+++ b/tests/ui-fulldeps/fluent-messages/valid.ftl
@@ -1 +1 @@
-valid_key = Valid!
+no_crate_key = Valid!
diff --git a/compiler/rustc_error_messages/locales/en-US/compiletest.ftl b/tests/ui-fulldeps/internal-lints/diagnostics.ftl
index 55061fbce7e..cb2d476d815 100644
--- a/compiler/rustc_error_messages/locales/en-US/compiletest.ftl
+++ b/tests/ui-fulldeps/internal-lints/diagnostics.ftl
@@ -1,4 +1,4 @@
-compiletest_example = this is an example message used in testing
+no_crate_example = this is an example message used in testing
     .note = with a note
     .help = with a help
     .suggestion = with a suggestion
diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.rs b/tests/ui-fulldeps/internal-lints/diagnostics.rs
index 643e81d99c6..3aa65d53d4e 100644
--- a/tests/ui-fulldeps/internal-lints/diagnostics.rs
+++ b/tests/ui-fulldeps/internal-lints/diagnostics.rs
@@ -13,20 +13,22 @@ extern crate rustc_span;
 
 use rustc_errors::{
     AddToDiagnostic, IntoDiagnostic, Diagnostic, DiagnosticBuilder,
-    ErrorGuaranteed, Handler, fluent, SubdiagnosticMessage,
+    ErrorGuaranteed, Handler, DiagnosticMessage, SubdiagnosticMessage,
 };
-use rustc_macros::{Diagnostic, Subdiagnostic};
+use rustc_macros::{fluent_messages, Diagnostic, Subdiagnostic};
 use rustc_span::Span;
 
+fluent_messages! { "./diagnostics.ftl" }
+
 #[derive(Diagnostic)]
-#[diag(compiletest_example)]
+#[diag(no_crate_example)]
 struct DeriveDiagnostic {
     #[primary_span]
     span: Span,
 }
 
 #[derive(Subdiagnostic)]
-#[note(compiletest_example)]
+#[note(no_crate_example)]
 struct Note {
     #[primary_span]
     span: Span,
@@ -45,7 +47,7 @@ pub struct TranslatableInIntoDiagnostic;
 
 impl<'a> IntoDiagnostic<'a, ErrorGuaranteed> for TranslatableInIntoDiagnostic {
     fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
-        handler.struct_err(fluent::compiletest_example)
+        handler.struct_err(crate::fluent_generated::no_crate_example)
     }
 }
 
@@ -68,12 +70,12 @@ impl AddToDiagnostic for TranslatableInAddToDiagnostic {
     where
         F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
     {
-        diag.note(fluent::note);
+        diag.note(crate::fluent_generated::no_crate_note);
     }
 }
 
 pub fn make_diagnostics<'a>(handler: &'a Handler) {
-    let _diag = handler.struct_err(fluent::compiletest_example);
+    let _diag = handler.struct_err(crate::fluent_generated::no_crate_example);
     //~^ ERROR diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
 
     let _diag = handler.struct_err("untranslatable diagnostic");
diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.stderr b/tests/ui-fulldeps/internal-lints/diagnostics.stderr
index 510d6a17108..6f797ebc2dd 100644
--- a/tests/ui-fulldeps/internal-lints/diagnostics.stderr
+++ b/tests/ui-fulldeps/internal-lints/diagnostics.stderr
@@ -1,5 +1,5 @@
 error: diagnostics should be created using translatable messages
-  --> $DIR/diagnostics.rs:39:17
+  --> $DIR/diagnostics.rs:41:17
    |
 LL |         handler.struct_err("untranslatable diagnostic")
    |                 ^^^^^^^^^^
@@ -11,15 +11,15 @@ LL | #![deny(rustc::untranslatable_diagnostic)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostics should be created using translatable messages
-  --> $DIR/diagnostics.rs:59:14
+  --> $DIR/diagnostics.rs:61:14
    |
 LL |         diag.note("untranslatable diagnostic");
    |              ^^^^
 
 error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
-  --> $DIR/diagnostics.rs:76:25
+  --> $DIR/diagnostics.rs:78:25
    |
-LL |     let _diag = handler.struct_err(fluent::compiletest_example);
+LL |     let _diag = handler.struct_err(crate::fluent_generated::no_crate_example);
    |                         ^^^^^^^^^^
    |
 note: the lint level is defined here
@@ -29,13 +29,13 @@ LL | #![deny(rustc::diagnostic_outside_of_impl)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
-  --> $DIR/diagnostics.rs:79:25
+  --> $DIR/diagnostics.rs:81:25
    |
 LL |     let _diag = handler.struct_err("untranslatable diagnostic");
    |                         ^^^^^^^^^^
 
 error: diagnostics should be created using translatable messages
-  --> $DIR/diagnostics.rs:79:25
+  --> $DIR/diagnostics.rs:81:25
    |
 LL |     let _diag = handler.struct_err("untranslatable diagnostic");
    |                         ^^^^^^^^^^
diff --git a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs
index bdfd9628c48..ddc86c1dc31 100644
--- a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs
+++ b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs
@@ -31,7 +31,10 @@ pub fn main() {
 }
 
 fn parse() {
-    let parse_session = ParseSess::new(FilePathMapping::empty());
+    let parse_session = ParseSess::new(
+        vec![rustc_parse::DEFAULT_LOCALE_RESOURCE],
+        FilePathMapping::empty()
+    );
 
     let path = Path::new(file!());
     let path = path.canonicalize().unwrap();
diff --git a/tests/ui-fulldeps/pprust-expr-roundtrip.rs b/tests/ui-fulldeps/pprust-expr-roundtrip.rs
index 7a91dcf0dad..e417a6a833b 100644
--- a/tests/ui-fulldeps/pprust-expr-roundtrip.rs
+++ b/tests/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -41,7 +41,7 @@ use rustc_session::parse::ParseSess;
 use rustc_span::source_map::FilePathMapping;
 use rustc_span::source_map::{FileName, Spanned, DUMMY_SP};
 use rustc_span::symbol::Ident;
-use thin_vec::thin_vec;
+use thin_vec::{thin_vec, ThinVec};
 
 fn parse_expr(ps: &ParseSess, src: &str) -> Option<P<Expr>> {
     let src_as_string = src.to_string();
@@ -76,17 +76,17 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
     for kind in 0..=19 {
         match kind {
             0 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Box(e))),
-            1 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Call(e, vec![]))),
+            1 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Call(e, thin_vec![]))),
             2 => {
                 let seg = PathSegment::from_ident(Ident::from_str("x"));
                 iter_exprs(depth - 1, &mut |e| {
                     g(ExprKind::MethodCall(Box::new(MethodCall {
-                        seg: seg.clone(), receiver: e, args: vec![make_x()], span: DUMMY_SP
+                        seg: seg.clone(), receiver: e, args: thin_vec![make_x()], span: DUMMY_SP
                     }))
                 )});
                 iter_exprs(depth - 1, &mut |e| {
                     g(ExprKind::MethodCall(Box::new(MethodCall {
-                        seg: seg.clone(), receiver: make_x(), args: vec![e], span: DUMMY_SP
+                        seg: seg.clone(), receiver: make_x(), args: thin_vec![e], span: DUMMY_SP
                     }))
                 )});
             }
@@ -111,7 +111,7 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
             }
             10 => {
                 let block = P(Block {
-                    stmts: Vec::new(),
+                    stmts: ThinVec::new(),
                     id: DUMMY_NODE_ID,
                     rules: BlockCheckMode::Default,
                     span: DUMMY_SP,
@@ -121,7 +121,7 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::If(e, block.clone(), None)));
             }
             11 => {
-                let decl = P(FnDecl { inputs: vec![], output: FnRetTy::Default(DUMMY_SP) });
+                let decl = P(FnDecl { inputs: thin_vec![], output: FnRetTy::Default(DUMMY_SP) });
                 iter_exprs(depth - 1, &mut |e| {
                     g(ExprKind::Closure(Box::new(Closure {
                         binder: ClosureBinder::NotPresent,
@@ -165,7 +165,7 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
                 g(ExprKind::Struct(P(StructExpr {
                     qself: None,
                     path,
-                    fields: vec![],
+                    fields: thin_vec![],
                     rest: StructRest::Base(make_x()),
                 })));
             }
@@ -220,7 +220,7 @@ fn main() {
 }
 
 fn run() {
-    let ps = ParseSess::new(FilePathMapping::empty());
+    let ps = ParseSess::new(vec![rustc_parse::DEFAULT_LOCALE_RESOURCE], FilePathMapping::empty());
 
     iter_exprs(2, &mut |mut e| {
         // If the pretty printer is correct, then `parse(print(e))` should be identical to `e`,
diff --git a/tests/ui-fulldeps/rename-directory.rs b/tests/ui-fulldeps/rename-directory.rs
deleted file mode 100644
index 8fc340cb918..00000000000
--- a/tests/ui-fulldeps/rename-directory.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-// run-pass
-
-#![allow(unused_must_use)]
-#![allow(unused_imports)]
-// This test can't be a unit test in std,
-// because it needs TempDir, which is in extra
-
-// ignore-cross-compile
-
-use std::env;
-use std::ffi::CString;
-use std::fs::{self, File};
-use std::path::PathBuf;
-
-fn rename_directory() {
-    let tmpdir = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap());
-    let old_path = tmpdir.join("foo/bar/baz");
-    fs::create_dir_all(&old_path).unwrap();
-    let test_file = &old_path.join("temp.txt");
-
-    File::create(test_file).unwrap();
-
-    let new_path = tmpdir.join("quux/blat");
-    fs::create_dir_all(&new_path).unwrap();
-    fs::rename(&old_path, &new_path.join("newdir"));
-    assert!(new_path.join("newdir").is_dir());
-    assert!(new_path.join("newdir/temp.txt").exists());
-}
-
-pub fn main() { rename_directory() }
diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
index 07f95d13937..01e6434b075 100644
--- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
+++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
@@ -17,26 +17,28 @@ use rustc_span::symbol::Ident;
 use rustc_span::Span;
 
 extern crate rustc_macros;
-use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
+use rustc_macros::{fluent_messages, Diagnostic, LintDiagnostic, Subdiagnostic};
 
 extern crate rustc_middle;
 use rustc_middle::ty::Ty;
 
 extern crate rustc_errors;
-use rustc_errors::{Applicability, MultiSpan};
+use rustc_errors::{Applicability, DiagnosticMessage, MultiSpan, SubdiagnosticMessage};
 
 extern crate rustc_session;
 
+fluent_messages! { "./example.ftl" }
+
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct Hello {}
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct HelloWarn {}
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 //~^ ERROR unsupported type attribute for diagnostic derive enum
 enum DiagnosticOnEnum {
     Foo,
@@ -46,13 +48,13 @@ enum DiagnosticOnEnum {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 #[diag = "E0123"]
 //~^ ERROR `#[diag = ...]` is not a valid attribute
 struct WrongStructAttrStyle {}
 
 #[derive(Diagnostic)]
-#[nonsense(compiletest_example, code = "E0123")]
+#[nonsense(no_crate_example, code = "E0123")]
 //~^ ERROR `#[nonsense(...)]` is not a valid attribute
 //~^^ ERROR diagnostic slug not specified
 //~^^^ ERROR cannot find attribute `nonsense` in this scope
@@ -66,7 +68,7 @@ struct InvalidLitNestedAttr {}
 
 #[derive(Diagnostic)]
 #[diag(nonsense, code = "E0123")]
-//~^ ERROR cannot find value `nonsense` in module `rustc_errors::fluent`
+//~^ ERROR cannot find value `nonsense` in module `crate::fluent_generated`
 struct InvalidNestedStructAttr {}
 
 #[derive(Diagnostic)]
@@ -90,12 +92,12 @@ struct InvalidNestedStructAttr2 {}
 struct InvalidNestedStructAttr3 {}
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123", slug = "foo")]
+#[diag(no_crate_example, code = "E0123", slug = "foo")]
 //~^ ERROR `#[diag(slug = ...)]` is not a valid attribute
 struct InvalidNestedStructAttr4 {}
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct WrongPlaceField {
     #[suggestion = "bar"]
     //~^ ERROR `#[suggestion = ...]` is not a valid attribute
@@ -103,20 +105,20 @@ struct WrongPlaceField {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
-#[diag(compiletest_example, code = "E0456")]
+#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0456")]
 //~^ ERROR specified multiple times
 //~^^ ERROR specified multiple times
 struct DiagSpecifiedTwice {}
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0456", code = "E0457")]
+#[diag(no_crate_example, code = "E0456", code = "E0457")]
 //~^ ERROR specified multiple times
 struct CodeSpecifiedTwice {}
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, compiletest_example, code = "E0456")]
-//~^ ERROR `#[diag(compiletest_example)]` is not a valid attribute
+#[diag(no_crate_example, no_crate::example, code = "E0456")]
+//~^ ERROR `#[diag(no_crate::example)]` is not a valid attribute
 struct SlugSpecifiedTwice {}
 
 #[derive(Diagnostic)]
@@ -128,11 +130,11 @@ struct KindNotProvided {} //~ ERROR diagnostic slug not specified
 struct SlugNotProvided {}
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example)]
+#[diag(no_crate_example)]
 struct CodeNotProvided {}
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct MessageWrongType {
     #[primary_span]
     //~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
@@ -140,7 +142,7 @@ struct MessageWrongType {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct InvalidPathFieldAttr {
     #[nonsense]
     //~^ ERROR `#[nonsense]` is not a valid attribute
@@ -149,34 +151,34 @@ struct InvalidPathFieldAttr {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct ErrorWithField {
     name: String,
-    #[label(label)]
+    #[label(no_crate_label)]
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct ErrorWithMessageAppliedToField {
-    #[label(label)]
+    #[label(no_crate_label)]
     //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
     name: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct ErrorWithNonexistentField {
-    #[suggestion(suggestion, code = "{name}")]
+    #[suggestion(no_crate_suggestion, code = "{name}")]
     //~^ ERROR `name` doesn't refer to a field on this type
     suggestion: (Span, Applicability),
 }
 
 #[derive(Diagnostic)]
 //~^ ERROR invalid format string: expected `'}'`
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct ErrorMissingClosingBrace {
-    #[suggestion(suggestion, code = "{name")]
+    #[suggestion(no_crate_suggestion, code = "{name")]
     suggestion: (Span, Applicability),
     name: String,
     val: usize,
@@ -184,50 +186,50 @@ struct ErrorMissingClosingBrace {
 
 #[derive(Diagnostic)]
 //~^ ERROR invalid format string: unmatched `}`
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct ErrorMissingOpeningBrace {
-    #[suggestion(suggestion, code = "name}")]
+    #[suggestion(no_crate_suggestion, code = "name}")]
     suggestion: (Span, Applicability),
     name: String,
     val: usize,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct LabelOnSpan {
-    #[label(label)]
+    #[label(no_crate_label)]
     sp: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct LabelOnNonSpan {
-    #[label(label)]
+    #[label(no_crate_label)]
     //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
     id: u32,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct Suggest {
-    #[suggestion(suggestion, code = "This is the suggested code")]
-    #[suggestion(suggestion, code = "This is the suggested code", style = "normal")]
-    #[suggestion(suggestion, code = "This is the suggested code", style = "short")]
-    #[suggestion(suggestion, code = "This is the suggested code", style = "hidden")]
-    #[suggestion(suggestion, code = "This is the suggested code", style = "verbose")]
+    #[suggestion(no_crate_suggestion, code = "This is the suggested code")]
+    #[suggestion(no_crate_suggestion, code = "This is the suggested code", style = "normal")]
+    #[suggestion(no_crate_suggestion, code = "This is the suggested code", style = "short")]
+    #[suggestion(no_crate_suggestion, code = "This is the suggested code", style = "hidden")]
+    #[suggestion(no_crate_suggestion, code = "This is the suggested code", style = "verbose")]
     suggestion: (Span, Applicability),
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct SuggestWithoutCode {
-    #[suggestion(suggestion)]
+    #[suggestion(no_crate_suggestion)]
     //~^ ERROR suggestion without `code = "..."`
     suggestion: (Span, Applicability),
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct SuggestWithBadKey {
     #[suggestion(nonsense = "bar")]
     //~^ ERROR `#[suggestion(nonsense = ...)]` is not a valid attribute
@@ -236,7 +238,7 @@ struct SuggestWithBadKey {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct SuggestWithShorthandMsg {
     #[suggestion(msg = "bar")]
     //~^ ERROR `#[suggestion(msg = ...)]` is not a valid attribute
@@ -245,52 +247,52 @@ struct SuggestWithShorthandMsg {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct SuggestWithoutMsg {
     #[suggestion(code = "bar")]
     suggestion: (Span, Applicability),
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct SuggestWithTypesSwapped {
-    #[suggestion(suggestion, code = "This is suggested code")]
+    #[suggestion(no_crate_suggestion, code = "This is suggested code")]
     suggestion: (Applicability, Span),
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct SuggestWithWrongTypeApplicabilityOnly {
-    #[suggestion(suggestion, code = "This is suggested code")]
+    #[suggestion(no_crate_suggestion, code = "This is suggested code")]
     //~^ ERROR wrong field type for suggestion
     suggestion: Applicability,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct SuggestWithSpanOnly {
-    #[suggestion(suggestion, code = "This is suggested code")]
+    #[suggestion(no_crate_suggestion, code = "This is suggested code")]
     suggestion: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct SuggestWithDuplicateSpanAndApplicability {
-    #[suggestion(suggestion, code = "This is suggested code")]
+    #[suggestion(no_crate_suggestion, code = "This is suggested code")]
     suggestion: (Span, Span, Applicability),
     //~^ ERROR specified multiple times
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct SuggestWithDuplicateApplicabilityAndSpan {
-    #[suggestion(suggestion, code = "This is suggested code")]
+    #[suggestion(no_crate_suggestion, code = "This is suggested code")]
     suggestion: (Applicability, Applicability, Span),
     //~^ ERROR specified multiple times
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct WrongKindOfAnnotation {
     #[label = "bar"]
     //~^ ERROR `#[label = ...]` is not a valid attribute
@@ -298,38 +300,38 @@ struct WrongKindOfAnnotation {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct OptionsInErrors {
-    #[label(label)]
+    #[label(no_crate_label)]
     label: Option<Span>,
-    #[suggestion(suggestion, code = "...")]
+    #[suggestion(no_crate_suggestion, code = "...")]
     opt_sugg: Option<(Span, Applicability)>,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0456")]
+#[diag(no_crate_example, code = "E0456")]
 struct MoveOutOfBorrowError<'tcx> {
     name: Ident,
     ty: Ty<'tcx>,
     #[primary_span]
-    #[label(label)]
+    #[label(no_crate_label)]
     span: Span,
-    #[label(label)]
+    #[label(no_crate_label)]
     other_span: Span,
-    #[suggestion(suggestion, code = "{name}.clone()")]
+    #[suggestion(no_crate_suggestion, code = "{name}.clone()")]
     opt_sugg: Option<(Span, Applicability)>,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct ErrorWithLifetime<'a> {
-    #[label(label)]
+    #[label(no_crate_label)]
     span: Span,
     name: &'a str,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct ErrorWithDefaultLabelAttr<'a> {
     #[label]
     span: Span,
@@ -338,7 +340,7 @@ struct ErrorWithDefaultLabelAttr<'a> {
 
 #[derive(Diagnostic)]
 //~^ ERROR the trait bound `Hello: IntoDiagnosticArg` is not satisfied
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct ArgFieldWithoutSkip {
     #[primary_span]
     span: Span,
@@ -346,7 +348,7 @@ struct ArgFieldWithoutSkip {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct ArgFieldWithSkip {
     #[primary_span]
     span: Span,
@@ -357,132 +359,132 @@ struct ArgFieldWithSkip {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct ErrorWithSpannedNote {
     #[note]
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct ErrorWithSpannedNoteCustom {
-    #[note(note)]
+    #[note(no_crate_note)]
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 #[note]
 struct ErrorWithNote {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
-#[note(note)]
+#[diag(no_crate_example, code = "E0123")]
+#[note(no_crate_note)]
 struct ErrorWithNoteCustom {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct ErrorWithSpannedHelp {
     #[help]
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct ErrorWithSpannedHelpCustom {
-    #[help(help)]
+    #[help(no_crate_help)]
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 #[help]
 struct ErrorWithHelp {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
-#[help(help)]
+#[diag(no_crate_example, code = "E0123")]
+#[help(no_crate_help)]
 struct ErrorWithHelpCustom {
     val: String,
 }
 
 #[derive(Diagnostic)]
 #[help]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct ErrorWithHelpWrongOrder {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[help(help)]
-#[diag(compiletest_example, code = "E0123")]
+#[help(no_crate_help)]
+#[diag(no_crate_example, code = "E0123")]
 struct ErrorWithHelpCustomWrongOrder {
     val: String,
 }
 
 #[derive(Diagnostic)]
 #[note]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct ErrorWithNoteWrongOrder {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[note(note)]
-#[diag(compiletest_example, code = "E0123")]
+#[note(no_crate_note)]
+#[diag(no_crate_example, code = "E0123")]
 struct ErrorWithNoteCustomWrongOrder {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct ApplicabilityInBoth {
-    #[suggestion(suggestion, code = "...", applicability = "maybe-incorrect")]
+    #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")]
     //~^ ERROR specified multiple times
     suggestion: (Span, Applicability),
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct InvalidApplicability {
-    #[suggestion(suggestion, code = "...", applicability = "batman")]
+    #[suggestion(no_crate_suggestion, code = "...", applicability = "batman")]
     //~^ ERROR invalid applicability
     suggestion: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct ValidApplicability {
-    #[suggestion(suggestion, code = "...", applicability = "maybe-incorrect")]
+    #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")]
     suggestion: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct NoApplicability {
-    #[suggestion(suggestion, code = "...")]
+    #[suggestion(no_crate_suggestion, code = "...")]
     suggestion: Span,
 }
 
 #[derive(Subdiagnostic)]
-#[note(parse_add_paren)]
+#[note(no_crate_example)]
 struct Note;
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example)]
+#[diag(no_crate_example)]
 struct Subdiagnostic {
     #[subdiagnostic]
     note: Note,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct VecField {
     #[primary_span]
     #[label]
@@ -490,57 +492,57 @@ struct VecField {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct UnitField {
     #[primary_span]
     spans: Span,
     #[help]
     foo: (),
-    #[help(help)]
+    #[help(no_crate_help)]
     bar: (),
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct OptUnitField {
     #[primary_span]
     spans: Span,
     #[help]
     foo: Option<()>,
-    #[help(help)]
+    #[help(no_crate_help)]
     bar: Option<()>,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct LabelWithTrailingPath {
-    #[label(label, foo)]
+    #[label(no_crate_label, foo)]
     //~^ ERROR `#[label(foo)]` is not a valid attribute
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct LabelWithTrailingNameValue {
-    #[label(label, foo = "...")]
+    #[label(no_crate_label, foo = "...")]
     //~^ ERROR `#[label(foo = ...)]` is not a valid attribute
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct LabelWithTrailingList {
-    #[label(label, foo("..."))]
+    #[label(no_crate_label, foo("..."))]
     //~^ ERROR `#[label(foo(...))]` is not a valid attribute
     span: Span,
 }
 
 #[derive(LintDiagnostic)]
-#[diag(compiletest_example)]
+#[diag(no_crate_example)]
 struct LintsGood {}
 
 #[derive(LintDiagnostic)]
-#[diag(compiletest_example)]
+#[diag(no_crate_example)]
 struct PrimarySpanOnLint {
     #[primary_span]
     //~^ ERROR `#[primary_span]` is not a valid attribute
@@ -548,42 +550,42 @@ struct PrimarySpanOnLint {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct ErrorWithMultiSpan {
     #[primary_span]
     span: MultiSpan,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 #[warning]
 struct ErrorWithWarn {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[error(compiletest_example, code = "E0123")]
+#[error(no_crate_example, code = "E0123")]
 //~^ ERROR `#[error(...)]` is not a valid attribute
 //~| ERROR diagnostic slug not specified
 //~| ERROR cannot find attribute `error` in this scope
 struct ErrorAttribute {}
 
 #[derive(Diagnostic)]
-#[warn_(compiletest_example, code = "E0123")]
+#[warn_(no_crate_example, code = "E0123")]
 //~^ ERROR `#[warn_(...)]` is not a valid attribute
 //~| ERROR diagnostic slug not specified
 //~| ERROR cannot find attribute `warn_` in this scope
 struct WarnAttribute {}
 
 #[derive(Diagnostic)]
-#[lint(compiletest_example, code = "E0123")]
+#[lint(no_crate_example, code = "E0123")]
 //~^ ERROR `#[lint(...)]` is not a valid attribute
 //~| ERROR diagnostic slug not specified
 //~| ERROR cannot find attribute `lint` in this scope
 struct LintAttributeOnSessionDiag {}
 
 #[derive(LintDiagnostic)]
-#[lint(compiletest_example, code = "E0123")]
+#[lint(no_crate_example, code = "E0123")]
 //~^ ERROR `#[lint(...)]` is not a valid attribute
 //~| ERROR `#[lint(...)]` is not a valid attribute
 //~| ERROR diagnostic slug not specified
@@ -591,55 +593,55 @@ struct LintAttributeOnSessionDiag {}
 struct LintAttributeOnLintDiag {}
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct DuplicatedSuggestionCode {
-    #[suggestion(suggestion, code = "...", code = ",,,")]
+    #[suggestion(no_crate_suggestion, code = "...", code = ",,,")]
     //~^ ERROR specified multiple times
     suggestion: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct InvalidTypeInSuggestionTuple {
-    #[suggestion(suggestion, code = "...")]
+    #[suggestion(no_crate_suggestion, code = "...")]
     suggestion: (Span, usize),
     //~^ ERROR wrong types for suggestion
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct MissingApplicabilityInSuggestionTuple {
-    #[suggestion(suggestion, code = "...")]
+    #[suggestion(no_crate_suggestion, code = "...")]
     suggestion: (Span,),
     //~^ ERROR wrong types for suggestion
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct MissingCodeInSuggestion {
-    #[suggestion(suggestion)]
+    #[suggestion(no_crate_suggestion)]
     //~^ ERROR suggestion without `code = "..."`
     suggestion: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
-#[multipart_suggestion(suggestion)]
+#[diag(no_crate_example, code = "E0123")]
+#[multipart_suggestion(no_crate_suggestion)]
 //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute
 //~| ERROR cannot find attribute `multipart_suggestion` in this scope
 #[multipart_suggestion()]
 //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute
 //~| ERROR cannot find attribute `multipart_suggestion` in this scope
 struct MultipartSuggestion {
-    #[multipart_suggestion(suggestion)]
+    #[multipart_suggestion(no_crate_suggestion)]
     //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute
     //~| ERROR cannot find attribute `multipart_suggestion` in this scope
     suggestion: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
-#[suggestion(suggestion, code = "...")]
+#[diag(no_crate_example, code = "E0123")]
+#[suggestion(no_crate_suggestion, code = "...")]
 //~^ ERROR `#[suggestion(...)]` is not a valid attribute
 struct SuggestionOnStruct {
     #[primary_span]
@@ -647,7 +649,7 @@ struct SuggestionOnStruct {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 #[label]
 //~^ ERROR `#[label]` is not a valid attribute
 struct LabelOnStruct {
@@ -657,30 +659,30 @@ struct LabelOnStruct {
 
 #[derive(Diagnostic)]
 enum ExampleEnum {
-    #[diag(compiletest_example)]
+    #[diag(no_crate_example)]
     Foo {
         #[primary_span]
         sp: Span,
         #[note]
         note_sp: Span,
     },
-    #[diag(compiletest_example)]
+    #[diag(no_crate_example)]
     Bar {
         #[primary_span]
         sp: Span,
     },
-    #[diag(compiletest_example)]
+    #[diag(no_crate_example)]
     Baz,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct RawIdentDiagnosticArg {
     pub r#type: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example)]
+#[diag(no_crate_example)]
 struct SubdiagnosticBad {
     #[subdiagnostic(bad)]
     //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute
@@ -688,7 +690,7 @@ struct SubdiagnosticBad {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example)]
+#[diag(no_crate_example)]
 struct SubdiagnosticBadStr {
     #[subdiagnostic = "bad"]
     //~^ ERROR `#[subdiagnostic = ...]` is not a valid attribute
@@ -696,7 +698,7 @@ struct SubdiagnosticBadStr {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example)]
+#[diag(no_crate_example)]
 struct SubdiagnosticBadTwice {
     #[subdiagnostic(bad, bad)]
     //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute
@@ -704,7 +706,7 @@ struct SubdiagnosticBadTwice {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example)]
+#[diag(no_crate_example)]
 struct SubdiagnosticBadLitStr {
     #[subdiagnostic("bad")]
     //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute
@@ -712,7 +714,7 @@ struct SubdiagnosticBadLitStr {
 }
 
 #[derive(LintDiagnostic)]
-#[diag(compiletest_example)]
+#[diag(no_crate_example)]
 struct SubdiagnosticEagerLint {
     #[subdiagnostic(eager)]
     //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute
@@ -720,7 +722,7 @@ struct SubdiagnosticEagerLint {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example)]
+#[diag(no_crate_example)]
 struct SubdiagnosticEagerCorrect {
     #[subdiagnostic(eager)]
     note: Note,
@@ -731,7 +733,7 @@ struct SubdiagnosticEagerCorrect {
 // after the `span_suggestion` call - which breaks eager translation.
 
 #[derive(Subdiagnostic)]
-#[suggestion(use_instead, applicability = "machine-applicable", code = "{correct}")]
+#[suggestion(no_crate_example, applicability = "machine-applicable", code = "{correct}")]
 pub(crate) struct SubdiagnosticWithSuggestion {
     #[primary_span]
     span: Span,
@@ -740,7 +742,7 @@ pub(crate) struct SubdiagnosticWithSuggestion {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example)]
+#[diag(no_crate_example)]
 struct SubdiagnosticEagerSuggestion {
     #[subdiagnostic(eager)]
     sub: SubdiagnosticWithSuggestion,
@@ -748,7 +750,7 @@ struct SubdiagnosticEagerSuggestion {
 
 /// with a doc comment on the type..
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(no_crate_example, code = "E0123")]
 struct WithDocComment {
     /// ..and the field
     #[primary_span]
@@ -756,21 +758,21 @@ struct WithDocComment {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example)]
+#[diag(no_crate_example)]
 struct SuggestionsGood {
     #[suggestion(code("foo", "bar"))]
     sub: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example)]
+#[diag(no_crate_example)]
 struct SuggestionsSingleItem {
     #[suggestion(code("foo"))]
     sub: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example)]
+#[diag(no_crate_example)]
 struct SuggestionsNoItem {
     #[suggestion(code())]
     //~^ ERROR expected at least one string literal for `code(...)`
@@ -778,7 +780,7 @@ struct SuggestionsNoItem {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example)]
+#[diag(no_crate_example)]
 struct SuggestionsInvalidItem {
     #[suggestion(code(foo))]
     //~^ ERROR `code(...)` must contain only string literals
@@ -786,7 +788,7 @@ struct SuggestionsInvalidItem {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example)]
+#[diag(no_crate_example)]
 struct SuggestionsInvalidLiteral {
     #[suggestion(code = 3)]
     //~^ ERROR `code = "..."`/`code(...)` must contain only string literals
@@ -794,16 +796,16 @@ struct SuggestionsInvalidLiteral {
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example)]
+#[diag(no_crate_example)]
 struct SuggestionStyleGood {
     #[suggestion(code = "", style = "hidden")]
     sub: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example)]
+#[diag(no_crate_example)]
 struct SuggestionOnVec {
-    #[suggestion(suggestion, code = "")]
+    #[suggestion(no_crate_suggestion, code = "")]
     //~^ ERROR `#[suggestion(...)]` is not a valid attribute
     sub: Vec<Span>,
 }
diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
index 61806c80efc..fc0cd8419e4 100644
--- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
+++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
@@ -1,11 +1,11 @@
 error: unsupported type attribute for diagnostic derive enum
-  --> $DIR/diagnostic-derive.rs:39:1
+  --> $DIR/diagnostic-derive.rs:41:1
    |
-LL | #[diag(compiletest_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[diag(no_crate_example, code = "E0123")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:42:5
+  --> $DIR/diagnostic-derive.rs:44:5
    |
 LL |     Foo,
    |     ^^^
@@ -13,7 +13,7 @@ LL |     Foo,
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:44:5
+  --> $DIR/diagnostic-derive.rs:46:5
    |
 LL |     Bar,
    |     ^^^
@@ -21,21 +21,21 @@ LL |     Bar,
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: `#[diag = ...]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:50:1
+  --> $DIR/diagnostic-derive.rs:52:1
    |
 LL | #[diag = "E0123"]
    | ^^^^^^^^^^^^^^^^^
 
 error: `#[nonsense(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:55:1
+  --> $DIR/diagnostic-derive.rs:57:1
    |
-LL | #[nonsense(compiletest_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[nonsense(no_crate_example, code = "E0123")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:55:1
+  --> $DIR/diagnostic-derive.rs:57:1
    |
-LL | / #[nonsense(compiletest_example, code = "E0123")]
+LL | / #[nonsense(no_crate_example, code = "E0123")]
 LL | |
 LL | |
 LL | |
@@ -45,7 +45,7 @@ LL | | struct InvalidStructAttr {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: `#[diag("...")]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:62:8
+  --> $DIR/diagnostic-derive.rs:64:8
    |
 LL | #[diag("E0123")]
    |        ^^^^^^^
@@ -53,7 +53,7 @@ LL | #[diag("E0123")]
    = help: a diagnostic slug is required as the first argument
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:62:1
+  --> $DIR/diagnostic-derive.rs:64:1
    |
 LL | / #[diag("E0123")]
 LL | |
@@ -64,7 +64,7 @@ LL | | struct InvalidLitNestedAttr {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: `#[diag(nonsense(...))]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:73:8
+  --> $DIR/diagnostic-derive.rs:75:8
    |
 LL | #[diag(nonsense("foo"), code = "E0123", slug = "foo")]
    |        ^^^^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL | #[diag(nonsense("foo"), code = "E0123", slug = "foo")]
    = help: a diagnostic slug is required as the first argument
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:73:1
+  --> $DIR/diagnostic-derive.rs:75:1
    |
 LL | / #[diag(nonsense("foo"), code = "E0123", slug = "foo")]
 LL | |
@@ -83,7 +83,7 @@ LL | | struct InvalidNestedStructAttr1 {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: `#[diag(nonsense = ...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:79:8
+  --> $DIR/diagnostic-derive.rs:81:8
    |
 LL | #[diag(nonsense = "...", code = "E0123", slug = "foo")]
    |        ^^^^^^^^^^^^^^^^
@@ -91,7 +91,7 @@ LL | #[diag(nonsense = "...", code = "E0123", slug = "foo")]
    = help: only `code` is a valid nested attributes following the slug
 
 error: `#[diag(slug = ...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:79:42
+  --> $DIR/diagnostic-derive.rs:81:42
    |
 LL | #[diag(nonsense = "...", code = "E0123", slug = "foo")]
    |                                          ^^^^^^^^^^^^
@@ -99,7 +99,7 @@ LL | #[diag(nonsense = "...", code = "E0123", slug = "foo")]
    = help: only `code` is a valid nested attributes following the slug
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:79:1
+  --> $DIR/diagnostic-derive.rs:81:1
    |
 LL | / #[diag(nonsense = "...", code = "E0123", slug = "foo")]
 LL | |
@@ -111,13 +111,13 @@ LL | | struct InvalidNestedStructAttr2 {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: `#[diag(nonsense = ...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:86:8
+  --> $DIR/diagnostic-derive.rs:88:8
    |
 LL | #[diag(nonsense = 4, code = "E0123", slug = "foo")]
    |        ^^^^^^^^^^^^
 
 error: `#[diag(slug = ...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:86:38
+  --> $DIR/diagnostic-derive.rs:88:38
    |
 LL | #[diag(nonsense = 4, code = "E0123", slug = "foo")]
    |                                      ^^^^^^^^^^^^
@@ -125,7 +125,7 @@ LL | #[diag(nonsense = 4, code = "E0123", slug = "foo")]
    = help: only `code` is a valid nested attributes following the slug
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:86:1
+  --> $DIR/diagnostic-derive.rs:88:1
    |
 LL | / #[diag(nonsense = 4, code = "E0123", slug = "foo")]
 LL | |
@@ -137,65 +137,65 @@ LL | | struct InvalidNestedStructAttr3 {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: `#[diag(slug = ...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:93:45
+  --> $DIR/diagnostic-derive.rs:95:42
    |
-LL | #[diag(compiletest_example, code = "E0123", slug = "foo")]
-   |                                             ^^^^^^^^^^^^
+LL | #[diag(no_crate_example, code = "E0123", slug = "foo")]
+   |                                          ^^^^^^^^^^^^
    |
    = help: only `code` is a valid nested attributes following the slug
 
 error: `#[suggestion = ...]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:100:5
+  --> $DIR/diagnostic-derive.rs:102:5
    |
 LL |     #[suggestion = "bar"]
    |     ^^^^^^^^^^^^^^^^^^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:107:8
+  --> $DIR/diagnostic-derive.rs:109:8
    |
-LL | #[diag(compiletest_example, code = "E0456")]
-   |        ^^^^^^^^^^^^^^^^^^^
+LL | #[diag(no_crate_example, code = "E0456")]
+   |        ^^^^^^^^^^^^^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:106:8
+  --> $DIR/diagnostic-derive.rs:108:8
    |
-LL | #[diag(compiletest_example, code = "E0123")]
-   |        ^^^^^^^^^^^^^^^^^^^
+LL | #[diag(no_crate_example, code = "E0123")]
+   |        ^^^^^^^^^^^^^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:107:36
+  --> $DIR/diagnostic-derive.rs:109:33
    |
-LL | #[diag(compiletest_example, code = "E0456")]
-   |                                    ^^^^^^^
+LL | #[diag(no_crate_example, code = "E0456")]
+   |                                 ^^^^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:106:36
+  --> $DIR/diagnostic-derive.rs:108:33
    |
-LL | #[diag(compiletest_example, code = "E0123")]
-   |                                    ^^^^^^^
+LL | #[diag(no_crate_example, code = "E0123")]
+   |                                 ^^^^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:113:52
+  --> $DIR/diagnostic-derive.rs:115:49
    |
-LL | #[diag(compiletest_example, code = "E0456", code = "E0457")]
-   |                                                    ^^^^^^^
+LL | #[diag(no_crate_example, code = "E0456", code = "E0457")]
+   |                                                 ^^^^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:113:36
+  --> $DIR/diagnostic-derive.rs:115:33
    |
-LL | #[diag(compiletest_example, code = "E0456", code = "E0457")]
-   |                                    ^^^^^^^
+LL | #[diag(no_crate_example, code = "E0456", code = "E0457")]
+   |                                 ^^^^^^^
 
-error: `#[diag(compiletest_example)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:118:29
+error: `#[diag(no_crate::example)]` is not a valid attribute
+  --> $DIR/diagnostic-derive.rs:120:26
    |
-LL | #[diag(compiletest_example, compiletest_example, code = "E0456")]
-   |                             ^^^^^^^^^^^^^^^^^^^
+LL | #[diag(no_crate_example, no_crate::example, code = "E0456")]
+   |                          ^^^^^^^^^^^^^^^^^
    |
    = help: diagnostic slug must be the first argument
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:123:1
+  --> $DIR/diagnostic-derive.rs:125:1
    |
 LL | struct KindNotProvided {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -203,7 +203,7 @@ LL | struct KindNotProvided {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:126:1
+  --> $DIR/diagnostic-derive.rs:128:1
    |
 LL | / #[diag(code = "E0456")]
 LL | |
@@ -213,31 +213,31 @@ LL | | struct SlugNotProvided {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
-  --> $DIR/diagnostic-derive.rs:137:5
+  --> $DIR/diagnostic-derive.rs:139:5
    |
 LL |     #[primary_span]
    |     ^^^^^^^^^^^^^^^
 
 error: `#[nonsense]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:145:5
+  --> $DIR/diagnostic-derive.rs:147:5
    |
 LL |     #[nonsense]
    |     ^^^^^^^^^^^
 
 error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
-  --> $DIR/diagnostic-derive.rs:162:5
+  --> $DIR/diagnostic-derive.rs:164:5
    |
-LL |     #[label(label)]
-   |     ^^^^^^^^^^^^^^^
+LL |     #[label(no_crate_label)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `name` doesn't refer to a field on this type
-  --> $DIR/diagnostic-derive.rs:170:37
+  --> $DIR/diagnostic-derive.rs:172:46
    |
-LL |     #[suggestion(suggestion, code = "{name}")]
-   |                                     ^^^^^^^^
+LL |     #[suggestion(no_crate_suggestion, code = "{name}")]
+   |                                              ^^^^^^^^
 
 error: invalid format string: expected `'}'` but string was terminated
-  --> $DIR/diagnostic-derive.rs:175:10
+  --> $DIR/diagnostic-derive.rs:177:10
    |
 LL | #[derive(Diagnostic)]
    |          ^^^^^^^^^^ expected `'}'` in format string
@@ -246,7 +246,7 @@ LL | #[derive(Diagnostic)]
    = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: invalid format string: unmatched `}` found
-  --> $DIR/diagnostic-derive.rs:185:10
+  --> $DIR/diagnostic-derive.rs:187:10
    |
 LL | #[derive(Diagnostic)]
    |          ^^^^^^^^^^ unmatched `}` in format string
@@ -255,19 +255,19 @@ LL | #[derive(Diagnostic)]
    = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
-  --> $DIR/diagnostic-derive.rs:205:5
+  --> $DIR/diagnostic-derive.rs:207:5
    |
-LL |     #[label(label)]
-   |     ^^^^^^^^^^^^^^^
+LL |     #[label(no_crate_label)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: suggestion without `code = "..."`
-  --> $DIR/diagnostic-derive.rs:224:5
+  --> $DIR/diagnostic-derive.rs:226:5
    |
-LL |     #[suggestion(suggestion)]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     #[suggestion(no_crate_suggestion)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[suggestion(nonsense = ...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:232:18
+  --> $DIR/diagnostic-derive.rs:234:18
    |
 LL |     #[suggestion(nonsense = "bar")]
    |                  ^^^^^^^^^^^^^^^^
@@ -275,13 +275,13 @@ LL |     #[suggestion(nonsense = "bar")]
    = help: only `style`, `code` and `applicability` are valid nested attributes
 
 error: suggestion without `code = "..."`
-  --> $DIR/diagnostic-derive.rs:232:5
+  --> $DIR/diagnostic-derive.rs:234:5
    |
 LL |     #[suggestion(nonsense = "bar")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[suggestion(msg = ...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:241:18
+  --> $DIR/diagnostic-derive.rs:243:18
    |
 LL |     #[suggestion(msg = "bar")]
    |                  ^^^^^^^^^^^
@@ -289,15 +289,15 @@ LL |     #[suggestion(msg = "bar")]
    = help: only `style`, `code` and `applicability` are valid nested attributes
 
 error: suggestion without `code = "..."`
-  --> $DIR/diagnostic-derive.rs:241:5
+  --> $DIR/diagnostic-derive.rs:243:5
    |
 LL |     #[suggestion(msg = "bar")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: wrong field type for suggestion
-  --> $DIR/diagnostic-derive.rs:264:5
+  --> $DIR/diagnostic-derive.rs:266:5
    |
-LL | /     #[suggestion(suggestion, code = "This is suggested code")]
+LL | /     #[suggestion(no_crate_suggestion, code = "This is suggested code")]
 LL | |
 LL | |     suggestion: Applicability,
    | |_____________________________^
@@ -305,75 +305,75 @@ LL | |     suggestion: Applicability,
    = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)`
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:280:24
+  --> $DIR/diagnostic-derive.rs:282:24
    |
 LL |     suggestion: (Span, Span, Applicability),
    |                        ^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:280:18
+  --> $DIR/diagnostic-derive.rs:282:18
    |
 LL |     suggestion: (Span, Span, Applicability),
    |                  ^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:288:33
+  --> $DIR/diagnostic-derive.rs:290:33
    |
 LL |     suggestion: (Applicability, Applicability, Span),
    |                                 ^^^^^^^^^^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:288:18
+  --> $DIR/diagnostic-derive.rs:290:18
    |
 LL |     suggestion: (Applicability, Applicability, Span),
    |                  ^^^^^^^^^^^^^
 
 error: `#[label = ...]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:295:5
+  --> $DIR/diagnostic-derive.rs:297:5
    |
 LL |     #[label = "bar"]
    |     ^^^^^^^^^^^^^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:446:44
+  --> $DIR/diagnostic-derive.rs:448:53
    |
-LL |     #[suggestion(suggestion, code = "...", applicability = "maybe-incorrect")]
-   |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")]
+   |                                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:448:24
+  --> $DIR/diagnostic-derive.rs:450:24
    |
 LL |     suggestion: (Span, Applicability),
    |                        ^^^^^^^^^^^^^
 
 error: invalid applicability
-  --> $DIR/diagnostic-derive.rs:454:44
+  --> $DIR/diagnostic-derive.rs:456:53
    |
-LL |     #[suggestion(suggestion, code = "...", applicability = "batman")]
-   |                                            ^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     #[suggestion(no_crate_suggestion, code = "...", applicability = "batman")]
+   |                                                     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[label(foo)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:517:20
+  --> $DIR/diagnostic-derive.rs:519:29
    |
-LL |     #[label(label, foo)]
-   |                    ^^^
+LL |     #[label(no_crate_label, foo)]
+   |                             ^^^
    |
    = help: a diagnostic slug must be the first argument to the attribute
 
 error: `#[label(foo = ...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:525:20
+  --> $DIR/diagnostic-derive.rs:527:29
    |
-LL |     #[label(label, foo = "...")]
-   |                    ^^^^^^^^^^^
+LL |     #[label(no_crate_label, foo = "...")]
+   |                             ^^^^^^^^^^^
 
 error: `#[label(foo(...))]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:533:20
+  --> $DIR/diagnostic-derive.rs:535:29
    |
-LL |     #[label(label, foo("..."))]
-   |                    ^^^^^^^^^^
+LL |     #[label(no_crate_label, foo("..."))]
+   |                             ^^^^^^^^^^
 
 error: `#[primary_span]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:545:5
+  --> $DIR/diagnostic-derive.rs:547:5
    |
 LL |     #[primary_span]
    |     ^^^^^^^^^^^^^^^
@@ -381,15 +381,15 @@ LL |     #[primary_span]
    = help: the `primary_span` field attribute is not valid for lint diagnostics
 
 error: `#[error(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:565:1
+  --> $DIR/diagnostic-derive.rs:567:1
    |
-LL | #[error(compiletest_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[error(no_crate_example, code = "E0123")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:565:1
+  --> $DIR/diagnostic-derive.rs:567:1
    |
-LL | / #[error(compiletest_example, code = "E0123")]
+LL | / #[error(no_crate_example, code = "E0123")]
 LL | |
 LL | |
 LL | |
@@ -399,15 +399,15 @@ LL | | struct ErrorAttribute {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: `#[warn_(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:572:1
+  --> $DIR/diagnostic-derive.rs:574:1
    |
-LL | #[warn_(compiletest_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[warn_(no_crate_example, code = "E0123")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:572:1
+  --> $DIR/diagnostic-derive.rs:574:1
    |
-LL | / #[warn_(compiletest_example, code = "E0123")]
+LL | / #[warn_(no_crate_example, code = "E0123")]
 LL | |
 LL | |
 LL | |
@@ -417,15 +417,15 @@ LL | | struct WarnAttribute {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: `#[lint(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:579:1
+  --> $DIR/diagnostic-derive.rs:581:1
    |
-LL | #[lint(compiletest_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[lint(no_crate_example, code = "E0123")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:579:1
+  --> $DIR/diagnostic-derive.rs:581:1
    |
-LL | / #[lint(compiletest_example, code = "E0123")]
+LL | / #[lint(no_crate_example, code = "E0123")]
 LL | |
 LL | |
 LL | |
@@ -435,21 +435,21 @@ LL | | struct LintAttributeOnSessionDiag {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: `#[lint(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:586:1
+  --> $DIR/diagnostic-derive.rs:588:1
    |
-LL | #[lint(compiletest_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[lint(no_crate_example, code = "E0123")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[lint(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:586:1
+  --> $DIR/diagnostic-derive.rs:588:1
    |
-LL | #[lint(compiletest_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[lint(no_crate_example, code = "E0123")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:586:1
+  --> $DIR/diagnostic-derive.rs:588:1
    |
-LL | / #[lint(compiletest_example, code = "E0123")]
+LL | / #[lint(no_crate_example, code = "E0123")]
 LL | |
 LL | |
 LL | |
@@ -460,19 +460,19 @@ LL | | struct LintAttributeOnLintDiag {}
    = help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest_example)]`
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:596:44
+  --> $DIR/diagnostic-derive.rs:598:53
    |
-LL |     #[suggestion(suggestion, code = "...", code = ",,,")]
-   |                                            ^^^^^^^^^^^^
+LL |     #[suggestion(no_crate_suggestion, code = "...", code = ",,,")]
+   |                                                     ^^^^^^^^^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:596:30
+  --> $DIR/diagnostic-derive.rs:598:39
    |
-LL |     #[suggestion(suggestion, code = "...", code = ",,,")]
-   |                              ^^^^^^^^^^^^
+LL |     #[suggestion(no_crate_suggestion, code = "...", code = ",,,")]
+   |                                       ^^^^^^^^^^^^
 
 error: wrong types for suggestion
-  --> $DIR/diagnostic-derive.rs:605:24
+  --> $DIR/diagnostic-derive.rs:607:24
    |
 LL |     suggestion: (Span, usize),
    |                        ^^^^^
@@ -480,7 +480,7 @@ LL |     suggestion: (Span, usize),
    = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)`
 
 error: wrong types for suggestion
-  --> $DIR/diagnostic-derive.rs:613:17
+  --> $DIR/diagnostic-derive.rs:615:17
    |
 LL |     suggestion: (Span,),
    |                 ^^^^^^^
@@ -488,21 +488,21 @@ LL |     suggestion: (Span,),
    = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)`
 
 error: suggestion without `code = "..."`
-  --> $DIR/diagnostic-derive.rs:620:5
+  --> $DIR/diagnostic-derive.rs:622:5
    |
-LL |     #[suggestion(suggestion)]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     #[suggestion(no_crate_suggestion)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[multipart_suggestion(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:627:1
+  --> $DIR/diagnostic-derive.rs:629:1
    |
-LL | #[multipart_suggestion(suggestion)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[multipart_suggestion(no_crate_suggestion)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider creating a `Subdiagnostic` instead
 
 error: `#[multipart_suggestion(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:630:1
+  --> $DIR/diagnostic-derive.rs:632:1
    |
 LL | #[multipart_suggestion()]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -510,23 +510,23 @@ LL | #[multipart_suggestion()]
    = help: consider creating a `Subdiagnostic` instead
 
 error: `#[multipart_suggestion(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:634:5
+  --> $DIR/diagnostic-derive.rs:636:5
    |
-LL |     #[multipart_suggestion(suggestion)]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     #[multipart_suggestion(no_crate_suggestion)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider creating a `Subdiagnostic` instead
 
 error: `#[suggestion(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:642:1
+  --> $DIR/diagnostic-derive.rs:644:1
    |
-LL | #[suggestion(suggestion, code = "...")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[suggestion(no_crate_suggestion, code = "...")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: `#[label]` and `#[suggestion]` can only be applied to fields
 
 error: `#[label]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:651:1
+  --> $DIR/diagnostic-derive.rs:653:1
    |
 LL | #[label]
    | ^^^^^^^^
@@ -534,7 +534,7 @@ LL | #[label]
    = help: `#[label]` and `#[suggestion]` can only be applied to fields
 
 error: `#[subdiagnostic(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:685:5
+  --> $DIR/diagnostic-derive.rs:687:5
    |
 LL |     #[subdiagnostic(bad)]
    |     ^^^^^^^^^^^^^^^^^^^^^
@@ -542,13 +542,13 @@ LL |     #[subdiagnostic(bad)]
    = help: `eager` is the only supported nested attribute for `subdiagnostic`
 
 error: `#[subdiagnostic = ...]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:693:5
+  --> $DIR/diagnostic-derive.rs:695:5
    |
 LL |     #[subdiagnostic = "bad"]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[subdiagnostic(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:701:5
+  --> $DIR/diagnostic-derive.rs:703:5
    |
 LL |     #[subdiagnostic(bad, bad)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -556,7 +556,7 @@ LL |     #[subdiagnostic(bad, bad)]
    = help: `eager` is the only supported nested attribute for `subdiagnostic`
 
 error: `#[subdiagnostic(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:709:5
+  --> $DIR/diagnostic-derive.rs:711:5
    |
 LL |     #[subdiagnostic("bad")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -564,7 +564,7 @@ LL |     #[subdiagnostic("bad")]
    = help: `eager` is the only supported nested attribute for `subdiagnostic`
 
 error: `#[subdiagnostic(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:717:5
+  --> $DIR/diagnostic-derive.rs:719:5
    |
 LL |     #[subdiagnostic(eager)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -572,95 +572,95 @@ LL |     #[subdiagnostic(eager)]
    = help: eager subdiagnostics are not supported on lints
 
 error: expected at least one string literal for `code(...)`
-  --> $DIR/diagnostic-derive.rs:775:18
+  --> $DIR/diagnostic-derive.rs:777:18
    |
 LL |     #[suggestion(code())]
    |                  ^^^^^^
 
 error: `code(...)` must contain only string literals
-  --> $DIR/diagnostic-derive.rs:783:23
+  --> $DIR/diagnostic-derive.rs:785:23
    |
 LL |     #[suggestion(code(foo))]
    |                       ^^^
 
 error: `code = "..."`/`code(...)` must contain only string literals
-  --> $DIR/diagnostic-derive.rs:791:18
+  --> $DIR/diagnostic-derive.rs:793:18
    |
 LL |     #[suggestion(code = 3)]
    |                  ^^^^^^^^
 
 error: `#[suggestion(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:806:5
+  --> $DIR/diagnostic-derive.rs:808:5
    |
-LL |     #[suggestion(suggestion, code = "")]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     #[suggestion(no_crate_suggestion, code = "")]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `#[suggestion(...)]` applied to `Vec` field is ambiguous
    = help: to show a suggestion consisting of multiple parts, use a `Subdiagnostic` annotated with `#[multipart_suggestion(...)]`
    = help: to show a variable set of suggestions, use a `Vec` of `Subdiagnostic`s annotated with `#[suggestion(...)]`
 
 error: cannot find attribute `nonsense` in this scope
-  --> $DIR/diagnostic-derive.rs:55:3
+  --> $DIR/diagnostic-derive.rs:57:3
    |
-LL | #[nonsense(compiletest_example, code = "E0123")]
+LL | #[nonsense(no_crate_example, code = "E0123")]
    |   ^^^^^^^^
 
 error: cannot find attribute `nonsense` in this scope
-  --> $DIR/diagnostic-derive.rs:145:7
+  --> $DIR/diagnostic-derive.rs:147:7
    |
 LL |     #[nonsense]
    |       ^^^^^^^^
 
 error: cannot find attribute `error` in this scope
-  --> $DIR/diagnostic-derive.rs:565:3
+  --> $DIR/diagnostic-derive.rs:567:3
    |
-LL | #[error(compiletest_example, code = "E0123")]
+LL | #[error(no_crate_example, code = "E0123")]
    |   ^^^^^
 
 error: cannot find attribute `warn_` in this scope
-  --> $DIR/diagnostic-derive.rs:572:3
+  --> $DIR/diagnostic-derive.rs:574:3
    |
-LL | #[warn_(compiletest_example, code = "E0123")]
+LL | #[warn_(no_crate_example, code = "E0123")]
    |   ^^^^^ help: a built-in attribute with a similar name exists: `warn`
 
 error: cannot find attribute `lint` in this scope
-  --> $DIR/diagnostic-derive.rs:579:3
+  --> $DIR/diagnostic-derive.rs:581:3
    |
-LL | #[lint(compiletest_example, code = "E0123")]
+LL | #[lint(no_crate_example, code = "E0123")]
    |   ^^^^ help: a built-in attribute with a similar name exists: `link`
 
 error: cannot find attribute `lint` in this scope
-  --> $DIR/diagnostic-derive.rs:586:3
+  --> $DIR/diagnostic-derive.rs:588:3
    |
-LL | #[lint(compiletest_example, code = "E0123")]
+LL | #[lint(no_crate_example, code = "E0123")]
    |   ^^^^ help: a built-in attribute with a similar name exists: `link`
 
 error: cannot find attribute `multipart_suggestion` in this scope
-  --> $DIR/diagnostic-derive.rs:627:3
+  --> $DIR/diagnostic-derive.rs:629:3
    |
-LL | #[multipart_suggestion(suggestion)]
+LL | #[multipart_suggestion(no_crate_suggestion)]
    |   ^^^^^^^^^^^^^^^^^^^^
 
 error: cannot find attribute `multipart_suggestion` in this scope
-  --> $DIR/diagnostic-derive.rs:630:3
+  --> $DIR/diagnostic-derive.rs:632:3
    |
 LL | #[multipart_suggestion()]
    |   ^^^^^^^^^^^^^^^^^^^^
 
 error: cannot find attribute `multipart_suggestion` in this scope
-  --> $DIR/diagnostic-derive.rs:634:7
+  --> $DIR/diagnostic-derive.rs:636:7
    |
-LL |     #[multipart_suggestion(suggestion)]
+LL |     #[multipart_suggestion(no_crate_suggestion)]
    |       ^^^^^^^^^^^^^^^^^^^^
 
-error[E0425]: cannot find value `nonsense` in module `rustc_errors::fluent`
-  --> $DIR/diagnostic-derive.rs:68:8
+error[E0425]: cannot find value `nonsense` in module `crate::fluent_generated`
+  --> $DIR/diagnostic-derive.rs:70:8
    |
 LL | #[diag(nonsense, code = "E0123")]
-   |        ^^^^^^^^ not found in `rustc_errors::fluent`
+   |        ^^^^^^^^ not found in `crate::fluent_generated`
 
 error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied
-  --> $DIR/diagnostic-derive.rs:339:10
+  --> $DIR/diagnostic-derive.rs:341:10
    |
 LL | #[derive(Diagnostic)]
    |          ^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello`
diff --git a/tests/ui-fulldeps/session-diagnostic/example.ftl b/tests/ui-fulldeps/session-diagnostic/example.ftl
new file mode 100644
index 00000000000..cb2d476d815
--- /dev/null
+++ b/tests/ui-fulldeps/session-diagnostic/example.ftl
@@ -0,0 +1,5 @@
+no_crate_example = this is an example message used in testing
+    .note = with a note
+    .help = with a help
+    .suggestion = with a suggestion
+    .label = with a label
diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs
index 09ad6964909..c882f7792d5 100644
--- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs
+++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs
@@ -15,12 +15,14 @@ extern crate rustc_macros;
 extern crate rustc_session;
 extern crate rustc_span;
 
-use rustc_errors::Applicability;
-use rustc_macros::Subdiagnostic;
+use rustc_errors::{Applicability, DiagnosticMessage, SubdiagnosticMessage};
+use rustc_macros::{fluent_messages, Subdiagnostic};
 use rustc_span::Span;
 
+fluent_messages! { "./example.ftl" }
+
 #[derive(Subdiagnostic)]
-#[label(parse_add_paren)]
+#[label(no_crate_example)]
 struct A {
     #[primary_span]
     span: Span,
@@ -29,13 +31,13 @@ struct A {
 
 #[derive(Subdiagnostic)]
 enum B {
-    #[label(parse_add_paren)]
+    #[label(no_crate_example)]
     A {
         #[primary_span]
         span: Span,
         var: String,
     },
-    #[label(parse_add_paren)]
+    #[label(no_crate_example)]
     B {
         #[primary_span]
         span: Span,
@@ -44,7 +46,7 @@ enum B {
 }
 
 #[derive(Subdiagnostic)]
-#[label(parse_add_paren)]
+#[label(no_crate_example)]
 //~^ ERROR label without `#[primary_span]` field
 struct C {
     var: String,
@@ -120,8 +122,8 @@ struct K {
 
 #[derive(Subdiagnostic)]
 #[label(slug)]
-//~^ ERROR cannot find value `slug` in module `rustc_errors::fluent`
-//~^^ NOTE not found in `rustc_errors::fluent`
+//~^ ERROR cannot find value `slug` in module `crate::fluent_generated`
+//~^^ NOTE not found in `crate::fluent_generated`
 struct L {
     #[primary_span]
     span: Span,
@@ -138,7 +140,7 @@ struct M {
 }
 
 #[derive(Subdiagnostic)]
-#[label(parse_add_paren, code = "...")]
+#[label(no_crate_example, code = "...")]
 //~^ ERROR `#[label(code = ...)]` is not a valid attribute
 struct N {
     #[primary_span]
@@ -147,7 +149,7 @@ struct N {
 }
 
 #[derive(Subdiagnostic)]
-#[label(parse_add_paren, applicability = "machine-applicable")]
+#[label(no_crate_example, applicability = "machine-applicable")]
 //~^ ERROR `#[label(applicability = ...)]` is not a valid attribute
 struct O {
     #[primary_span]
@@ -160,7 +162,7 @@ struct O {
 //~^ ERROR cannot find attribute `foo` in this scope
 //~^^ ERROR unsupported type attribute for subdiagnostic enum
 enum P {
-    #[label(parse_add_paren)]
+    #[label(no_crate_example)]
     A {
         #[primary_span]
         span: Span,
@@ -230,7 +232,7 @@ enum U {
 
 #[derive(Subdiagnostic)]
 enum V {
-    #[label(parse_add_paren)]
+    #[label(no_crate_example)]
     A {
         #[primary_span]
         span: Span,
@@ -244,7 +246,7 @@ enum V {
 }
 
 #[derive(Subdiagnostic)]
-#[label(parse_add_paren)]
+#[label(no_crate_example)]
 //~^ ERROR label without `#[primary_span]` field
 struct W {
     #[primary_span]
@@ -253,7 +255,7 @@ struct W {
 }
 
 #[derive(Subdiagnostic)]
-#[label(parse_add_paren)]
+#[label(no_crate_example)]
 struct X {
     #[primary_span]
     span: Span,
@@ -263,7 +265,7 @@ struct X {
 }
 
 #[derive(Subdiagnostic)]
-#[label(parse_add_paren)]
+#[label(no_crate_example)]
 struct Y {
     #[primary_span]
     span: Span,
@@ -274,7 +276,7 @@ struct Y {
 }
 
 #[derive(Subdiagnostic)]
-#[label(parse_add_paren)]
+#[label(no_crate_example)]
 struct Z {
     #[primary_span]
     span: Span,
@@ -285,7 +287,7 @@ struct Z {
 }
 
 #[derive(Subdiagnostic)]
-#[label(parse_add_paren)]
+#[label(no_crate_example)]
 struct AA {
     #[primary_span]
     span: Span,
@@ -296,7 +298,7 @@ struct AA {
 }
 
 #[derive(Subdiagnostic)]
-#[label(parse_add_paren)]
+#[label(no_crate_example)]
 struct AB {
     #[primary_span]
     span: Span,
@@ -312,23 +314,23 @@ union AC {
 }
 
 #[derive(Subdiagnostic)]
-#[label(parse_add_paren)]
-#[label(parse_add_paren)]
+#[label(no_crate_example)]
+#[label(no_crate_example)]
 struct AD {
     #[primary_span]
     span: Span,
 }
 
 #[derive(Subdiagnostic)]
-#[label(parse_add_paren, parse_add_paren)]
-//~^ ERROR `#[label(parse_add_paren)]` is not a valid attribute
+#[label(no_crate_example, no_crate::example)]
+//~^ ERROR `#[label(no_crate::example)]` is not a valid attribute
 struct AE {
     #[primary_span]
     span: Span,
 }
 
 #[derive(Subdiagnostic)]
-#[label(parse_add_paren)]
+#[label(no_crate_example)]
 struct AF {
     #[primary_span]
     //~^ NOTE previously specified here
@@ -346,7 +348,7 @@ struct AG {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "...")]
+#[suggestion(no_crate_example, code = "...")]
 struct AH {
     #[primary_span]
     span: Span,
@@ -357,7 +359,7 @@ struct AH {
 
 #[derive(Subdiagnostic)]
 enum AI {
-    #[suggestion(parse_add_paren, code = "...")]
+    #[suggestion(no_crate_example, code = "...")]
     A {
         #[primary_span]
         span: Span,
@@ -365,7 +367,7 @@ enum AI {
         applicability: Applicability,
         var: String,
     },
-    #[suggestion(parse_add_paren, code = "...")]
+    #[suggestion(no_crate_example, code = "...")]
     B {
         #[primary_span]
         span: Span,
@@ -376,7 +378,7 @@ enum AI {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "...", code = "...")]
+#[suggestion(no_crate_example, code = "...", code = "...")]
 //~^ ERROR specified multiple times
 //~^^ NOTE previously specified here
 struct AJ {
@@ -387,7 +389,7 @@ struct AJ {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "...")]
+#[suggestion(no_crate_example, code = "...")]
 struct AK {
     #[primary_span]
     span: Span,
@@ -400,7 +402,7 @@ struct AK {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "...")]
+#[suggestion(no_crate_example, code = "...")]
 struct AL {
     #[primary_span]
     span: Span,
@@ -410,14 +412,14 @@ struct AL {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "...")]
+#[suggestion(no_crate_example, code = "...")]
 struct AM {
     #[primary_span]
     span: Span,
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren)]
+#[suggestion(no_crate_example)]
 //~^ ERROR suggestion without `code = "..."`
 struct AN {
     #[primary_span]
@@ -427,7 +429,7 @@ struct AN {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "...", applicability = "foo")]
+#[suggestion(no_crate_example, code = "...", applicability = "foo")]
 //~^ ERROR invalid applicability
 struct AO {
     #[primary_span]
@@ -435,24 +437,24 @@ struct AO {
 }
 
 #[derive(Subdiagnostic)]
-#[help(parse_add_paren)]
+#[help(no_crate_example)]
 struct AP {
     var: String,
 }
 
 #[derive(Subdiagnostic)]
-#[note(parse_add_paren)]
+#[note(no_crate_example)]
 struct AQ;
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "...")]
+#[suggestion(no_crate_example, code = "...")]
 //~^ ERROR suggestion without `#[primary_span]` field
 struct AR {
     var: String,
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "...", applicability = "machine-applicable")]
+#[suggestion(no_crate_example, code = "...", applicability = "machine-applicable")]
 struct AS {
     #[primary_span]
     span: Span,
@@ -462,7 +464,7 @@ struct AS {
 #[label]
 //~^ ERROR unsupported type attribute for subdiagnostic enum
 enum AT {
-    #[label(parse_add_paren)]
+    #[label(no_crate_example)]
     A {
         #[primary_span]
         span: Span,
@@ -471,7 +473,7 @@ enum AT {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")]
+#[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")]
 struct AU {
     #[primary_span]
     span: Span,
@@ -479,7 +481,7 @@ struct AU {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")]
+#[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")]
 //~^ ERROR `var` doesn't refer to a field on this type
 struct AV {
     #[primary_span]
@@ -488,7 +490,7 @@ struct AV {
 
 #[derive(Subdiagnostic)]
 enum AW {
-    #[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")]
+    #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")]
     A {
         #[primary_span]
         span: Span,
@@ -498,7 +500,7 @@ enum AW {
 
 #[derive(Subdiagnostic)]
 enum AX {
-    #[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")]
+    #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")]
     //~^ ERROR `var` doesn't refer to a field on this type
     A {
         #[primary_span]
@@ -507,18 +509,18 @@ enum AX {
 }
 
 #[derive(Subdiagnostic)]
-#[warning(parse_add_paren)]
+#[warning(no_crate_example)]
 struct AY {}
 
 #[derive(Subdiagnostic)]
-#[warning(parse_add_paren)]
+#[warning(no_crate_example)]
 struct AZ {
     #[primary_span]
     span: Span,
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "...")]
+#[suggestion(no_crate_example, code = "...")]
 //~^ ERROR suggestion without `#[primary_span]` field
 struct BA {
     #[suggestion_part]
@@ -533,7 +535,7 @@ struct BA {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(parse_add_paren, code = "...", applicability = "machine-applicable")]
+#[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")]
 //~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields
 //~| ERROR `#[multipart_suggestion(code = ...)]` is not a valid attribute
 struct BBa {
@@ -541,7 +543,7 @@ struct BBa {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")]
+#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")]
 struct BBb {
     #[suggestion_part]
     //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
@@ -549,7 +551,7 @@ struct BBb {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")]
+#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")]
 struct BBc {
     #[suggestion_part()]
     //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
@@ -557,7 +559,7 @@ struct BBc {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(parse_add_paren)]
+#[multipart_suggestion(no_crate_example)]
 //~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields
 struct BC {
     #[primary_span]
@@ -566,7 +568,7 @@ struct BC {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(parse_add_paren)]
+#[multipart_suggestion(no_crate_example)]
 struct BD {
     #[suggestion_part]
     //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
@@ -586,7 +588,7 @@ struct BD {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")]
+#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")]
 struct BE {
     #[suggestion_part(code = "...", code = ",,,")]
     //~^ ERROR specified multiple times
@@ -595,7 +597,7 @@ struct BE {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")]
+#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")]
 struct BF {
     #[suggestion_part(code = "(")]
     first: Span,
@@ -604,7 +606,7 @@ struct BF {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(parse_add_paren)]
+#[multipart_suggestion(no_crate_example)]
 struct BG {
     #[applicability]
     appl: Applicability,
@@ -615,7 +617,7 @@ struct BG {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")]
+#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")]
 struct BH {
     #[applicability]
     //~^ ERROR `#[applicability]` has no effect
@@ -627,14 +629,14 @@ struct BH {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")]
+#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")]
 struct BI {
     #[suggestion_part(code = "")]
     spans: Vec<Span>,
 }
 
 #[derive(Subdiagnostic)]
-#[label(parse_add_paren)]
+#[label(no_crate_example)]
 struct BJ {
     #[primary_span]
     span: Span,
@@ -643,7 +645,7 @@ struct BJ {
 
 /// with a doc comment on the type..
 #[derive(Subdiagnostic)]
-#[label(parse_add_paren)]
+#[label(no_crate_example)]
 struct BK {
     /// ..and the field
     #[primary_span]
@@ -654,7 +656,7 @@ struct BK {
 #[derive(Subdiagnostic)]
 enum BL {
     /// ..and the variant..
-    #[label(parse_add_paren)]
+    #[label(no_crate_example)]
     Foo {
         /// ..and the field
         #[primary_span]
@@ -663,7 +665,7 @@ enum BL {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(parse_add_paren)]
+#[multipart_suggestion(no_crate_example)]
 struct BM {
     #[suggestion_part(code("foo"))]
     //~^ ERROR expected exactly one string literal for `code = ...`
@@ -672,7 +674,7 @@ struct BM {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(parse_add_paren)]
+#[multipart_suggestion(no_crate_example)]
 struct BN {
     #[suggestion_part(code("foo", "bar"))]
     //~^ ERROR expected exactly one string literal for `code = ...`
@@ -681,7 +683,7 @@ struct BN {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(parse_add_paren)]
+#[multipart_suggestion(no_crate_example)]
 struct BO {
     #[suggestion_part(code(3))]
     //~^ ERROR expected exactly one string literal for `code = ...`
@@ -690,7 +692,7 @@ struct BO {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(parse_add_paren)]
+#[multipart_suggestion(no_crate_example)]
 struct BP {
     #[suggestion_part(code())]
     //~^ ERROR expected exactly one string literal for `code = ...`
@@ -699,7 +701,7 @@ struct BP {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(parse_add_paren)]
+#[multipart_suggestion(no_crate_example)]
 struct BQ {
     #[suggestion_part(code = 3)]
     //~^ ERROR `code = "..."`/`code(...)` must contain only string literals
@@ -708,42 +710,42 @@ struct BQ {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "")]
+#[suggestion(no_crate_example, code = "")]
 struct SuggestionStyleDefault {
     #[primary_span]
     sub: Span,
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "", style = "short")]
+#[suggestion(no_crate_example, code = "", style = "short")]
 struct SuggestionStyleShort {
     #[primary_span]
     sub: Span,
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "", style = "hidden")]
+#[suggestion(no_crate_example, code = "", style = "hidden")]
 struct SuggestionStyleHidden {
     #[primary_span]
     sub: Span,
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "", style = "verbose")]
+#[suggestion(no_crate_example, code = "", style = "verbose")]
 struct SuggestionStyleVerbose {
     #[primary_span]
     sub: Span,
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "", style = "tool-only")]
+#[suggestion(no_crate_example, code = "", style = "tool-only")]
 struct SuggestionStyleToolOnly {
     #[primary_span]
     sub: Span,
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "", style = "hidden", style = "normal")]
+#[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")]
 //~^ ERROR specified multiple times
 //~| NOTE previously specified here
 struct SuggestionStyleTwice {
@@ -752,7 +754,7 @@ struct SuggestionStyleTwice {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion_hidden(parse_add_paren, code = "")]
+#[suggestion_hidden(no_crate_example, code = "")]
 //~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute
 struct SuggestionStyleOldSyntax {
     #[primary_span]
@@ -760,7 +762,7 @@ struct SuggestionStyleOldSyntax {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion_hidden(parse_add_paren, code = "", style = "normal")]
+#[suggestion_hidden(no_crate_example, code = "", style = "normal")]
 //~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute
 struct SuggestionStyleOldAndNewSyntax {
     #[primary_span]
@@ -768,7 +770,7 @@ struct SuggestionStyleOldAndNewSyntax {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "", style = "foo")]
+#[suggestion(no_crate_example, code = "", style = "foo")]
 //~^ ERROR invalid suggestion style
 struct SuggestionStyleInvalid1 {
     #[primary_span]
@@ -776,7 +778,7 @@ struct SuggestionStyleInvalid1 {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "", style = 42)]
+#[suggestion(no_crate_example, code = "", style = 42)]
 //~^ ERROR `#[suggestion(style = ...)]` is not a valid attribute
 struct SuggestionStyleInvalid2 {
     #[primary_span]
@@ -784,7 +786,7 @@ struct SuggestionStyleInvalid2 {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "", style)]
+#[suggestion(no_crate_example, code = "", style)]
 //~^ ERROR `#[suggestion(style)]` is not a valid attribute
 struct SuggestionStyleInvalid3 {
     #[primary_span]
@@ -792,7 +794,7 @@ struct SuggestionStyleInvalid3 {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "", style("foo"))]
+#[suggestion(no_crate_example, code = "", style("foo"))]
 //~^ ERROR `#[suggestion(style(...))]` is not a valid attribute
 struct SuggestionStyleInvalid4 {
     #[primary_span]
@@ -800,7 +802,7 @@ struct SuggestionStyleInvalid4 {
 }
 
 #[derive(Subdiagnostic)]
-#[suggestion(parse_add_paren, code = "")]
+#[suggestion(no_crate_example, code = "")]
 //~^ ERROR suggestion without `#[primary_span]` field
 struct PrimarySpanOnVec {
     #[primary_span]
diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr
index f9d1a63031d..343134af6bc 100644
--- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr
+++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr
@@ -1,7 +1,7 @@
 error: label without `#[primary_span]` field
-  --> $DIR/subdiagnostic-derive.rs:47:1
+  --> $DIR/subdiagnostic-derive.rs:49:1
    |
-LL | / #[label(parse_add_paren)]
+LL | / #[label(no_crate_example)]
 LL | |
 LL | | struct C {
 LL | |     var: String,
@@ -9,141 +9,141 @@ LL | | }
    | |_^
 
 error: diagnostic slug must be first argument of a `#[label(...)]` attribute
-  --> $DIR/subdiagnostic-derive.rs:54:1
+  --> $DIR/subdiagnostic-derive.rs:56:1
    |
 LL | #[label]
    | ^^^^^^^^
 
 error: `#[foo]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:63:1
+  --> $DIR/subdiagnostic-derive.rs:65:1
    |
 LL | #[foo]
    | ^^^^^^
 
 error: `#[label = ...]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:73:1
+  --> $DIR/subdiagnostic-derive.rs:75:1
    |
 LL | #[label = "..."]
    | ^^^^^^^^^^^^^^^^
 
 error: `#[label(bug = ...)]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:82:9
+  --> $DIR/subdiagnostic-derive.rs:84:9
    |
 LL | #[label(bug = "...")]
    |         ^^^^^^^^^^^
 
 error: diagnostic slug must be first argument of a `#[label(...)]` attribute
-  --> $DIR/subdiagnostic-derive.rs:82:1
+  --> $DIR/subdiagnostic-derive.rs:84:1
    |
 LL | #[label(bug = "...")]
    | ^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[label("...")]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:92:9
+  --> $DIR/subdiagnostic-derive.rs:94:9
    |
 LL | #[label("...")]
    |         ^^^^^
 
 error: diagnostic slug must be first argument of a `#[label(...)]` attribute
-  --> $DIR/subdiagnostic-derive.rs:92:1
+  --> $DIR/subdiagnostic-derive.rs:94:1
    |
 LL | #[label("...")]
    | ^^^^^^^^^^^^^^^
 
 error: `#[label(slug = ...)]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:102:9
+  --> $DIR/subdiagnostic-derive.rs:104:9
    |
 LL | #[label(slug = 4)]
    |         ^^^^^^^^
 
 error: diagnostic slug must be first argument of a `#[label(...)]` attribute
-  --> $DIR/subdiagnostic-derive.rs:102:1
+  --> $DIR/subdiagnostic-derive.rs:104:1
    |
 LL | #[label(slug = 4)]
    | ^^^^^^^^^^^^^^^^^^
 
 error: `#[label(slug(...))]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:112:9
+  --> $DIR/subdiagnostic-derive.rs:114:9
    |
 LL | #[label(slug("..."))]
    |         ^^^^^^^^^^^
 
 error: diagnostic slug must be first argument of a `#[label(...)]` attribute
-  --> $DIR/subdiagnostic-derive.rs:112:1
+  --> $DIR/subdiagnostic-derive.rs:114:1
    |
 LL | #[label(slug("..."))]
    | ^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug must be first argument of a `#[label(...)]` attribute
-  --> $DIR/subdiagnostic-derive.rs:132:1
+  --> $DIR/subdiagnostic-derive.rs:134:1
    |
 LL | #[label()]
    | ^^^^^^^^^^
 
 error: `#[label(code = ...)]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:141:26
+  --> $DIR/subdiagnostic-derive.rs:143:27
    |
-LL | #[label(parse_add_paren, code = "...")]
-   |                          ^^^^^^^^^^^^
+LL | #[label(no_crate_example, code = "...")]
+   |                           ^^^^^^^^^^^^
 
 error: `#[label(applicability = ...)]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:150:26
+  --> $DIR/subdiagnostic-derive.rs:152:27
    |
-LL | #[label(parse_add_paren, applicability = "machine-applicable")]
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[label(no_crate_example, applicability = "machine-applicable")]
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: unsupported type attribute for subdiagnostic enum
-  --> $DIR/subdiagnostic-derive.rs:159:1
+  --> $DIR/subdiagnostic-derive.rs:161:1
    |
 LL | #[foo]
    | ^^^^^^
 
 error: `#[bar]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:173:5
+  --> $DIR/subdiagnostic-derive.rs:175:5
    |
 LL |     #[bar]
    |     ^^^^^^
 
 error: `#[bar = ...]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:185:5
+  --> $DIR/subdiagnostic-derive.rs:187:5
    |
 LL |     #[bar = "..."]
    |     ^^^^^^^^^^^^^^
 
 error: `#[bar = ...]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:197:5
+  --> $DIR/subdiagnostic-derive.rs:199:5
    |
 LL |     #[bar = 4]
    |     ^^^^^^^^^^
 
 error: `#[bar(...)]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:209:5
+  --> $DIR/subdiagnostic-derive.rs:211:5
    |
 LL |     #[bar("...")]
    |     ^^^^^^^^^^^^^
 
 error: `#[label(code = ...)]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:221:13
+  --> $DIR/subdiagnostic-derive.rs:223:13
    |
 LL |     #[label(code = "...")]
    |             ^^^^^^^^^^^^
 
 error: diagnostic slug must be first argument of a `#[label(...)]` attribute
-  --> $DIR/subdiagnostic-derive.rs:221:5
+  --> $DIR/subdiagnostic-derive.rs:223:5
    |
 LL |     #[label(code = "...")]
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
-  --> $DIR/subdiagnostic-derive.rs:250:5
+  --> $DIR/subdiagnostic-derive.rs:252:5
    |
 LL |     #[primary_span]
    |     ^^^^^^^^^^^^^^^
 
 error: label without `#[primary_span]` field
-  --> $DIR/subdiagnostic-derive.rs:247:1
+  --> $DIR/subdiagnostic-derive.rs:249:1
    |
-LL | / #[label(parse_add_paren)]
+LL | / #[label(no_crate_example)]
 LL | |
 LL | | struct W {
 LL | |     #[primary_span]
@@ -153,13 +153,13 @@ LL | | }
    | |_^
 
 error: `#[applicability]` is only valid on suggestions
-  --> $DIR/subdiagnostic-derive.rs:260:5
+  --> $DIR/subdiagnostic-derive.rs:262:5
    |
 LL |     #[applicability]
    |     ^^^^^^^^^^^^^^^^
 
 error: `#[bar]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:270:5
+  --> $DIR/subdiagnostic-derive.rs:272:5
    |
 LL |     #[bar]
    |     ^^^^^^
@@ -167,13 +167,13 @@ LL |     #[bar]
    = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes
 
 error: `#[bar = ...]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:281:5
+  --> $DIR/subdiagnostic-derive.rs:283:5
    |
 LL |     #[bar = "..."]
    |     ^^^^^^^^^^^^^^
 
 error: `#[bar(...)]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:292:5
+  --> $DIR/subdiagnostic-derive.rs:294:5
    |
 LL |     #[bar("...")]
    |     ^^^^^^^^^^^^^
@@ -181,7 +181,7 @@ LL |     #[bar("...")]
    = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes
 
 error: unexpected unsupported untagged union
-  --> $DIR/subdiagnostic-derive.rs:308:1
+  --> $DIR/subdiagnostic-derive.rs:310:1
    |
 LL | / union AC {
 LL | |
@@ -190,78 +190,78 @@ LL | |     b: u64,
 LL | | }
    | |_^
 
-error: `#[label(parse_add_paren)]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:323:26
+error: `#[label(no_crate::example)]` is not a valid attribute
+  --> $DIR/subdiagnostic-derive.rs:325:27
    |
-LL | #[label(parse_add_paren, parse_add_paren)]
-   |                          ^^^^^^^^^^^^^^^
+LL | #[label(no_crate_example, no_crate::example)]
+   |                           ^^^^^^^^^^^^^^^^^
    |
    = help: a diagnostic slug must be the first argument to the attribute
 
 error: specified multiple times
-  --> $DIR/subdiagnostic-derive.rs:336:5
+  --> $DIR/subdiagnostic-derive.rs:338:5
    |
 LL |     #[primary_span]
    |     ^^^^^^^^^^^^^^^
    |
 note: previously specified here
-  --> $DIR/subdiagnostic-derive.rs:333:5
+  --> $DIR/subdiagnostic-derive.rs:335:5
    |
 LL |     #[primary_span]
    |     ^^^^^^^^^^^^^^^
 
 error: subdiagnostic kind not specified
-  --> $DIR/subdiagnostic-derive.rs:342:8
+  --> $DIR/subdiagnostic-derive.rs:344:8
    |
 LL | struct AG {
    |        ^^
 
 error: specified multiple times
-  --> $DIR/subdiagnostic-derive.rs:379:45
+  --> $DIR/subdiagnostic-derive.rs:381:46
    |
-LL | #[suggestion(parse_add_paren, code = "...", code = "...")]
-   |                                             ^^^^^^^^^^^^
+LL | #[suggestion(no_crate_example, code = "...", code = "...")]
+   |                                              ^^^^^^^^^^^^
    |
 note: previously specified here
-  --> $DIR/subdiagnostic-derive.rs:379:31
+  --> $DIR/subdiagnostic-derive.rs:381:32
    |
-LL | #[suggestion(parse_add_paren, code = "...", code = "...")]
-   |                               ^^^^^^^^^^^^
+LL | #[suggestion(no_crate_example, code = "...", code = "...")]
+   |                                ^^^^^^^^^^^^
 
 error: specified multiple times
-  --> $DIR/subdiagnostic-derive.rs:397:5
+  --> $DIR/subdiagnostic-derive.rs:399:5
    |
 LL |     #[applicability]
    |     ^^^^^^^^^^^^^^^^
    |
 note: previously specified here
-  --> $DIR/subdiagnostic-derive.rs:394:5
+  --> $DIR/subdiagnostic-derive.rs:396:5
    |
 LL |     #[applicability]
    |     ^^^^^^^^^^^^^^^^
 
 error: the `#[applicability]` attribute can only be applied to fields of type `Applicability`
-  --> $DIR/subdiagnostic-derive.rs:407:5
+  --> $DIR/subdiagnostic-derive.rs:409:5
    |
 LL |     #[applicability]
    |     ^^^^^^^^^^^^^^^^
 
 error: suggestion without `code = "..."`
-  --> $DIR/subdiagnostic-derive.rs:420:1
+  --> $DIR/subdiagnostic-derive.rs:422:1
    |
-LL | #[suggestion(parse_add_paren)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[suggestion(no_crate_example)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: invalid applicability
-  --> $DIR/subdiagnostic-derive.rs:430:45
+  --> $DIR/subdiagnostic-derive.rs:432:46
    |
-LL | #[suggestion(parse_add_paren, code = "...", applicability = "foo")]
-   |                                             ^^^^^^^^^^^^^^^^^^^^^
+LL | #[suggestion(no_crate_example, code = "...", applicability = "foo")]
+   |                                              ^^^^^^^^^^^^^^^^^^^^^
 
 error: suggestion without `#[primary_span]` field
-  --> $DIR/subdiagnostic-derive.rs:448:1
+  --> $DIR/subdiagnostic-derive.rs:450:1
    |
-LL | / #[suggestion(parse_add_paren, code = "...")]
+LL | / #[suggestion(no_crate_example, code = "...")]
 LL | |
 LL | | struct AR {
 LL | |     var: String,
@@ -269,25 +269,25 @@ LL | | }
    | |_^
 
 error: unsupported type attribute for subdiagnostic enum
-  --> $DIR/subdiagnostic-derive.rs:462:1
+  --> $DIR/subdiagnostic-derive.rs:464:1
    |
 LL | #[label]
    | ^^^^^^^^
 
 error: `var` doesn't refer to a field on this type
-  --> $DIR/subdiagnostic-derive.rs:482:38
+  --> $DIR/subdiagnostic-derive.rs:484:39
    |
-LL | #[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")]
-   |                                      ^^^^^^^
+LL | #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")]
+   |                                       ^^^^^^^
 
 error: `var` doesn't refer to a field on this type
-  --> $DIR/subdiagnostic-derive.rs:501:42
+  --> $DIR/subdiagnostic-derive.rs:503:43
    |
-LL |     #[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")]
-   |                                          ^^^^^^^
+LL |     #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")]
+   |                                           ^^^^^^^
 
 error: `#[suggestion_part]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:524:5
+  --> $DIR/subdiagnostic-derive.rs:526:5
    |
 LL |     #[suggestion_part]
    |     ^^^^^^^^^^^^^^^^^^
@@ -295,7 +295,7 @@ LL |     #[suggestion_part]
    = help: `#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead
 
 error: `#[suggestion_part(...)]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:527:5
+  --> $DIR/subdiagnostic-derive.rs:529:5
    |
 LL |     #[suggestion_part(code = "...")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -303,9 +303,9 @@ LL |     #[suggestion_part(code = "...")]
    = help: `#[suggestion_part(...)]` is only valid in multipart suggestions
 
 error: suggestion without `#[primary_span]` field
-  --> $DIR/subdiagnostic-derive.rs:521:1
+  --> $DIR/subdiagnostic-derive.rs:523:1
    |
-LL | / #[suggestion(parse_add_paren, code = "...")]
+LL | / #[suggestion(no_crate_example, code = "...")]
 LL | |
 LL | | struct BA {
 LL | |     #[suggestion_part]
@@ -315,17 +315,17 @@ LL | | }
    | |_^
 
 error: `#[multipart_suggestion(code = ...)]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:536:41
+  --> $DIR/subdiagnostic-derive.rs:538:42
    |
-LL | #[multipart_suggestion(parse_add_paren, code = "...", applicability = "machine-applicable")]
-   |                                         ^^^^^^^^^^^^
+LL | #[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")]
+   |                                          ^^^^^^^^^^^^
    |
    = help: only `style` and `applicability` are valid nested attributes
 
 error: multipart suggestion without any `#[suggestion_part(...)]` fields
-  --> $DIR/subdiagnostic-derive.rs:536:1
+  --> $DIR/subdiagnostic-derive.rs:538:1
    |
-LL | / #[multipart_suggestion(parse_add_paren, code = "...", applicability = "machine-applicable")]
+LL | / #[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")]
 LL | |
 LL | |
 LL | | struct BBa {
@@ -334,19 +334,19 @@ LL | | }
    | |_^
 
 error: `#[suggestion_part(...)]` attribute without `code = "..."`
-  --> $DIR/subdiagnostic-derive.rs:546:5
+  --> $DIR/subdiagnostic-derive.rs:548:5
    |
 LL |     #[suggestion_part]
    |     ^^^^^^^^^^^^^^^^^^
 
 error: `#[suggestion_part(...)]` attribute without `code = "..."`
-  --> $DIR/subdiagnostic-derive.rs:554:5
+  --> $DIR/subdiagnostic-derive.rs:556:5
    |
 LL |     #[suggestion_part()]
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: `#[primary_span]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:563:5
+  --> $DIR/subdiagnostic-derive.rs:565:5
    |
 LL |     #[primary_span]
    |     ^^^^^^^^^^^^^^^
@@ -354,9 +354,9 @@ LL |     #[primary_span]
    = help: multipart suggestions use one or more `#[suggestion_part]`s rather than one `#[primary_span]`
 
 error: multipart suggestion without any `#[suggestion_part(...)]` fields
-  --> $DIR/subdiagnostic-derive.rs:560:1
+  --> $DIR/subdiagnostic-derive.rs:562:1
    |
-LL | / #[multipart_suggestion(parse_add_paren)]
+LL | / #[multipart_suggestion(no_crate_example)]
 LL | |
 LL | | struct BC {
 LL | |     #[primary_span]
@@ -366,19 +366,19 @@ LL | | }
    | |_^
 
 error: `#[suggestion_part(...)]` attribute without `code = "..."`
-  --> $DIR/subdiagnostic-derive.rs:571:5
+  --> $DIR/subdiagnostic-derive.rs:573:5
    |
 LL |     #[suggestion_part]
    |     ^^^^^^^^^^^^^^^^^^
 
 error: `#[suggestion_part(...)]` attribute without `code = "..."`
-  --> $DIR/subdiagnostic-derive.rs:574:5
+  --> $DIR/subdiagnostic-derive.rs:576:5
    |
 LL |     #[suggestion_part()]
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: `#[suggestion_part(foo = ...)]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:577:23
+  --> $DIR/subdiagnostic-derive.rs:579:23
    |
 LL |     #[suggestion_part(foo = "bar")]
    |                       ^^^^^^^^^^^
@@ -386,123 +386,123 @@ LL |     #[suggestion_part(foo = "bar")]
    = help: `code` is the only valid nested attribute
 
 error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
-  --> $DIR/subdiagnostic-derive.rs:580:5
+  --> $DIR/subdiagnostic-derive.rs:582:5
    |
 LL |     #[suggestion_part(code = "...")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
-  --> $DIR/subdiagnostic-derive.rs:583:5
+  --> $DIR/subdiagnostic-derive.rs:585:5
    |
 LL |     #[suggestion_part()]
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: specified multiple times
-  --> $DIR/subdiagnostic-derive.rs:591:37
+  --> $DIR/subdiagnostic-derive.rs:593:37
    |
 LL |     #[suggestion_part(code = "...", code = ",,,")]
    |                                     ^^^^^^^^^^^^
    |
 note: previously specified here
-  --> $DIR/subdiagnostic-derive.rs:591:23
+  --> $DIR/subdiagnostic-derive.rs:593:23
    |
 LL |     #[suggestion_part(code = "...", code = ",,,")]
    |                       ^^^^^^^^^^^^
 
 error: `#[applicability]` has no effect if all `#[suggestion]`/`#[multipart_suggestion]` attributes have a static `applicability = "..."`
-  --> $DIR/subdiagnostic-derive.rs:620:5
+  --> $DIR/subdiagnostic-derive.rs:622:5
    |
 LL |     #[applicability]
    |     ^^^^^^^^^^^^^^^^
 
 error: expected exactly one string literal for `code = ...`
-  --> $DIR/subdiagnostic-derive.rs:668:23
+  --> $DIR/subdiagnostic-derive.rs:670:23
    |
 LL |     #[suggestion_part(code("foo"))]
    |                       ^^^^^^^^^^^
 
 error: expected exactly one string literal for `code = ...`
-  --> $DIR/subdiagnostic-derive.rs:677:23
+  --> $DIR/subdiagnostic-derive.rs:679:23
    |
 LL |     #[suggestion_part(code("foo", "bar"))]
    |                       ^^^^^^^^^^^^^^^^^^
 
 error: expected exactly one string literal for `code = ...`
-  --> $DIR/subdiagnostic-derive.rs:686:23
+  --> $DIR/subdiagnostic-derive.rs:688:23
    |
 LL |     #[suggestion_part(code(3))]
    |                       ^^^^^^^
 
 error: expected exactly one string literal for `code = ...`
-  --> $DIR/subdiagnostic-derive.rs:695:23
+  --> $DIR/subdiagnostic-derive.rs:697:23
    |
 LL |     #[suggestion_part(code())]
    |                       ^^^^^^
 
 error: `code = "..."`/`code(...)` must contain only string literals
-  --> $DIR/subdiagnostic-derive.rs:704:23
+  --> $DIR/subdiagnostic-derive.rs:706:23
    |
 LL |     #[suggestion_part(code = 3)]
    |                       ^^^^^^^^
 
 error: specified multiple times
-  --> $DIR/subdiagnostic-derive.rs:746:60
+  --> $DIR/subdiagnostic-derive.rs:748:61
    |
-LL | #[suggestion(parse_add_paren, code = "", style = "hidden", style = "normal")]
-   |                                                            ^^^^^^^^^^^^^^^^
+LL | #[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")]
+   |                                                             ^^^^^^^^^^^^^^^^
    |
 note: previously specified here
-  --> $DIR/subdiagnostic-derive.rs:746:42
+  --> $DIR/subdiagnostic-derive.rs:748:43
    |
-LL | #[suggestion(parse_add_paren, code = "", style = "hidden", style = "normal")]
-   |                                          ^^^^^^^^^^^^^^^^
+LL | #[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")]
+   |                                           ^^^^^^^^^^^^^^^^
 
 error: `#[suggestion_hidden(...)]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:755:1
+  --> $DIR/subdiagnostic-derive.rs:757:1
    |
-LL | #[suggestion_hidden(parse_add_paren, code = "")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[suggestion_hidden(no_crate_example, code = "")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: Use `#[suggestion(..., style = "hidden")]` instead
 
 error: `#[suggestion_hidden(...)]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:763:1
+  --> $DIR/subdiagnostic-derive.rs:765:1
    |
-LL | #[suggestion_hidden(parse_add_paren, code = "", style = "normal")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[suggestion_hidden(no_crate_example, code = "", style = "normal")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: Use `#[suggestion(..., style = "hidden")]` instead
 
 error: invalid suggestion style
-  --> $DIR/subdiagnostic-derive.rs:771:50
+  --> $DIR/subdiagnostic-derive.rs:773:51
    |
-LL | #[suggestion(parse_add_paren, code = "", style = "foo")]
-   |                                                  ^^^^^
+LL | #[suggestion(no_crate_example, code = "", style = "foo")]
+   |                                                   ^^^^^
    |
    = help: valid styles are `normal`, `short`, `hidden`, `verbose` and `tool-only`
 
 error: `#[suggestion(style = ...)]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:779:42
+  --> $DIR/subdiagnostic-derive.rs:781:43
    |
-LL | #[suggestion(parse_add_paren, code = "", style = 42)]
-   |                                          ^^^^^^^^^^
+LL | #[suggestion(no_crate_example, code = "", style = 42)]
+   |                                           ^^^^^^^^^^
 
 error: `#[suggestion(style)]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:787:42
+  --> $DIR/subdiagnostic-derive.rs:789:43
    |
-LL | #[suggestion(parse_add_paren, code = "", style)]
-   |                                          ^^^^^
+LL | #[suggestion(no_crate_example, code = "", style)]
+   |                                           ^^^^^
    |
    = help: a diagnostic slug must be the first argument to the attribute
 
 error: `#[suggestion(style(...))]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:795:42
+  --> $DIR/subdiagnostic-derive.rs:797:43
    |
-LL | #[suggestion(parse_add_paren, code = "", style("foo"))]
-   |                                          ^^^^^^^^^^^^
+LL | #[suggestion(no_crate_example, code = "", style("foo"))]
+   |                                           ^^^^^^^^^^^^
 
 error: `#[primary_span]` is not a valid attribute
-  --> $DIR/subdiagnostic-derive.rs:806:5
+  --> $DIR/subdiagnostic-derive.rs:808:5
    |
 LL |     #[primary_span]
    |     ^^^^^^^^^^^^^^^
@@ -511,9 +511,9 @@ LL |     #[primary_span]
    = help: to create a suggestion with multiple spans, use `#[multipart_suggestion]` instead
 
 error: suggestion without `#[primary_span]` field
-  --> $DIR/subdiagnostic-derive.rs:803:1
+  --> $DIR/subdiagnostic-derive.rs:805:1
    |
-LL | / #[suggestion(parse_add_paren, code = "")]
+LL | / #[suggestion(no_crate_example, code = "")]
 LL | |
 LL | | struct PrimarySpanOnVec {
 LL | |     #[primary_span]
@@ -523,64 +523,64 @@ LL | | }
    | |_^
 
 error: cannot find attribute `foo` in this scope
-  --> $DIR/subdiagnostic-derive.rs:63:3
+  --> $DIR/subdiagnostic-derive.rs:65:3
    |
 LL | #[foo]
    |   ^^^
 
 error: cannot find attribute `foo` in this scope
-  --> $DIR/subdiagnostic-derive.rs:159:3
+  --> $DIR/subdiagnostic-derive.rs:161:3
    |
 LL | #[foo]
    |   ^^^
 
 error: cannot find attribute `bar` in this scope
-  --> $DIR/subdiagnostic-derive.rs:173:7
+  --> $DIR/subdiagnostic-derive.rs:175:7
    |
 LL |     #[bar]
    |       ^^^
 
 error: cannot find attribute `bar` in this scope
-  --> $DIR/subdiagnostic-derive.rs:185:7
+  --> $DIR/subdiagnostic-derive.rs:187:7
    |
 LL |     #[bar = "..."]
    |       ^^^
 
 error: cannot find attribute `bar` in this scope
-  --> $DIR/subdiagnostic-derive.rs:197:7
+  --> $DIR/subdiagnostic-derive.rs:199:7
    |
 LL |     #[bar = 4]
    |       ^^^
 
 error: cannot find attribute `bar` in this scope
-  --> $DIR/subdiagnostic-derive.rs:209:7
+  --> $DIR/subdiagnostic-derive.rs:211:7
    |
 LL |     #[bar("...")]
    |       ^^^
 
 error: cannot find attribute `bar` in this scope
-  --> $DIR/subdiagnostic-derive.rs:270:7
+  --> $DIR/subdiagnostic-derive.rs:272:7
    |
 LL |     #[bar]
    |       ^^^
 
 error: cannot find attribute `bar` in this scope
-  --> $DIR/subdiagnostic-derive.rs:281:7
+  --> $DIR/subdiagnostic-derive.rs:283:7
    |
 LL |     #[bar = "..."]
    |       ^^^
 
 error: cannot find attribute `bar` in this scope
-  --> $DIR/subdiagnostic-derive.rs:292:7
+  --> $DIR/subdiagnostic-derive.rs:294:7
    |
 LL |     #[bar("...")]
    |       ^^^
 
-error[E0425]: cannot find value `slug` in module `rustc_errors::fluent`
-  --> $DIR/subdiagnostic-derive.rs:122:9
+error[E0425]: cannot find value `slug` in module `crate::fluent_generated`
+  --> $DIR/subdiagnostic-derive.rs:124:9
    |
 LL | #[label(slug)]
-   |         ^^^^ not found in `rustc_errors::fluent`
+   |         ^^^^ not found in `crate::fluent_generated`
 
 error: aborting due to 81 previous errors
 
diff --git a/tests/ui-fulldeps/issue-15149.rs b/tests/ui-fulldeps/std/issue-15149.rs
index 064472f5785..064472f5785 100644
--- a/tests/ui-fulldeps/issue-15149.rs
+++ b/tests/ui-fulldeps/std/issue-15149.rs
diff --git a/tests/ui-fulldeps/issue-81357-unsound-file-methods.rs b/tests/ui-fulldeps/std/issue-81357-unsound-file-methods.rs
index fdf1150f8d2..fdf1150f8d2 100644
--- a/tests/ui-fulldeps/issue-81357-unsound-file-methods.rs
+++ b/tests/ui-fulldeps/std/issue-81357-unsound-file-methods.rs
diff --git a/tests/ui-fulldeps/stdio-from.rs b/tests/ui-fulldeps/std/stdio-from.rs
index fef9f27fcdf..fef9f27fcdf 100644
--- a/tests/ui-fulldeps/stdio-from.rs
+++ b/tests/ui-fulldeps/std/stdio-from.rs
diff --git a/tests/ui-fulldeps/switch-stdout.rs b/tests/ui-fulldeps/std/switch-stdout.rs
index e9501a80930..e9501a80930 100644
--- a/tests/ui-fulldeps/switch-stdout.rs
+++ b/tests/ui-fulldeps/std/switch-stdout.rs
diff --git a/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr b/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr
index d1b9d7a40b4..eb739b149a1 100644
--- a/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr
+++ b/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr
@@ -7,10 +7,7 @@ LL |   fn oom() -> ! {
    |  _-^^^^^^^^^^^^
 LL | |     loop {}
 LL | | }
-   | | -
-   | | |
-   | |_unexpected argument of type `core::alloc::Layout`
-   |   help: remove the extra argument
+   | |_- unexpected argument of type `core::alloc::Layout`
    |
 note: function defined here
   --> $DIR/alloc-error-handler-bad-signature-3.rs:10:4
diff --git a/tests/ui/argument-suggestions/extra_arguments.rs b/tests/ui/argument-suggestions/extra_arguments.rs
index 3f83de95e2d..1442062326d 100644
--- a/tests/ui/argument-suggestions/extra_arguments.rs
+++ b/tests/ui/argument-suggestions/extra_arguments.rs
@@ -3,8 +3,15 @@ fn one_arg(_a: i32) {}
 fn two_arg_same(_a: i32, _b: i32) {}
 fn two_arg_diff(_a: i32, _b: &str) {}
 
+macro_rules! foo {
+    ($x:expr) => {
+        empty($x, 1); //~ ERROR function takes
+    }
+}
+
 fn main() {
   empty(""); //~ ERROR function takes
+  empty(1, 1); //~ ERROR function takes
 
   one_arg(1, 1); //~ ERROR function takes
   one_arg(1, ""); //~ ERROR function takes
@@ -32,4 +39,5 @@ fn main() {
     1,
     ""
   );
+  foo!(1);
 }
diff --git a/tests/ui/argument-suggestions/extra_arguments.stderr b/tests/ui/argument-suggestions/extra_arguments.stderr
index 0911685b428..11c71099743 100644
--- a/tests/ui/argument-suggestions/extra_arguments.stderr
+++ b/tests/ui/argument-suggestions/extra_arguments.stderr
@@ -1,5 +1,5 @@
 error[E0061]: this function takes 0 arguments but 1 argument was supplied
-  --> $DIR/extra_arguments.rs:7:3
+  --> $DIR/extra_arguments.rs:13:3
    |
 LL |   empty("");
    |   ^^^^^ --
@@ -13,8 +13,27 @@ note: function defined here
 LL | fn empty() {}
    |    ^^^^^
 
+error[E0061]: this function takes 0 arguments but 2 arguments were supplied
+  --> $DIR/extra_arguments.rs:14:3
+   |
+LL |   empty(1, 1);
+   |   ^^^^^ -  - unexpected argument of type `{integer}`
+   |         |
+   |         unexpected argument of type `{integer}`
+   |
+note: function defined here
+  --> $DIR/extra_arguments.rs:1:4
+   |
+LL | fn empty() {}
+   |    ^^^^^
+help: remove the extra arguments
+   |
+LL -   empty(1, 1);
+LL +   empty();
+   |
+
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
-  --> $DIR/extra_arguments.rs:9:3
+  --> $DIR/extra_arguments.rs:16:3
    |
 LL |   one_arg(1, 1);
    |   ^^^^^^^  ---
@@ -29,7 +48,7 @@ LL | fn one_arg(_a: i32) {}
    |    ^^^^^^^ -------
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
-  --> $DIR/extra_arguments.rs:10:3
+  --> $DIR/extra_arguments.rs:17:3
    |
 LL |   one_arg(1, "");
    |   ^^^^^^^  ----
@@ -44,7 +63,7 @@ LL | fn one_arg(_a: i32) {}
    |    ^^^^^^^ -------
 
 error[E0061]: this function takes 1 argument but 3 arguments were supplied
-  --> $DIR/extra_arguments.rs:11:3
+  --> $DIR/extra_arguments.rs:18:3
    |
 LL |   one_arg(1, "", 1.0);
    |   ^^^^^^^    --  --- unexpected argument of type `{float}`
@@ -63,7 +82,7 @@ LL +   one_arg(1);
    |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
-  --> $DIR/extra_arguments.rs:13:3
+  --> $DIR/extra_arguments.rs:20:3
    |
 LL |   two_arg_same(1, 1, 1);
    |   ^^^^^^^^^^^^     ---
@@ -78,7 +97,7 @@ LL | fn two_arg_same(_a: i32, _b: i32) {}
    |    ^^^^^^^^^^^^ -------  -------
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
-  --> $DIR/extra_arguments.rs:14:3
+  --> $DIR/extra_arguments.rs:21:3
    |
 LL |   two_arg_same(1, 1, 1.0);
    |   ^^^^^^^^^^^^     -----
@@ -93,7 +112,7 @@ LL | fn two_arg_same(_a: i32, _b: i32) {}
    |    ^^^^^^^^^^^^ -------  -------
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
-  --> $DIR/extra_arguments.rs:16:3
+  --> $DIR/extra_arguments.rs:23:3
    |
 LL |   two_arg_diff(1, 1, "");
    |   ^^^^^^^^^^^^  ---
@@ -108,7 +127,7 @@ LL | fn two_arg_diff(_a: i32, _b: &str) {}
    |    ^^^^^^^^^^^^ -------  --------
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
-  --> $DIR/extra_arguments.rs:17:3
+  --> $DIR/extra_arguments.rs:24:3
    |
 LL |   two_arg_diff(1, "", "");
    |   ^^^^^^^^^^^^      ----
@@ -123,7 +142,7 @@ LL | fn two_arg_diff(_a: i32, _b: &str) {}
    |    ^^^^^^^^^^^^ -------  --------
 
 error[E0061]: this function takes 2 arguments but 4 arguments were supplied
-  --> $DIR/extra_arguments.rs:18:3
+  --> $DIR/extra_arguments.rs:25:3
    |
 LL |   two_arg_diff(1, 1, "", "");
    |   ^^^^^^^^^^^^    -      -- unexpected argument of type `&'static str`
@@ -142,7 +161,7 @@ LL +   two_arg_diff(1, "");
    |
 
 error[E0061]: this function takes 2 arguments but 4 arguments were supplied
-  --> $DIR/extra_arguments.rs:19:3
+  --> $DIR/extra_arguments.rs:26:3
    |
 LL |   two_arg_diff(1, "", 1, "");
    |   ^^^^^^^^^^^^        -  -- unexpected argument of type `&'static str`
@@ -161,7 +180,7 @@ LL +   two_arg_diff(1, "");
    |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
-  --> $DIR/extra_arguments.rs:22:3
+  --> $DIR/extra_arguments.rs:29:3
    |
 LL |   two_arg_same(1, 1,     "");
    |   ^^^^^^^^^^^^     --------
@@ -176,7 +195,7 @@ LL | fn two_arg_same(_a: i32, _b: i32) {}
    |    ^^^^^^^^^^^^ -------  -------
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
-  --> $DIR/extra_arguments.rs:23:3
+  --> $DIR/extra_arguments.rs:30:3
    |
 LL |   two_arg_diff(1, 1,     "");
    |   ^^^^^^^^^^^^  ---
@@ -191,7 +210,7 @@ LL | fn two_arg_diff(_a: i32, _b: &str) {}
    |    ^^^^^^^^^^^^ -------  --------
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
-  --> $DIR/extra_arguments.rs:24:3
+  --> $DIR/extra_arguments.rs:31:3
    |
 LL |     two_arg_same(
    |     ^^^^^^^^^^^^
@@ -211,7 +230,7 @@ LL | fn two_arg_same(_a: i32, _b: i32) {}
    |    ^^^^^^^^^^^^ -------  -------
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
-  --> $DIR/extra_arguments.rs:30:3
+  --> $DIR/extra_arguments.rs:37:3
    |
 LL |     two_arg_diff(
    |     ^^^^^^^^^^^^
@@ -229,6 +248,26 @@ note: function defined here
 LL | fn two_arg_diff(_a: i32, _b: &str) {}
    |    ^^^^^^^^^^^^ -------  --------
 
-error: aborting due to 14 previous errors
+error[E0061]: this function takes 0 arguments but 2 arguments were supplied
+  --> $DIR/extra_arguments.rs:8:9
+   |
+LL |         empty($x, 1);
+   |         ^^^^^     - unexpected argument of type `{integer}`
+...
+LL |   foo!(1);
+   |   -------
+   |   |    |
+   |   |    unexpected argument of type `{integer}`
+   |   |    help: remove the extra argument
+   |   in this macro invocation
+   |
+note: function defined here
+  --> $DIR/extra_arguments.rs:1:4
+   |
+LL | fn empty() {}
+   |    ^^^^^
+   = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 16 previous errors
 
 For more information about this error, try `rustc --explain E0061`.
diff --git a/tests/ui/argument-suggestions/issue-100154.stderr b/tests/ui/argument-suggestions/issue-100154.stderr
index 1499229c3ce..2504f616fb7 100644
--- a/tests/ui/argument-suggestions/issue-100154.stderr
+++ b/tests/ui/argument-suggestions/issue-100154.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this function takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-100154.rs:4:5
    |
 LL |     foo::<()>(());
diff --git a/tests/ui/argument-suggestions/too-long.stderr b/tests/ui/argument-suggestions/too-long.stderr
index 4928943294b..bb6f06a35c6 100644
--- a/tests/ui/argument-suggestions/too-long.stderr
+++ b/tests/ui/argument-suggestions/too-long.stderr
@@ -6,7 +6,7 @@ LL |     qux.foo(a, b, c, d, e, f, g, h, i, j, k, l);
    |         |
    |         arguments to this method are incorrect
    |
-note: associated function defined here
+note: method defined here
   --> $DIR/too-long.rs:4:8
    |
 LL |     fn foo(
diff --git a/tests/ui/associated-consts/issue-105330.stderr b/tests/ui/associated-consts/issue-105330.stderr
index 08570d4a5d9..bbafc55dac3 100644
--- a/tests/ui/associated-consts/issue-105330.stderr
+++ b/tests/ui/associated-consts/issue-105330.stderr
@@ -33,7 +33,7 @@ LL | fn main<A: TraitWAssocConst<A=32>>() {
    = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
    = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl headers
   --> $DIR/issue-105330.rs:6:27
    |
 LL | impl TraitWAssocConst for impl Demo {
diff --git a/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs
new file mode 100644
index 00000000000..8cab1f66c27
--- /dev/null
+++ b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs
@@ -0,0 +1,14 @@
+#![feature(associated_type_bounds)]
+
+trait B {
+    type AssocType;
+}
+
+fn f()
+where
+    dyn for<'j> B<AssocType: 'j>:,
+    //~^ ERROR associated type bounds are only allowed in where clauses and function signatures
+{
+}
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr
new file mode 100644
index 00000000000..6fa266d23d4
--- /dev/null
+++ b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr
@@ -0,0 +1,8 @@
+error: associated type bounds are only allowed in where clauses and function signatures, not in bounds
+  --> $DIR/bad-universal-in-dyn-in-where-clause.rs:9:19
+   |
+LL |     dyn for<'j> B<AssocType: 'j>:,
+   |                   ^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs
new file mode 100644
index 00000000000..1d5d181efcc
--- /dev/null
+++ b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs
@@ -0,0 +1,13 @@
+#![feature(associated_type_bounds)]
+
+trait Trait {
+    type Item;
+}
+
+trait Trait2 {}
+
+// It's not possible to insert a universal `impl Trait` here!
+impl dyn Trait<Item: Trait2> {}
+//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.stderr b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.stderr
new file mode 100644
index 00000000000..8b66627d57f
--- /dev/null
+++ b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.stderr
@@ -0,0 +1,8 @@
+error: associated type bounds are only allowed in where clauses and function signatures, not in impl headers
+  --> $DIR/bad-universal-in-impl-sig.rs:10:16
+   |
+LL | impl dyn Trait<Item: Trait2> {}
+   |                ^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/associated-type-bounds/inside-adt.rs b/tests/ui/associated-type-bounds/inside-adt.rs
index 8eb8c44bb42..057966941dc 100644
--- a/tests/ui/associated-type-bounds/inside-adt.rs
+++ b/tests/ui/associated-type-bounds/inside-adt.rs
@@ -3,28 +3,24 @@
 use std::mem::ManuallyDrop;
 
 struct S1 { f: dyn Iterator<Item: Copy> }
-//~^ ERROR associated type bounds are not allowed within structs, enums, or unions
+//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
 struct S2 { f: Box<dyn Iterator<Item: Copy>> }
-//~^ ERROR associated type bounds are not allowed within structs, enums, or unions
+//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
 struct S3 { f: dyn Iterator<Item: 'static> }
-//~^ ERROR associated type bounds are not allowed within structs, enums, or unions
+//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
 
 enum E1 { V(dyn Iterator<Item: Copy>) }
-//~^ ERROR associated type bounds are not allowed within structs, enums, or unions
-//~| ERROR the size for values of type `(dyn Iterator<Item = impl Copy> + 'static)`
+//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
 enum E2 { V(Box<dyn Iterator<Item: Copy>>) }
-//~^ ERROR associated type bounds are not allowed within structs, enums, or unions
+//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
 enum E3 { V(dyn Iterator<Item: 'static>) }
-//~^ ERROR associated type bounds are not allowed within structs, enums, or unions
-//~| ERROR the size for values of type `(dyn Iterator<Item = impl Sized + 'static> + 'static)`
+//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
 
 union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> }
-//~^ ERROR associated type bounds are not allowed within structs, enums, or unions
-//~| ERROR the size for values of type `(dyn Iterator<Item = impl Copy> + 'static)`
+//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
 union U2 { f: ManuallyDrop<Box<dyn Iterator<Item: Copy>>> }
-//~^ ERROR associated type bounds are not allowed within structs, enums, or unions
+//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
 union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> }
-//~^ ERROR associated type bounds are not allowed within structs, enums, or unions
-//~| ERROR the size for values of type `(dyn Iterator<Item = impl Sized + 'static> + 'static)`
+//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
 
 fn main() {}
diff --git a/tests/ui/associated-type-bounds/inside-adt.stderr b/tests/ui/associated-type-bounds/inside-adt.stderr
index 1668b613b25..f848bd798ee 100644
--- a/tests/ui/associated-type-bounds/inside-adt.stderr
+++ b/tests/ui/associated-type-bounds/inside-adt.stderr
@@ -1,131 +1,56 @@
-error: associated type bounds are not allowed within structs, enums, or unions
+error: associated type bounds are only allowed in where clauses and function signatures, not in field types
   --> $DIR/inside-adt.rs:5:29
    |
 LL | struct S1 { f: dyn Iterator<Item: Copy> }
    |                             ^^^^^^^^^^
 
-error: associated type bounds are not allowed within structs, enums, or unions
+error: associated type bounds are only allowed in where clauses and function signatures, not in field types
   --> $DIR/inside-adt.rs:7:33
    |
 LL | struct S2 { f: Box<dyn Iterator<Item: Copy>> }
    |                                 ^^^^^^^^^^
 
-error: associated type bounds are not allowed within structs, enums, or unions
+error: associated type bounds are only allowed in where clauses and function signatures, not in field types
   --> $DIR/inside-adt.rs:9:29
    |
 LL | struct S3 { f: dyn Iterator<Item: 'static> }
    |                             ^^^^^^^^^^^^^
 
-error: associated type bounds are not allowed within structs, enums, or unions
+error: associated type bounds are only allowed in where clauses and function signatures, not in field types
   --> $DIR/inside-adt.rs:12:26
    |
 LL | enum E1 { V(dyn Iterator<Item: Copy>) }
    |                          ^^^^^^^^^^
 
-error: associated type bounds are not allowed within structs, enums, or unions
-  --> $DIR/inside-adt.rs:15:30
+error: associated type bounds are only allowed in where clauses and function signatures, not in field types
+  --> $DIR/inside-adt.rs:14:30
    |
 LL | enum E2 { V(Box<dyn Iterator<Item: Copy>>) }
    |                              ^^^^^^^^^^
 
-error: associated type bounds are not allowed within structs, enums, or unions
-  --> $DIR/inside-adt.rs:17:26
+error: associated type bounds are only allowed in where clauses and function signatures, not in field types
+  --> $DIR/inside-adt.rs:16:26
    |
 LL | enum E3 { V(dyn Iterator<Item: 'static>) }
    |                          ^^^^^^^^^^^^^
 
-error: associated type bounds are not allowed within structs, enums, or unions
-  --> $DIR/inside-adt.rs:21:41
+error: associated type bounds are only allowed in where clauses and function signatures, not in field types
+  --> $DIR/inside-adt.rs:19:41
    |
 LL | union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> }
    |                                         ^^^^^^^^^^
 
-error: associated type bounds are not allowed within structs, enums, or unions
-  --> $DIR/inside-adt.rs:24:45
+error: associated type bounds are only allowed in where clauses and function signatures, not in field types
+  --> $DIR/inside-adt.rs:21:45
    |
 LL | union U2 { f: ManuallyDrop<Box<dyn Iterator<Item: Copy>>> }
    |                                             ^^^^^^^^^^
 
-error: associated type bounds are not allowed within structs, enums, or unions
-  --> $DIR/inside-adt.rs:26:41
+error: associated type bounds are only allowed in where clauses and function signatures, not in field types
+  --> $DIR/inside-adt.rs:23:41
    |
 LL | union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> }
    |                                         ^^^^^^^^^^^^^
 
-error[E0277]: the size for values of type `(dyn Iterator<Item = impl Copy> + 'static)` cannot be known at compilation time
-  --> $DIR/inside-adt.rs:12:13
-   |
-LL | enum E1 { V(dyn Iterator<Item: Copy>) }
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `(dyn Iterator<Item = impl Copy> + 'static)`
-   = note: no field of an enum variant may have a dynamically sized type
-   = help: change the field's type to have a statically known size
-help: borrowed types always have a statically known size
-   |
-LL | enum E1 { V(&dyn Iterator<Item: Copy>) }
-   |             +
-help: the `Box` type always has a statically known size and allocates its contents in the heap
-   |
-LL | enum E1 { V(Box<dyn Iterator<Item: Copy>>) }
-   |             ++++                        +
-
-error[E0277]: the size for values of type `(dyn Iterator<Item = impl Sized + 'static> + 'static)` cannot be known at compilation time
-  --> $DIR/inside-adt.rs:17:13
-   |
-LL | enum E3 { V(dyn Iterator<Item: 'static>) }
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `(dyn Iterator<Item = impl Sized + 'static> + 'static)`
-   = note: no field of an enum variant may have a dynamically sized type
-   = help: change the field's type to have a statically known size
-help: borrowed types always have a statically known size
-   |
-LL | enum E3 { V(&dyn Iterator<Item: 'static>) }
-   |             +
-help: the `Box` type always has a statically known size and allocates its contents in the heap
-   |
-LL | enum E3 { V(Box<dyn Iterator<Item: 'static>>) }
-   |             ++++                           +
-
-error[E0277]: the size for values of type `(dyn Iterator<Item = impl Copy> + 'static)` cannot be known at compilation time
-  --> $DIR/inside-adt.rs:21:15
-   |
-LL | union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> }
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: within `ManuallyDrop<(dyn Iterator<Item = impl Copy> + 'static)>`, the trait `Sized` is not implemented for `(dyn Iterator<Item = impl Copy> + 'static)`
-   = note: required because it appears within the type `ManuallyDrop<dyn Iterator<Item = impl Copy>>`
-   = note: no field of a union may have a dynamically sized type
-   = help: change the field's type to have a statically known size
-help: borrowed types always have a statically known size
-   |
-LL | union U1 { f: &ManuallyDrop<dyn Iterator<Item: Copy>> }
-   |               +
-help: the `Box` type always has a statically known size and allocates its contents in the heap
-   |
-LL | union U1 { f: Box<ManuallyDrop<dyn Iterator<Item: Copy>>> }
-   |               ++++                                      +
-
-error[E0277]: the size for values of type `(dyn Iterator<Item = impl Sized + 'static> + 'static)` cannot be known at compilation time
-  --> $DIR/inside-adt.rs:26:15
-   |
-LL | union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> }
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: within `ManuallyDrop<(dyn Iterator<Item = impl Sized + 'static> + 'static)>`, the trait `Sized` is not implemented for `(dyn Iterator<Item = impl Sized + 'static> + 'static)`
-   = note: required because it appears within the type `ManuallyDrop<dyn Iterator<Item = impl Sized>>`
-   = note: no field of a union may have a dynamically sized type
-   = help: change the field's type to have a statically known size
-help: borrowed types always have a statically known size
-   |
-LL | union U3 { f: &ManuallyDrop<dyn Iterator<Item: 'static>> }
-   |               +
-help: the `Box` type always has a statically known size and allocates its contents in the heap
-   |
-LL | union U3 { f: Box<ManuallyDrop<dyn Iterator<Item: 'static>>> }
-   |               ++++                                         +
-
-error: aborting due to 13 previous errors
+error: aborting due to 9 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-types/associated-type-projection-from-supertrait.stderr b/tests/ui/associated-types/associated-type-projection-from-supertrait.stderr
index 5fe53a27eb8..3f3bf22b0c4 100644
--- a/tests/ui/associated-types/associated-type-projection-from-supertrait.stderr
+++ b/tests/ui/associated-types/associated-type-projection-from-supertrait.stderr
@@ -34,7 +34,7 @@ LL | fn f() { ModelT.chip_paint(Blue); }
    |                 |
    |                 arguments to this method are incorrect
    |
-note: associated function defined here
+note: method defined here
   --> $DIR/associated-type-projection-from-supertrait.rs:12:8
    |
 LL |     fn chip_paint(&self, c: Self::Color) { }
@@ -48,7 +48,7 @@ LL | fn g() { ModelU.chip_paint(Black); }
    |                 |
    |                 arguments to this method are incorrect
    |
-note: associated function defined here
+note: method defined here
   --> $DIR/associated-type-projection-from-supertrait.rs:12:8
    |
 LL |     fn chip_paint(&self, c: Self::Color) { }
diff --git a/tests/ui/associated-types/associated-types-eq-hr.stderr b/tests/ui/associated-types/associated-types-eq-hr.stderr
index 99db0c1bf3b..3e1142d5d95 100644
--- a/tests/ui/associated-types/associated-types-eq-hr.stderr
+++ b/tests/ui/associated-types/associated-types-eq-hr.stderr
@@ -15,7 +15,7 @@ note: required by a bound in `foo`
   --> $DIR/associated-types-eq-hr.rs:45:36
    |
 LL | fn foo<T>()
-   |    --- required by a bound in this
+   |    --- required by a bound in this function
 LL | where
 LL |     T: for<'x> TheTrait<&'x isize, A = &'x isize>,
    |                                    ^^^^^^^^^^^^^ required by this bound in `foo`
@@ -37,7 +37,7 @@ note: required by a bound in `bar`
   --> $DIR/associated-types-eq-hr.rs:52:36
    |
 LL | fn bar<T>()
-   |    --- required by a bound in this
+   |    --- required by a bound in this function
 LL | where
 LL |     T: for<'x> TheTrait<&'x isize, A = &'x usize>,
    |                                    ^^^^^^^^^^^^^ required by this bound in `bar`
diff --git a/tests/ui/associated-types/defaults-suitability.stderr b/tests/ui/associated-types/defaults-suitability.stderr
index eadad4cd572..2485758757b 100644
--- a/tests/ui/associated-types/defaults-suitability.stderr
+++ b/tests/ui/associated-types/defaults-suitability.stderr
@@ -27,7 +27,7 @@ LL |     Self::Ty: Clone,
    |               ^^^^^ required by this bound in `Tr2::Ty`
 LL | {
 LL |     type Ty = NotClone;
-   |          -- required by a bound in this
+   |          -- required by a bound in this associated type
 help: consider annotating `NotClone` with `#[derive(Clone)]`
    |
 LL | #[derive(Clone)]
@@ -75,7 +75,7 @@ LL |     Self::Assoc: IsU8<Self::Assoc>,
    |                  ^^^^^^^^^^^^^^^^^ required by this bound in `D::Assoc`
 ...
 LL |     type Assoc = NotClone;
-   |          ----- required by a bound in this
+   |          ----- required by a bound in this associated type
 
 error[E0277]: the trait bound `<Self as Foo2<T>>::Baz: Clone` is not satisfied
   --> $DIR/defaults-suitability.rs:65:23
@@ -124,7 +124,7 @@ LL |     Self::Baz: Clone,
    |                ^^^^^ required by this bound in `Foo3::Baz`
 ...
 LL |     type Baz = T;
-   |          --- required by a bound in this
+   |          --- required by a bound in this associated type
 help: consider further restricting type parameter `T`
    |
 LL |     Self::Baz: Clone, T: std::clone::Clone
diff --git a/tests/ui/associated-types/hr-associated-type-bound-1.stderr b/tests/ui/associated-types/hr-associated-type-bound-1.stderr
index 73b5e1053fb..b380a1b6f06 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-1.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-1.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `X`
   --> $DIR/hr-associated-type-bound-1.rs:3:33
    |
 LL | trait X<'a>
-   |       - required by a bound in this
+   |       - required by a bound in this trait
 LL | where
 LL |     for<'b> <Self as X<'b>>::U: Clone,
    |                                 ^^^^^ required by this bound in `X`
diff --git a/tests/ui/associated-types/hr-associated-type-bound-object.stderr b/tests/ui/associated-types/hr-associated-type-bound-object.stderr
index 6d19186bde4..a0a6f76a583 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-object.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-object.stderr
@@ -8,7 +8,7 @@ note: required by a bound in `X`
   --> $DIR/hr-associated-type-bound-object.rs:3:33
    |
 LL | trait X<'a>
-   |       - required by a bound in this
+   |       - required by a bound in this trait
 LL | where
 LL |     for<'b> <Self as X<'b>>::U: Clone,
    |                                 ^^^^^ required by this bound in `X`
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-1.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-1.stderr
index af2e616896a..e249f2e0c27 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-1.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-1.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `Y`
   --> $DIR/hr-associated-type-bound-param-1.rs:4:36
    |
 LL | trait Y<'a, T: ?Sized>
-   |       - required by a bound in this
+   |       - required by a bound in this trait
 ...
 LL |     for<'b> <Self as Y<'b, T>>::V: Clone,
    |                                    ^^^^^ required by this bound in `Y`
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr
index 52294f8c94a..366670269d7 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `Z`
   --> $DIR/hr-associated-type-bound-param-2.rs:6:35
    |
 LL | trait Z<'a, T: ?Sized>
-   |       - required by a bound in this
+   |       - required by a bound in this trait
 ...
 LL |     for<'b> <T as Z<'b, u16>>::W: Clone,
    |                                   ^^^^^ required by this bound in `Z`
@@ -25,7 +25,7 @@ note: required by a bound in `Z`
   --> $DIR/hr-associated-type-bound-param-2.rs:6:35
    |
 LL | trait Z<'a, T: ?Sized>
-   |       - required by a bound in this
+   |       - required by a bound in this trait
 ...
 LL |     for<'b> <T as Z<'b, u16>>::W: Clone,
    |                                   ^^^^^ required by this bound in `Z`
@@ -41,7 +41,7 @@ note: required by a bound in `Z`
   --> $DIR/hr-associated-type-bound-param-2.rs:6:35
    |
 LL | trait Z<'a, T: ?Sized>
-   |       - required by a bound in this
+   |       - required by a bound in this trait
 ...
 LL |     for<'b> <T as Z<'b, u16>>::W: Clone,
    |                                   ^^^^^ required by this bound in `Z`
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr
index 84d5e0494cb..f49439d3573 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `X`
   --> $DIR/hr-associated-type-bound-param-3.rs:4:33
    |
 LL | trait X<'a, T>
-   |       - required by a bound in this
+   |       - required by a bound in this trait
 ...
 LL |     for<'b> <T as X<'b, T>>::U: Clone,
    |                                 ^^^^^ required by this bound in `X`
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr
index ee1d5d32495..f8733b423d7 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `X`
   --> $DIR/hr-associated-type-bound-param-4.rs:4:36
    |
 LL | trait X<'a, T>
-   |       - required by a bound in this
+   |       - required by a bound in this trait
 ...
 LL |     for<'b> <(T,) as X<'b, T>>::U: Clone,
    |                                    ^^^^^ required by this bound in `X`
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr
index ece3151ba97..aae80a9b2e1 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `X`
   --> $DIR/hr-associated-type-bound-param-5.rs:17:45
    |
 LL | trait X<'a, T: Cycle + for<'b> X<'b, T>>
-   |       - required by a bound in this
+   |       - required by a bound in this trait
 ...
 LL |     for<'b> <T::Next as X<'b, T::Next>>::U: Clone,
    |                                             ^^^^^ required by this bound in `X`
@@ -25,7 +25,7 @@ note: required by a bound in `X`
   --> $DIR/hr-associated-type-bound-param-5.rs:17:45
    |
 LL | trait X<'a, T: Cycle + for<'b> X<'b, T>>
-   |       - required by a bound in this
+   |       - required by a bound in this trait
 ...
 LL |     for<'b> <T::Next as X<'b, T::Next>>::U: Clone,
    |                                             ^^^^^ required by this bound in `X`
diff --git a/tests/ui/associated-types/hr-associated-type-projection-1.stderr b/tests/ui/associated-types/hr-associated-type-projection-1.stderr
index 2281d9419b4..dd0389c34e6 100644
--- a/tests/ui/associated-types/hr-associated-type-projection-1.stderr
+++ b/tests/ui/associated-types/hr-associated-type-projection-1.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `UnsafeCopy`
   --> $DIR/hr-associated-type-projection-1.rs:3:64
    |
 LL | trait UnsafeCopy<'a, T: Copy>
-   |       ---------- required by a bound in this
+   |       ---------- required by a bound in this trait
 LL | where
 LL |     for<'b> <Self as UnsafeCopy<'b, T>>::Item: std::ops::Deref<Target = T>,
    |                                                                ^^^^^^^^^^ required by this bound in `UnsafeCopy`
diff --git a/tests/ui/associated-types/point-at-type-on-obligation-failure-2.stderr b/tests/ui/associated-types/point-at-type-on-obligation-failure-2.stderr
index 2e7a1dd2a31..3b4689e08cc 100644
--- a/tests/ui/associated-types/point-at-type-on-obligation-failure-2.stderr
+++ b/tests/ui/associated-types/point-at-type-on-obligation-failure-2.stderr
@@ -23,7 +23,7 @@ LL |     Self::Assoc: Bar,
    |                  ^^^ required by this bound in `Baz::Assoc`
 LL | {
 LL |     type Assoc;
-   |          ----- required by a bound in this
+   |          ----- required by a bound in this associated type
 
 error[E0277]: the trait bound `bool: Bar` is not satisfied
   --> $DIR/point-at-type-on-obligation-failure-2.rs:30:18
@@ -38,7 +38,7 @@ LL |     <Self as Bat>::Assoc: Bar,
    |                           ^^^ required by this bound in `Bat::Assoc`
 LL | {
 LL |     type Assoc;
-   |          ----- required by a bound in this
+   |          ----- required by a bound in this associated type
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.rs b/tests/ui/async-await/in-trait/fn-not-async-err2.rs
index 2c4ed553580..78017429f73 100644
--- a/tests/ui/async-await/in-trait/fn-not-async-err2.rs
+++ b/tests/ui/async-await/in-trait/fn-not-async-err2.rs
@@ -11,7 +11,7 @@ trait MyTrait {
 
 impl MyTrait for i32 {
     fn foo(&self) -> impl Future<Output = i32> {
-        //~^ ERROR `impl Trait` only allowed in function and inherent method return types, not in `impl` method return [E0562]
+        //~^ ERROR `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types
         async { *self }
     }
 }
diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.stderr b/tests/ui/async-await/in-trait/fn-not-async-err2.stderr
index f591f184772..37d9669c012 100644
--- a/tests/ui/async-await/in-trait/fn-not-async-err2.stderr
+++ b/tests/ui/async-await/in-trait/fn-not-async-err2.stderr
@@ -1,4 +1,4 @@
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types
   --> $DIR/fn-not-async-err2.rs:13:22
    |
 LL |     fn foo(&self) -> impl Future<Output = i32> {
diff --git a/tests/ui/async-await/issues/issue-62097.rs b/tests/ui/async-await/issues/issue-62097.rs
index a24c84cffc7..13c72abb136 100644
--- a/tests/ui/async-await/issues/issue-62097.rs
+++ b/tests/ui/async-await/issues/issue-62097.rs
@@ -12,7 +12,7 @@ impl Struct {
     pub async fn run_dummy_fn(&self) {
         foo(|| self.bar()).await;
         //~^ ERROR closure may outlive the current function
-        //~| ERROR borrowed data escapes outside of associated function
+        //~| ERROR borrowed data escapes outside of method
     }
 
     pub fn bar(&self) {}
diff --git a/tests/ui/async-await/issues/issue-62097.stderr b/tests/ui/async-await/issues/issue-62097.stderr
index 786f6213260..21a61548d01 100644
--- a/tests/ui/async-await/issues/issue-62097.stderr
+++ b/tests/ui/async-await/issues/issue-62097.stderr
@@ -16,18 +16,18 @@ help: to force the closure to take ownership of `self` (and any other referenced
 LL |         foo(move || self.bar()).await;
    |             ++++
 
-error[E0521]: borrowed data escapes outside of associated function
+error[E0521]: borrowed data escapes outside of method
   --> $DIR/issue-62097.rs:13:9
    |
 LL |     pub async fn run_dummy_fn(&self) {
    |                               -----
    |                               |
-   |                               `self` is a reference that is only valid in the associated function body
+   |                               `self` is a reference that is only valid in the method body
    |                               let's call the lifetime of this reference `'1`
 LL |         foo(|| self.bar()).await;
    |         ^^^^^^^^^^^^^^^^^^
    |         |
-   |         `self` escapes the associated function body here
+   |         `self` escapes the method body here
    |         argument requires that `'1` must outlive `'static`
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/async-await/issues/issue-65159.rs b/tests/ui/async-await/issues/issue-65159.rs
index df2ca025705..6e547508bd4 100644
--- a/tests/ui/async-await/issues/issue-65159.rs
+++ b/tests/ui/async-await/issues/issue-65159.rs
@@ -3,7 +3,7 @@
 // edition:2018
 
 async fn copy() -> Result<()>
-//~^ ERROR this enum takes 2 generic arguments
+//~^ ERROR enum takes 2 generic arguments
 {
     Ok(())
 }
diff --git a/tests/ui/async-await/issues/issue-65159.stderr b/tests/ui/async-await/issues/issue-65159.stderr
index 40c0e72b203..b8741333c32 100644
--- a/tests/ui/async-await/issues/issue-65159.stderr
+++ b/tests/ui/async-await/issues/issue-65159.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: enum takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-65159.rs:5:20
    |
 LL | async fn copy() -> Result<()>
diff --git a/tests/ui/async-await/issues/issue-72312.stderr b/tests/ui/async-await/issues/issue-72312.stderr
index aa947b69003..679272858bd 100644
--- a/tests/ui/async-await/issues/issue-72312.stderr
+++ b/tests/ui/async-await/issues/issue-72312.stderr
@@ -1,10 +1,10 @@
-error[E0521]: borrowed data escapes outside of associated function
+error[E0521]: borrowed data escapes outside of method
   --> $DIR/issue-72312.rs:12:9
    |
 LL |       pub async fn start(&self) {
    |                          -----
    |                          |
-   |                          `self` is a reference that is only valid in the associated function body
+   |                          `self` is a reference that is only valid in the method body
    |                          let's call the lifetime of this reference `'1`
 ...
 LL | /         require_static(async move {
@@ -15,7 +15,7 @@ LL | |             &self;
 LL | |         });
    | |          ^
    | |          |
-   | |__________`self` escapes the associated function body here
+   | |__________`self` escapes the method body here
    |            argument requires that `'1` must outlive `'static`
 
 error: aborting due to previous error
diff --git a/tests/ui/attributes/invalid_macro_export_argument.rs b/tests/ui/attributes/invalid_macro_export_argument.rs
new file mode 100644
index 00000000000..85d009f11a6
--- /dev/null
+++ b/tests/ui/attributes/invalid_macro_export_argument.rs
@@ -0,0 +1,26 @@
+// check-pass
+#[macro_export(hello, world)] //~ WARN `#[macro_export]` can only take 1 or 0 arguments
+macro_rules! a {
+    () => ()
+}
+
+#[macro_export(not_local_inner_macros)] //~ WARN `not_local_inner_macros` isn't a valid `#[macro_export]` argument
+macro_rules! b {
+    () => ()
+}
+
+#[macro_export]
+macro_rules! c {
+    () => ()
+}
+#[macro_export(local_inner_macros)]
+macro_rules! d {
+    () => ()
+}
+
+#[macro_export()]
+macro_rules! e {
+    () => ()
+}
+
+fn main() {}
diff --git a/tests/ui/attributes/invalid_macro_export_argument.stderr b/tests/ui/attributes/invalid_macro_export_argument.stderr
new file mode 100644
index 00000000000..a4e17642c2a
--- /dev/null
+++ b/tests/ui/attributes/invalid_macro_export_argument.stderr
@@ -0,0 +1,16 @@
+warning: `#[macro_export]` can only take 1 or 0 arguments
+  --> $DIR/invalid_macro_export_argument.rs:2:1
+   |
+LL | #[macro_export(hello, world)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(invalid_macro_export_arguments)]` on by default
+
+warning: `not_local_inner_macros` isn't a valid `#[macro_export]` argument
+  --> $DIR/invalid_macro_export_argument.rs:7:16
+   |
+LL | #[macro_export(not_local_inner_macros)]
+   |                ^^^^^^^^^^^^^^^^^^^^^^
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/auto-traits/auto-trait-validation.stderr b/tests/ui/auto-traits/auto-trait-validation.stderr
index 2c380e5b09a..89b63d23d4c 100644
--- a/tests/ui/auto-traits/auto-trait-validation.stderr
+++ b/tests/ui/auto-traits/auto-trait-validation.stderr
@@ -12,7 +12,7 @@ error[E0568]: auto traits cannot have super traits or lifetime bounds
 LL | auto trait Bound : Copy {}
    |            -----^^^^^^^ help: remove the super traits or lifetime bounds
    |            |
-   |            auto trait cannot have super traits or lifetime bounds
+   |            auto traits cannot have super traits or lifetime bounds
 
 error[E0568]: auto traits cannot have super traits or lifetime bounds
   --> $DIR/auto-trait-validation.rs:9:25
@@ -20,7 +20,7 @@ error[E0568]: auto traits cannot have super traits or lifetime bounds
 LL | auto trait LifetimeBound : 'static {}
    |            -------------^^^^^^^^^^ help: remove the super traits or lifetime bounds
    |            |
-   |            auto trait cannot have super traits or lifetime bounds
+   |            auto traits cannot have super traits or lifetime bounds
 
 error[E0380]: auto traits cannot have associated items
   --> $DIR/auto-trait-validation.rs:11:25
@@ -29,7 +29,7 @@ LL | auto trait MyTrait { fn foo() {} }
    |            -------   ---^^^-----
    |            |         |
    |            |         help: remove these associated items
-   |            auto trait cannot have associated items
+   |            auto traits cannot have associated items
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/auto-traits/issue-23080-2.stderr b/tests/ui/auto-traits/issue-23080-2.stderr
index 267a712f62f..fed485612da 100644
--- a/tests/ui/auto-traits/issue-23080-2.stderr
+++ b/tests/ui/auto-traits/issue-23080-2.stderr
@@ -2,7 +2,7 @@ error[E0380]: auto traits cannot have associated items
   --> $DIR/issue-23080-2.rs:5:10
    |
 LL | unsafe auto trait Trait {
-   |                   ----- auto trait cannot have associated items
+   |                   ----- auto traits cannot have associated items
 LL |     type Output;
    |     -----^^^^^^- help: remove these associated items
 
diff --git a/tests/ui/auto-traits/issue-23080.stderr b/tests/ui/auto-traits/issue-23080.stderr
index c1b16b2f403..f5d607298b7 100644
--- a/tests/ui/auto-traits/issue-23080.stderr
+++ b/tests/ui/auto-traits/issue-23080.stderr
@@ -2,7 +2,7 @@ error[E0380]: auto traits cannot have associated items
   --> $DIR/issue-23080.rs:5:8
    |
 LL |   unsafe auto trait Trait {
-   |                     ----- auto trait cannot have associated items
+   |                     ----- auto traits cannot have associated items
 LL |       fn method(&self) {
    |  _____-  ^^^^^^
 LL | |         println!("Hello");
diff --git a/tests/ui/auto-traits/issue-84075.stderr b/tests/ui/auto-traits/issue-84075.stderr
index 02dca598ec2..6fbdc669b6f 100644
--- a/tests/ui/auto-traits/issue-84075.stderr
+++ b/tests/ui/auto-traits/issue-84075.stderr
@@ -4,7 +4,7 @@ error[E0568]: auto traits cannot have super traits or lifetime bounds
 LL | auto trait Magic where Self: Copy {}
    |            ----- ^^^^^^^^^^^^^^^^ help: remove the super traits or lifetime bounds
    |            |
-   |            auto trait cannot have super traits or lifetime bounds
+   |            auto traits cannot have super traits or lifetime bounds
 
 error: aborting due to previous error
 
diff --git a/tests/ui/auto-traits/str-contains-slice-conceptually.rs b/tests/ui/auto-traits/str-contains-slice-conceptually.rs
new file mode 100644
index 00000000000..6a16fdcf284
--- /dev/null
+++ b/tests/ui/auto-traits/str-contains-slice-conceptually.rs
@@ -0,0 +1,13 @@
+#![feature(negative_impls)]
+#![feature(auto_traits)]
+
+auto trait AutoTrait {}
+
+impl<T> !AutoTrait for [T] {}
+
+fn needs_auto_trait<T: AutoTrait + ?Sized>() {}
+
+fn main() {
+  needs_auto_trait::<str>();
+  //~^ ERROR the trait bound `[u8]: AutoTrait` is not satisfied in `str`
+}
diff --git a/tests/ui/auto-traits/str-contains-slice-conceptually.stderr b/tests/ui/auto-traits/str-contains-slice-conceptually.stderr
new file mode 100644
index 00000000000..1cf16cebddd
--- /dev/null
+++ b/tests/ui/auto-traits/str-contains-slice-conceptually.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the trait bound `[u8]: AutoTrait` is not satisfied in `str`
+  --> $DIR/str-contains-slice-conceptually.rs:11:22
+   |
+LL |   needs_auto_trait::<str>();
+   |                      ^^^ within `str`, the trait `AutoTrait` is not implemented for `[u8]`
+   |
+   = note: `str` is considered to contain a `[u8]` slice for auto trait purposes
+note: required by a bound in `needs_auto_trait`
+  --> $DIR/str-contains-slice-conceptually.rs:8:24
+   |
+LL | fn needs_auto_trait<T: AutoTrait + ?Sized>() {}
+   |                        ^^^^^^^^^ required by this bound in `needs_auto_trait`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr b/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr
index 4827916fa5c..547b4bb5448 100644
--- a/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr
+++ b/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr
@@ -4,7 +4,7 @@ error[E0568]: auto traits cannot have super traits or lifetime bounds
 LL | auto trait Magic : Sized where Option<Self> : Magic {}
    |            -----^^^^^^^^ help: remove the super traits or lifetime bounds
    |            |
-   |            auto trait cannot have super traits or lifetime bounds
+   |            auto traits cannot have super traits or lifetime bounds
 
 error[E0568]: auto traits cannot have super traits or lifetime bounds
   --> $DIR/typeck-auto-trait-no-supertraits-2.rs:4:26
@@ -12,7 +12,7 @@ error[E0568]: auto traits cannot have super traits or lifetime bounds
 LL | auto trait Magic : Sized where Option<Self> : Magic {}
    |            -----         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the super traits or lifetime bounds
    |            |
-   |            auto trait cannot have super traits or lifetime bounds
+   |            auto traits cannot have super traits or lifetime bounds
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr b/tests/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr
index d7716f4b61f..80f07410381 100644
--- a/tests/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr
+++ b/tests/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr
@@ -4,7 +4,7 @@ error[E0568]: auto traits cannot have super traits or lifetime bounds
 LL | auto trait Magic: Copy {}
    |            -----^^^^^^ help: remove the super traits or lifetime bounds
    |            |
-   |            auto trait cannot have super traits or lifetime bounds
+   |            auto traits cannot have super traits or lifetime bounds
 
 error: aborting due to previous error
 
diff --git a/tests/ui/borrowck/issue-103624.rs b/tests/ui/borrowck/issue-103624.rs
index f1fa95f9246..d95a40bd4a0 100644
--- a/tests/ui/borrowck/issue-103624.rs
+++ b/tests/ui/borrowck/issue-103624.rs
@@ -12,7 +12,7 @@ impl StructA {
     async fn foo(&self) {
         let bar = self.b.bar().await;
         spawn_blocking(move || {
-            //~^ ERROR borrowed data escapes outside of associated function
+            //~^ ERROR borrowed data escapes outside of method
             self.b;
             //~^ ERROR cannot move out of `self.b`, as `self` is a captured variable in an `Fn` closure
         })
diff --git a/tests/ui/borrowck/issue-103624.stderr b/tests/ui/borrowck/issue-103624.stderr
index e6a35dd8801..7a281e8aa30 100644
--- a/tests/ui/borrowck/issue-103624.stderr
+++ b/tests/ui/borrowck/issue-103624.stderr
@@ -10,13 +10,13 @@ LL |
 LL |             self.b;
    |             ^^^^^^ move occurs because `self.b` has type `StructB`, which does not implement the `Copy` trait
 
-error[E0521]: borrowed data escapes outside of associated function
+error[E0521]: borrowed data escapes outside of method
   --> $DIR/issue-103624.rs:14:9
    |
 LL |       async fn foo(&self) {
    |                    -----
    |                    |
-   |                    `self` is a reference that is only valid in the associated function body
+   |                    `self` is a reference that is only valid in the method body
    |                    let's call the lifetime of this reference `'1`
 LL |           let bar = self.b.bar().await;
 LL | /         spawn_blocking(move || {
@@ -26,7 +26,7 @@ LL | |
 LL | |         })
    | |          ^
    | |          |
-   | |__________`self` escapes the associated function body here
+   | |__________`self` escapes the method body here
    |            argument requires that `'1` must outlive `'static`
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs b/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs
index dd0320bc53b..d067ff44704 100644
--- a/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs
+++ b/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs
@@ -14,8 +14,8 @@ impl MarketMultiplier {
 }
 
 async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_> {
-    //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
-    //~^^ ERROR this struct takes 1 generic argument but 0 generic arguments were supplied
+    //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+    //~^^ ERROR struct takes 1 generic argument but 0 generic arguments were supplied
     LockedMarket(generator.lock().unwrap().buy())
 }
 
diff --git a/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr b/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr
index d2b927fb664..73e0aaf1e45 100644
--- a/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr
+++ b/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/issue-82126-mismatched-subst-and-hir.rs:16:59
    |
 LL | async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_> {
@@ -12,7 +12,7 @@ note: struct defined here, with 0 lifetime parameters
 LL | struct LockedMarket<T>(T);
    |        ^^^^^^^^^^^^
 
-error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/issue-82126-mismatched-subst-and-hir.rs:16:59
    |
 LL | async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_> {
diff --git a/tests/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr b/tests/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr
index 8dccf929b2b..c5089295063 100644
--- a/tests/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr
+++ b/tests/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr
@@ -12,7 +12,7 @@ note: required by a bound in `with_closure`
   --> $DIR/expect-infer-var-appearing-twice.rs:2:14
    |
 LL | fn with_closure<F, A>(_: F)
-   |    ------------ required by a bound in this
+   |    ------------ required by a bound in this function
 LL |     where F: FnOnce(A, A)
    |              ^^^^^^^^^^^^ required by this bound in `with_closure`
 
diff --git a/tests/ui/const-generics/defaults/wfness.stderr b/tests/ui/const-generics/defaults/wfness.stderr
index 25038f830be..bd9bfcd7dad 100644
--- a/tests/ui/const-generics/defaults/wfness.stderr
+++ b/tests/ui/const-generics/defaults/wfness.stderr
@@ -23,7 +23,7 @@ note: required by a bound in `WhereClause`
   --> $DIR/wfness.rs:8:9
    |
 LL | struct WhereClause<const N: u8 = 2>
-   |        ----------- required by a bound in this
+   |        ----------- required by a bound in this struct
 LL | where
 LL |     (): Trait<N>;
    |         ^^^^^^^^ required by this bound in `WhereClause`
diff --git a/tests/ui/const-generics/ensure_is_evaluatable.stderr b/tests/ui/const-generics/ensure_is_evaluatable.stderr
index bf6c35ad8fd..ab2871ff281 100644
--- a/tests/ui/const-generics/ensure_is_evaluatable.stderr
+++ b/tests/ui/const-generics/ensure_is_evaluatable.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `bar`
   --> $DIR/ensure_is_evaluatable.rs:15:10
    |
 LL | fn bar<const N: usize>() -> [(); N]
-   |    --- required by a bound in this
+   |    --- required by a bound in this function
 LL | where
 LL |     [(); N + 1]:,
    |          ^^^^^ required by this bound in `bar`
diff --git a/tests/ui/const-generics/fn_with_two_const_inputs.stderr b/tests/ui/const-generics/fn_with_two_const_inputs.stderr
index 614e7e0d2fc..c124010aab0 100644
--- a/tests/ui/const-generics/fn_with_two_const_inputs.stderr
+++ b/tests/ui/const-generics/fn_with_two_const_inputs.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `bar`
   --> $DIR/fn_with_two_const_inputs.rs:18:10
    |
 LL | fn bar<const N: usize>() -> [(); N]
-   |    --- required by a bound in this
+   |    --- required by a bound in this function
 LL | where
 LL |     [(); N + 1]:,
    |          ^^^^^ required by this bound in `bar`
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-102768.rs b/tests/ui/const-generics/generic_const_exprs/issue-102768.rs
index 7aea0d30d1a..18a9b53cf76 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-102768.rs
+++ b/tests/ui/const-generics/generic_const_exprs/issue-102768.rs
@@ -7,8 +7,8 @@ trait X {
 
 const _: () = {
     fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {}
-    //~^ ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments
-    //~| ERROR this associated type takes 0 generic arguments but 1 generic argument
+    //~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
+    //~| ERROR associated type takes 0 generic arguments but 1 generic argument
 };
 
 fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr b/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr
index 8278edabe3a..175d54e4184 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
   --> $DIR/issue-102768.rs:9:30
    |
 LL |     fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {}
@@ -14,7 +14,7 @@ help: add missing lifetime argument
 LL |     fn f2<'a>(arg: Box<dyn X<Y<'_, 1> = &'a ()>>) {}
    |                                +++
 
-error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-102768.rs:9:30
    |
 LL |     fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr b/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr
index 0be4c43daac..827dd59d9ad 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/issue-105608.rs:13:22
    |
 LL |     Combination::<0>.and::<_>().and::<_>();
-   |                      ^^^ cannot infer type of the type parameter `M` declared on the associated function `and`
+   |                      ^^^ cannot infer type of the type parameter `M` declared on the method `and`
    |
 help: consider specifying the generic argument
    |
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr b/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr
index f2fddfbfbb5..996b75493e6 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `Arr`
   --> $DIR/issue-72819-generic-in-const-eval.rs:8:39
    |
 LL | struct Arr<const N: usize>
-   |        --- required by a bound in this
+   |        --- required by a bound in this struct
 LL | where Assert::<{N < usize::MAX / 2}>: IsTrue,
    |                                       ^^^^^^ required by this bound in `Arr`
 
@@ -26,7 +26,7 @@ note: required by a bound in `Arr`
   --> $DIR/issue-72819-generic-in-const-eval.rs:8:39
    |
 LL | struct Arr<const N: usize>
-   |        --- required by a bound in this
+   |        --- required by a bound in this struct
 LL | where Assert::<{N < usize::MAX / 2}>: IsTrue,
    |                                       ^^^^^^ required by this bound in `Arr`
 
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-76595.stderr b/tests/ui/const-generics/generic_const_exprs/issue-76595.stderr
index c587a7e153f..302da59651c 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-76595.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-76595.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: function takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-76595.rs:15:5
    |
 LL |     test::<2>();
diff --git a/tests/ui/const-generics/generic_const_exprs/obligation-cause.stderr b/tests/ui/const-generics/generic_const_exprs/obligation-cause.stderr
index a253ec676f7..63e6fcc8e11 100644
--- a/tests/ui/const-generics/generic_const_exprs/obligation-cause.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/obligation-cause.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `g`
   --> $DIR/obligation-cause.rs:13:44
    |
 LL | fn g<T>()
-   |    - required by a bound in this
+   |    - required by a bound in this function
 ...
 LL |     Is<{ std::mem::size_of::<T>() == 0 }>: True,
    |                                            ^^^^ required by this bound in `g`
diff --git a/tests/ui/const-generics/incorrect-number-of-const-args.stderr b/tests/ui/const-generics/incorrect-number-of-const-args.stderr
index a845454f762..01ac4e69a05 100644
--- a/tests/ui/const-generics/incorrect-number-of-const-args.stderr
+++ b/tests/ui/const-generics/incorrect-number-of-const-args.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: function takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/incorrect-number-of-const-args.rs:6:5
    |
 LL |     foo::<0>();
@@ -16,7 +16,7 @@ help: add missing generic argument
 LL |     foo::<0, Y>();
    |            +++
 
-error[E0107]: this function takes 2 generic arguments but 3 generic arguments were supplied
+error[E0107]: function takes 2 generic arguments but 3 generic arguments were supplied
   --> $DIR/incorrect-number-of-const-args.rs:9:5
    |
 LL |     foo::<0, 0, 0>();
diff --git a/tests/ui/const-generics/infer/method-chain.stderr b/tests/ui/const-generics/infer/method-chain.stderr
index ff6da535bd2..f527ee6e4f5 100644
--- a/tests/ui/const-generics/infer/method-chain.stderr
+++ b/tests/ui/const-generics/infer/method-chain.stderr
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/method-chain.rs:15:33
    |
 LL |     Foo.bar().bar().bar().bar().baz();
-   |                                 ^^^ cannot infer the value of the const parameter `N` declared on the associated function `baz`
+   |                                 ^^^ cannot infer the value of the const parameter `N` declared on the method `baz`
    |
 help: consider specifying the generic argument
    |
diff --git a/tests/ui/const-generics/infer/uninferred-consts.stderr b/tests/ui/const-generics/infer/uninferred-consts.stderr
index 3980ecea863..20daf45706b 100644
--- a/tests/ui/const-generics/infer/uninferred-consts.stderr
+++ b/tests/ui/const-generics/infer/uninferred-consts.stderr
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/uninferred-consts.rs:9:9
    |
 LL |     Foo.foo();
-   |         ^^^ cannot infer the value of the const parameter `A` declared on the associated function `foo`
+   |         ^^^ cannot infer the value of the const parameter `A` declared on the method `foo`
    |
 help: consider specifying the generic arguments
    |
diff --git a/tests/ui/const-generics/invalid-const-arg-for-type-param.rs b/tests/ui/const-generics/invalid-const-arg-for-type-param.rs
index 7d4dc98f396..bf10f471dc5 100644
--- a/tests/ui/const-generics/invalid-const-arg-for-type-param.rs
+++ b/tests/ui/const-generics/invalid-const-arg-for-type-param.rs
@@ -4,11 +4,11 @@ struct S;
 
 fn main() {
     let _: u32 = 5i32.try_into::<32>().unwrap();
-    //~^ ERROR this associated function takes
+    //~^ ERROR method takes
 
     S.f::<0>();
     //~^ ERROR no method named `f`
 
     S::<0>;
-    //~^ ERROR this struct takes 0
+    //~^ ERROR struct takes 0
 }
diff --git a/tests/ui/const-generics/invalid-const-arg-for-type-param.stderr b/tests/ui/const-generics/invalid-const-arg-for-type-param.stderr
index 8c76ca69029..4a649d8a7e8 100644
--- a/tests/ui/const-generics/invalid-const-arg-for-type-param.stderr
+++ b/tests/ui/const-generics/invalid-const-arg-for-type-param.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/invalid-const-arg-for-type-param.rs:6:23
    |
 LL |     let _: u32 = 5i32.try_into::<32>().unwrap();
@@ -23,7 +23,7 @@ LL | struct S;
 LL |     S.f::<0>();
    |       ^ method not found in `S`
 
-error[E0107]: this struct takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/invalid-const-arg-for-type-param.rs:12:5
    |
 LL |     S::<0>;
diff --git a/tests/ui/const-generics/invalid-constant-in-args.rs b/tests/ui/const-generics/invalid-constant-in-args.rs
index 7419d4a25ce..fd259197d29 100644
--- a/tests/ui/const-generics/invalid-constant-in-args.rs
+++ b/tests/ui/const-generics/invalid-constant-in-args.rs
@@ -2,5 +2,5 @@ use std::cell::Cell;
 
 fn main() {
     let _: Cell<&str, "a"> = Cell::new("");
-    //~^ ERROR this struct takes 1 generic argument but 2 generic arguments were supplied
+    //~^ ERROR struct takes 1 generic argument but 2 generic arguments were supplied
 }
diff --git a/tests/ui/const-generics/invalid-constant-in-args.stderr b/tests/ui/const-generics/invalid-constant-in-args.stderr
index 993b63518e4..2545cc6f396 100644
--- a/tests/ui/const-generics/invalid-constant-in-args.stderr
+++ b/tests/ui/const-generics/invalid-constant-in-args.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/invalid-constant-in-args.rs:4:12
    |
 LL |     let _: Cell<&str, "a"> = Cell::new("");
diff --git a/tests/ui/const-generics/issues/issue-67185-2.stderr b/tests/ui/const-generics/issues/issue-67185-2.stderr
index c7be8e14a10..032b0c41047 100644
--- a/tests/ui/const-generics/issues/issue-67185-2.stderr
+++ b/tests/ui/const-generics/issues/issue-67185-2.stderr
@@ -35,7 +35,7 @@ note: required by a bound in `Foo`
   --> $DIR/issue-67185-2.rs:15:25
    |
 LL | trait Foo
-   |       --- required by a bound in this
+   |       --- required by a bound in this trait
 ...
 LL |     <u8 as Baz>::Quaks: Bar,
    |                         ^^^ required by this bound in `Foo`
@@ -53,7 +53,7 @@ note: required by a bound in `Foo`
   --> $DIR/issue-67185-2.rs:14:30
    |
 LL | trait Foo
-   |       --- required by a bound in this
+   |       --- required by a bound in this trait
 LL | where
 LL |     [<u8 as Baz>::Quaks; 2]: Bar,
    |                              ^^^ required by this bound in `Foo`
@@ -71,7 +71,7 @@ note: required by a bound in `Foo`
   --> $DIR/issue-67185-2.rs:14:30
    |
 LL | trait Foo
-   |       --- required by a bound in this
+   |       --- required by a bound in this trait
 LL | where
 LL |     [<u8 as Baz>::Quaks; 2]: Bar,
    |                              ^^^ required by this bound in `Foo`
@@ -89,7 +89,7 @@ note: required by a bound in `Foo`
   --> $DIR/issue-67185-2.rs:15:25
    |
 LL | trait Foo
-   |       --- required by a bound in this
+   |       --- required by a bound in this trait
 ...
 LL |     <u8 as Baz>::Quaks: Bar,
    |                         ^^^ required by this bound in `Foo`
diff --git a/tests/ui/const-generics/issues/issue-73260.stderr b/tests/ui/const-generics/issues/issue-73260.stderr
index f9ff0f28d51..c56b45cc8fa 100644
--- a/tests/ui/const-generics/issues/issue-73260.stderr
+++ b/tests/ui/const-generics/issues/issue-73260.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `Arr`
   --> $DIR/issue-73260.rs:5:37
    |
 LL | struct Arr<const N: usize>
-   |        --- required by a bound in this
+   |        --- required by a bound in this struct
 LL | where
 LL |     Assert::<{N < usize::MAX / 2}>: IsTrue,
    |                                     ^^^^^^ required by this bound in `Arr`
@@ -27,7 +27,7 @@ note: required by a bound in `Arr`
   --> $DIR/issue-73260.rs:5:37
    |
 LL | struct Arr<const N: usize>
-   |        --- required by a bound in this
+   |        --- required by a bound in this struct
 LL | where
 LL |     Assert::<{N < usize::MAX / 2}>: IsTrue,
    |                                     ^^^^^^ required by this bound in `Arr`
diff --git a/tests/ui/const-generics/issues/issue-79674.stderr b/tests/ui/const-generics/issues/issue-79674.stderr
index 02b48b55f8b..ba7fd2ca3cc 100644
--- a/tests/ui/const-generics/issues/issue-79674.stderr
+++ b/tests/ui/const-generics/issues/issue-79674.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `requires_distinct`
   --> $DIR/issue-79674.rs:23:37
    |
 LL | fn requires_distinct<A, B>(_a: A, _b: B) where
-   |    ----------------- required by a bound in this
+   |    ----------------- required by a bound in this function
 LL |     A: MiniTypeId, B: MiniTypeId,
 LL |     Lift<{is_same_type::<A, B>()}>: IsFalse {}
    |                                     ^^^^^^^ required by this bound in `requires_distinct`
diff --git a/tests/ui/const-generics/issues/issue-86530.stderr b/tests/ui/const-generics/issues/issue-86530.stderr
index c63857b2314..620ed4f0fb2 100644
--- a/tests/ui/const-generics/issues/issue-86530.stderr
+++ b/tests/ui/const-generics/issues/issue-86530.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `z`
   --> $DIR/issue-86530.rs:10:8
    |
 LL | fn z<T>(t: T)
-   |    - required by a bound in this
+   |    - required by a bound in this function
 LL | where
 LL |     T: X,
    |        ^ required by this bound in `z`
diff --git a/tests/ui/const-generics/issues/issue-87493.rs b/tests/ui/const-generics/issues/issue-87493.rs
index d8599ab22a3..80472e6bd9c 100644
--- a/tests/ui/const-generics/issues/issue-87493.rs
+++ b/tests/ui/const-generics/issues/issue-87493.rs
@@ -7,7 +7,7 @@ where
     S: MyTrait,
     T: MyTrait<Assoc == S::Assoc>,
     //~^ ERROR: expected one of `,` or `>`, found `==`
-    //~| ERROR: this trait takes 0 generic arguments but 1 generic argument was supplied
+    //~| ERROR: trait takes 0 generic arguments but 1 generic argument was supplied
 {
 }
 
diff --git a/tests/ui/const-generics/issues/issue-87493.stderr b/tests/ui/const-generics/issues/issue-87493.stderr
index 653afae2191..73bd6ed73e6 100644
--- a/tests/ui/const-generics/issues/issue-87493.stderr
+++ b/tests/ui/const-generics/issues/issue-87493.stderr
@@ -9,7 +9,7 @@ help: if you meant to use an associated type binding, replace `==` with `=`
 LL |     T: MyTrait<Assoc = S::Assoc>,
    |                      ~
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-87493.rs:8:8
    |
 LL |     T: MyTrait<Assoc == S::Assoc>,
diff --git a/tests/ui/const-generics/occurs-check/unused-substs-1.stderr b/tests/ui/const-generics/occurs-check/unused-substs-1.stderr
index a3c011d927b..51ef354e3ed 100644
--- a/tests/ui/const-generics/occurs-check/unused-substs-1.stderr
+++ b/tests/ui/const-generics/occurs-check/unused-substs-1.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `A`
   --> $DIR/unused-substs-1.rs:9:11
    |
 LL | struct A<const N: usize>
-   |        - required by a bound in this
+   |        - required by a bound in this unit struct
 LL | where
 LL |     A<N>: Bar<N>;
    |           ^^^^^^ required by this bound in `A`
diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs
index b126b24853f..79743abe409 100644
--- a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs
+++ b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs
@@ -7,7 +7,7 @@ struct Bar;
 const T: usize = 42;
 
 impl Foo<N = 3> for Bar {
-//~^ ERROR this trait takes 1 generic argument but 0 generic arguments were supplied
+//~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied
 //~| ERROR associated type bindings are not allowed here
 //~| ERROR associated const equality is incomplete
     fn do_x(&self) -> [u8; 3] {
diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr
index acfdde8e1a0..4f4e1aa3a04 100644
--- a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr
+++ b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr
@@ -7,7 +7,7 @@ LL | impl Foo<N = 3> for Bar {
    = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
    = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/issue-89013-no-kw.rs:9:6
    |
 LL | impl Foo<N = 3> for Bar {
diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013.rs b/tests/ui/const-generics/parser-error-recovery/issue-89013.rs
index 9431779faf8..335d0d94e83 100644
--- a/tests/ui/const-generics/parser-error-recovery/issue-89013.rs
+++ b/tests/ui/const-generics/parser-error-recovery/issue-89013.rs
@@ -8,7 +8,7 @@ const T: usize = 42;
 
 impl Foo<N = const 3> for Bar {
 //~^ ERROR expected lifetime, type, or constant, found keyword `const`
-//~| ERROR this trait takes 1 generic
+//~| ERROR trait takes 1 generic
 //~| ERROR associated type bindings are not allowed here
 //~| ERROR associated const equality is incomplete
     fn do_x(&self) -> [u8; 3] {
diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr b/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr
index 583749a8573..3d2b98feb39 100644
--- a/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr
+++ b/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr
@@ -19,7 +19,7 @@ LL | impl Foo<N = const 3> for Bar {
    = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
    = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/issue-89013.rs:9:6
    |
 LL | impl Foo<N = const 3> for Bar {
diff --git a/tests/ui/const-generics/unify_with_nested_expr.stderr b/tests/ui/const-generics/unify_with_nested_expr.stderr
index 8bab0dff7f2..d4d78b59627 100644
--- a/tests/ui/const-generics/unify_with_nested_expr.stderr
+++ b/tests/ui/const-generics/unify_with_nested_expr.stderr
@@ -8,7 +8,7 @@ note: required by a bound in `bar`
   --> $DIR/unify_with_nested_expr.rs:14:10
    |
 LL | fn bar<const N: usize>()
-   |    --- required by a bound in this
+   |    --- required by a bound in this function
 LL | where
 LL |     [(); N + 1]:,
    |          ^^^^^ required by this bound in `bar`
diff --git a/tests/ui/constructor-lifetime-args.rs b/tests/ui/constructor-lifetime-args.rs
index a824a44c9c2..f5802e7d8b1 100644
--- a/tests/ui/constructor-lifetime-args.rs
+++ b/tests/ui/constructor-lifetime-args.rs
@@ -15,12 +15,12 @@ enum E<'a, 'b> {
 fn main() {
     S(&0, &0); // OK
     S::<'static>(&0, &0);
-    //~^ ERROR this struct takes 2 lifetime arguments
+    //~^ ERROR struct takes 2 lifetime arguments
     S::<'static, 'static, 'static>(&0, &0);
-    //~^ ERROR this struct takes 2 lifetime arguments
+    //~^ ERROR struct takes 2 lifetime arguments
     E::V(&0); // OK
     E::V::<'static>(&0);
-    //~^ ERROR this enum takes 2 lifetime arguments
+    //~^ ERROR enum takes 2 lifetime arguments
     E::V::<'static, 'static, 'static>(&0);
-    //~^ ERROR this enum takes 2 lifetime arguments
+    //~^ ERROR enum takes 2 lifetime arguments
 }
diff --git a/tests/ui/constructor-lifetime-args.stderr b/tests/ui/constructor-lifetime-args.stderr
index bc1141b16c5..a18123fe19c 100644
--- a/tests/ui/constructor-lifetime-args.stderr
+++ b/tests/ui/constructor-lifetime-args.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/constructor-lifetime-args.rs:17:5
    |
 LL |     S::<'static>(&0, &0);
@@ -16,7 +16,7 @@ help: add missing lifetime argument
 LL |     S::<'static, 'static>(&0, &0);
    |                +++++++++
 
-error[E0107]: this struct takes 2 lifetime arguments but 3 lifetime arguments were supplied
+error[E0107]: struct takes 2 lifetime arguments but 3 lifetime arguments were supplied
   --> $DIR/constructor-lifetime-args.rs:19:5
    |
 LL |     S::<'static, 'static, 'static>(&0, &0);
@@ -30,7 +30,7 @@ note: struct defined here, with 2 lifetime parameters: `'a`, `'b`
 LL | struct S<'a, 'b>(&'a u8, &'b u8);
    |        ^ --  --
 
-error[E0107]: this enum takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: enum takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/constructor-lifetime-args.rs:22:8
    |
 LL |     E::V::<'static>(&0);
@@ -48,7 +48,7 @@ help: add missing lifetime argument
 LL |     E::V::<'static, 'static>(&0);
    |                   +++++++++
 
-error[E0107]: this enum takes 2 lifetime arguments but 3 lifetime arguments were supplied
+error[E0107]: enum takes 2 lifetime arguments but 3 lifetime arguments were supplied
   --> $DIR/constructor-lifetime-args.rs:24:8
    |
 LL |     E::V::<'static, 'static, 'static>(&0);
diff --git a/tests/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr b/tests/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr
index 9710bf476ec..69fb1a59d4f 100644
--- a/tests/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr
+++ b/tests/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr
@@ -2,10 +2,7 @@ warning: the type `!` does not permit zero-initialization
   --> $DIR/validate_uninhabited_zsts.rs:4:14
    |
 LL |     unsafe { std::mem::transmute(()) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^
-   |              |
-   |              this code causes undefined behavior when executed
-   |              help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |              ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
    |
    = note: the `!` type has no valid value
    = note: `#[warn(invalid_value)]` on by default
@@ -40,10 +37,7 @@ warning: the type `empty::Empty` does not permit zero-initialization
   --> $DIR/validate_uninhabited_zsts.rs:21:42
    |
 LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^
-   |                                          |
-   |                                          this code causes undefined behavior when executed
-   |                                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
    |
 note: in this struct field
   --> $DIR/validate_uninhabited_zsts.rs:16:22
diff --git a/tests/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr b/tests/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr
index 9710bf476ec..69fb1a59d4f 100644
--- a/tests/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr
+++ b/tests/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr
@@ -2,10 +2,7 @@ warning: the type `!` does not permit zero-initialization
   --> $DIR/validate_uninhabited_zsts.rs:4:14
    |
 LL |     unsafe { std::mem::transmute(()) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^
-   |              |
-   |              this code causes undefined behavior when executed
-   |              help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |              ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
    |
    = note: the `!` type has no valid value
    = note: `#[warn(invalid_value)]` on by default
@@ -40,10 +37,7 @@ warning: the type `empty::Empty` does not permit zero-initialization
   --> $DIR/validate_uninhabited_zsts.rs:21:42
    |
 LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^
-   |                                          |
-   |                                          this code causes undefined behavior when executed
-   |                                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
    |
 note: in this struct field
   --> $DIR/validate_uninhabited_zsts.rs:16:22
diff --git a/tests/ui/consts/ct-var-in-collect_all_mismatches.stderr b/tests/ui/consts/ct-var-in-collect_all_mismatches.stderr
index 43fba2573ff..fa20077da7e 100644
--- a/tests/ui/consts/ct-var-in-collect_all_mismatches.stderr
+++ b/tests/ui/consts/ct-var-in-collect_all_mismatches.stderr
@@ -8,7 +8,7 @@ note: required by a bound in `Foo::<T, N>::unsatisfied`
   --> $DIR/ct-var-in-collect_all_mismatches.rs:15:12
    |
 LL |     fn unsatisfied(self)
-   |        ----------- required by a bound in this
+   |        ----------- required by a bound in this associated function
 LL |     where
 LL |         T: Bar<N>,
    |            ^^^^^^ required by this bound in `Foo::<T, N>::unsatisfied`
diff --git a/tests/ui/consts/gate-do-not-const-check.rs b/tests/ui/consts/gate-do-not-const-check.rs
new file mode 100644
index 00000000000..be7e70dfabb
--- /dev/null
+++ b/tests/ui/consts/gate-do-not-const-check.rs
@@ -0,0 +1,5 @@
+#[rustc_do_not_const_check]
+//~^ ERROR this is an internal attribute that will never be stable
+const fn foo() {}
+
+fn main() {}
diff --git a/tests/ui/consts/gate-do-not-const-check.stderr b/tests/ui/consts/gate-do-not-const-check.stderr
new file mode 100644
index 00000000000..3bb1360166a
--- /dev/null
+++ b/tests/ui/consts/gate-do-not-const-check.stderr
@@ -0,0 +1,11 @@
+error[E0658]: this is an internal attribute that will never be stable
+  --> $DIR/gate-do-not-const-check.rs:1:1
+   |
+LL | #[rustc_do_not_const_check]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/deprecation/deprecation-lint.rs b/tests/ui/deprecation/deprecation-lint.rs
index 0417e952eb7..83056feaf27 100644
--- a/tests/ui/deprecation/deprecation-lint.rs
+++ b/tests/ui/deprecation/deprecation-lint.rs
@@ -14,22 +14,22 @@ mod cross_crate {
         let foo = MethodTester;
 
         deprecated(); //~ ERROR use of deprecated function `deprecation_lint::deprecated`
-        foo.method_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`
-        Foo::method_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`
-        <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`
-        foo.trait_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`
-        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`
-        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`
-        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`
+        foo.method_deprecated(); //~ ERROR use of deprecated method `deprecation_lint::MethodTester::method_deprecated`
+        Foo::method_deprecated(&foo); //~ ERROR use of deprecated method `deprecation_lint::MethodTester::method_deprecated`
+        <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated method `deprecation_lint::MethodTester::method_deprecated`
+        foo.trait_deprecated(); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated`
+        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated`
+        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated`
+        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated`
 
         deprecated_text(); //~ ERROR use of deprecated function `deprecation_lint::deprecated_text`: text
-        foo.method_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text
-        Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text
-        <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text
-        foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
-        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
-        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
-        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
+        foo.method_deprecated_text(); //~ ERROR use of deprecated method `deprecation_lint::MethodTester::method_deprecated_text`: text
+        Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated method `deprecation_lint::MethodTester::method_deprecated_text`: text
+        <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated method `deprecation_lint::MethodTester::method_deprecated_text`: text
+        foo.trait_deprecated_text(); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text
+        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text
+        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text
 
         let _ = DeprecatedStruct { //~ ERROR use of deprecated struct `deprecation_lint::DeprecatedStruct`: text
             i: 0 //~ ERROR use of deprecated field `deprecation_lint::DeprecatedStruct::i`: text
@@ -61,19 +61,19 @@ mod cross_crate {
     }
 
     fn test_method_param<Foo: Trait>(foo: Foo) {
-        foo.trait_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`
-        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`
-        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`
-        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`
-        foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
-        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
-        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
-        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
+        foo.trait_deprecated(); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated`
+        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated`
+        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated`
+        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated`
+        foo.trait_deprecated_text(); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text
+        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text
+        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text
     }
 
     fn test_method_object(foo: &Trait) {
-        foo.trait_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`
-        foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
+        foo.trait_deprecated(); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated`
+        foo.trait_deprecated_text(); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text
     }
 
     struct S;
@@ -243,22 +243,22 @@ mod this_crate {
         let foo = MethodTester;
 
         deprecated(); //~ ERROR use of deprecated function `this_crate::deprecated`
-        foo.method_deprecated(); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated`
-        Foo::method_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated`
-        <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated`
-        foo.trait_deprecated(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated`
-        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated`
-        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated`
-        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated`
+        foo.method_deprecated(); //~ ERROR use of deprecated method `this_crate::MethodTester::method_deprecated`
+        Foo::method_deprecated(&foo); //~ ERROR use of deprecated method `this_crate::MethodTester::method_deprecated`
+        <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated method `this_crate::MethodTester::method_deprecated`
+        foo.trait_deprecated(); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated`
+        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated`
+        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated`
+        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated`
 
         deprecated_text(); //~ ERROR use of deprecated function `this_crate::deprecated_text`: text
-        foo.method_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
-        Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
-        <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
-        foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+        foo.method_deprecated_text(); //~ ERROR use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text
+        Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text
+        <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text
+        foo.trait_deprecated_text(); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
+        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
+        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
 
         // Future deprecations are only permitted with `#![feature(staged_api)]`
         deprecated_future(); //~ ERROR use of deprecated function
@@ -289,19 +289,19 @@ mod this_crate {
     }
 
     fn test_method_param<Foo: Trait>(foo: Foo) {
-        foo.trait_deprecated(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated`
-        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated`
-        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated`
-        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated`
-        foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+        foo.trait_deprecated(); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated`
+        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated`
+        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated`
+        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated`
+        foo.trait_deprecated_text(); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
+        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
+        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
     }
 
     fn test_method_object(foo: &Trait) {
-        foo.trait_deprecated(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated`
-        foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+        foo.trait_deprecated(); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated`
+        foo.trait_deprecated_text(); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
     }
 
     #[deprecated(since = "1.0.0", note = "text")]
diff --git a/tests/ui/deprecation/deprecation-lint.stderr b/tests/ui/deprecation/deprecation-lint.stderr
index 3842f849295..2098073409d 100644
--- a/tests/ui/deprecation/deprecation-lint.stderr
+++ b/tests/ui/deprecation/deprecation-lint.stderr
@@ -10,13 +10,13 @@ note: the lint level is defined here
 LL | #![deny(deprecated)]
    |         ^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
+error: use of deprecated method `deprecation_lint::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:21:16
    |
 LL |         Trait::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
+error: use of deprecated method `deprecation_lint::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:23:25
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
@@ -28,13 +28,13 @@ error: use of deprecated function `deprecation_lint::deprecated_text`: text
 LL |         deprecated_text();
    |         ^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
+error: use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:30:16
    |
-LL | ...   Trait::trait_deprecated_text(&foo);
-   |              ^^^^^^^^^^^^^^^^^^^^^
+LL |         Trait::trait_deprecated_text(&foo);
+   |                ^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
+error: use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:32:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
@@ -100,25 +100,25 @@ error: use of deprecated function `deprecation_lint::deprecated_text`: text
 LL |         macro_test_arg!(macro_test_arg!(deprecated_text()));
    |                                         ^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
+error: use of deprecated method `deprecation_lint::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:65:16
    |
 LL |         Trait::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
+error: use of deprecated method `deprecation_lint::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:67:25
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
    |                         ^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
+error: use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:69:16
    |
-LL | ...   Trait::trait_deprecated_text(&foo);
-   |              ^^^^^^^^^^^^^^^^^^^^^
+LL |         Trait::trait_deprecated_text(&foo);
+   |                ^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
+error: use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:71:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
@@ -184,13 +184,13 @@ error: use of deprecated function `this_crate::deprecated`: text
 LL |         deprecated();
    |         ^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+error: use of deprecated method `this_crate::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:250:16
    |
 LL |         Trait::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+error: use of deprecated method `this_crate::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:252:25
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
@@ -202,17 +202,17 @@ error: use of deprecated function `this_crate::deprecated_text`: text
 LL |         deprecated_text();
    |         ^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:259:16
    |
 LL |         Trait::trait_deprecated_text(&foo);
    |                ^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:261:25
    |
-LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
-   |                       ^^^^^^^^^^^^^^^^^^^^^
+LL |         <Foo as Trait>::trait_deprecated_text(&foo);
+   |                         ^^^^^^^^^^^^^^^^^^^^^
 
 error: use of deprecated function `this_crate::deprecated_future`: text
   --> $DIR/deprecation-lint.rs:264:9
@@ -274,29 +274,29 @@ error: use of deprecated tuple struct `this_crate::nested::DeprecatedTupleStruct
 LL | ...   let _ = nested::DeprecatedTupleStruct (1);
    |                       ^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+error: use of deprecated method `this_crate::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:293:16
    |
 LL |         Trait::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+error: use of deprecated method `this_crate::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:295:25
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
    |                         ^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:297:16
    |
 LL |         Trait::trait_deprecated_text(&foo);
    |                ^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:299:25
    |
-LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
-   |                       ^^^^^^^^^^^^^^^^^^^^^
+LL |         <Foo as Trait>::trait_deprecated_text(&foo);
+   |                         ^^^^^^^^^^^^^^^^^^^^^
 
 error: use of deprecated function `this_crate::test_fn_closure_body::{closure#0}::bar`
   --> $DIR/deprecation-lint.rs:317:13
@@ -352,65 +352,65 @@ error: use of deprecated tuple struct `this_crate2::Deprecated2`: text
 LL |         let Deprecated2
    |             ^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text
+error: use of deprecated method `deprecation_lint::MethodTester::method_deprecated`: text
   --> $DIR/deprecation-lint.rs:17:13
    |
 LL |         foo.method_deprecated();
    |             ^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text
+error: use of deprecated method `deprecation_lint::MethodTester::method_deprecated`: text
   --> $DIR/deprecation-lint.rs:18:14
    |
 LL |         Foo::method_deprecated(&foo);
    |              ^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text
+error: use of deprecated method `deprecation_lint::MethodTester::method_deprecated`: text
   --> $DIR/deprecation-lint.rs:19:16
    |
 LL |         <Foo>::method_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
+error: use of deprecated method `deprecation_lint::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:20:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
+error: use of deprecated method `deprecation_lint::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:22:16
    |
 LL |         <Foo>::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text
+error: use of deprecated method `deprecation_lint::MethodTester::method_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:26:13
    |
-LL | ...   foo.method_deprecated_text();
-   |           ^^^^^^^^^^^^^^^^^^^^^^
+LL |         foo.method_deprecated_text();
+   |             ^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text
+error: use of deprecated method `deprecation_lint::MethodTester::method_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:27:14
    |
-LL | ...   Foo::method_deprecated_text(&foo);
-   |            ^^^^^^^^^^^^^^^^^^^^^^
+LL |         Foo::method_deprecated_text(&foo);
+   |              ^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text
+error: use of deprecated method `deprecation_lint::MethodTester::method_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:28:16
    |
 LL | ...   <Foo>::method_deprecated_text(&foo);
    |              ^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
+error: use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:29:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
+error: use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:31:16
    |
-LL | ...   <Foo>::trait_deprecated_text(&foo);
-   |              ^^^^^^^^^^^^^^^^^^^^^
+LL |         <Foo>::trait_deprecated_text(&foo);
+   |                ^^^^^^^^^^^^^^^^^^^^^
 
 error: use of deprecated field `deprecation_lint::DeprecatedStruct::i`: text
   --> $DIR/deprecation-lint.rs:35:13
@@ -424,37 +424,37 @@ error: use of deprecated field `deprecation_lint::nested::DeprecatedStruct::i`:
 LL |             i: 0
    |             ^^^^
 
-error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
+error: use of deprecated method `deprecation_lint::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:64:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
+error: use of deprecated method `deprecation_lint::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:66:16
    |
 LL |         <Foo>::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
+error: use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:68:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
+error: use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:70:16
    |
-LL | ...   <Foo>::trait_deprecated_text(&foo);
-   |              ^^^^^^^^^^^^^^^^^^^^^
+LL |         <Foo>::trait_deprecated_text(&foo);
+   |                ^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
+error: use of deprecated method `deprecation_lint::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:75:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
+error: use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:76:13
    |
 LL |         foo.trait_deprecated_text();
@@ -544,61 +544,61 @@ error: use of deprecated field `deprecation_lint::Deprecated2::2`: text
 LL |              _)
    |              ^
 
-error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text
+error: use of deprecated method `this_crate::MethodTester::method_deprecated`: text
   --> $DIR/deprecation-lint.rs:246:13
    |
 LL |         foo.method_deprecated();
    |             ^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text
+error: use of deprecated method `this_crate::MethodTester::method_deprecated`: text
   --> $DIR/deprecation-lint.rs:247:14
    |
 LL |         Foo::method_deprecated(&foo);
    |              ^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text
+error: use of deprecated method `this_crate::MethodTester::method_deprecated`: text
   --> $DIR/deprecation-lint.rs:248:16
    |
 LL |         <Foo>::method_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+error: use of deprecated method `this_crate::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:249:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+error: use of deprecated method `this_crate::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:251:16
    |
 LL |         <Foo>::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
+error: use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:255:13
    |
-LL | ...   foo.method_deprecated_text();
-   |           ^^^^^^^^^^^^^^^^^^^^^^
+LL |         foo.method_deprecated_text();
+   |             ^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
+error: use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:256:14
    |
-LL | ...   Foo::method_deprecated_text(&foo);
-   |            ^^^^^^^^^^^^^^^^^^^^^^
+LL |         Foo::method_deprecated_text(&foo);
+   |              ^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
+error: use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:257:16
    |
-LL | ...   <Foo>::method_deprecated_text(&foo);
-   |              ^^^^^^^^^^^^^^^^^^^^^^
+LL |         <Foo>::method_deprecated_text(&foo);
+   |                ^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:258:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:260:16
    |
 LL |         <Foo>::trait_deprecated_text(&foo);
@@ -616,37 +616,37 @@ error: use of deprecated field `this_crate::nested::DeprecatedStruct::i`: text
 LL |             i: 0
    |             ^^^^
 
-error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+error: use of deprecated method `this_crate::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:292:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+error: use of deprecated method `this_crate::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:294:16
    |
 LL |         <Foo>::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:296:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:298:16
    |
 LL |         <Foo>::trait_deprecated_text(&foo);
    |                ^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+error: use of deprecated method `this_crate::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:303:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:304:13
    |
 LL |         foo.trait_deprecated_text();
diff --git a/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed b/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed
index 99a2b09614f..85e88287094 100644
--- a/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed
+++ b/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed
@@ -3,7 +3,7 @@
 #![deny(deprecated)]
 
 fn main() {
-    let _foo = str::trim_start("   aoeu"); //~ ERROR use of deprecated associated function `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated]
+    let _foo = str::trim_start("   aoeu"); //~ ERROR use of deprecated method `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated]
 
-    let _bar = "   aoeu".trim_start(); //~ ERROR use of deprecated associated function `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated]
+    let _bar = "   aoeu".trim_start(); //~ ERROR use of deprecated method `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated]
 }
diff --git a/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs b/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs
index 62bf84aa3ea..246de2f5e4b 100644
--- a/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs
+++ b/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs
@@ -3,7 +3,7 @@
 #![deny(deprecated)]
 
 fn main() {
-    let _foo = str::trim_left("   aoeu"); //~ ERROR use of deprecated associated function `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated]
+    let _foo = str::trim_left("   aoeu"); //~ ERROR use of deprecated method `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated]
 
-    let _bar = "   aoeu".trim_left(); //~ ERROR use of deprecated associated function `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated]
+    let _bar = "   aoeu".trim_left(); //~ ERROR use of deprecated method `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated]
 }
diff --git a/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr b/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr
index 8d4529526e3..3b518d1802b 100644
--- a/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr
+++ b/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr
@@ -1,4 +1,4 @@
-error: use of deprecated associated function `core::str::<impl str>::trim_left`: superseded by `trim_start`
+error: use of deprecated method `core::str::<impl str>::trim_left`: superseded by `trim_start`
   --> $DIR/issue-84637-deprecated-associated-function.rs:6:21
    |
 LL |     let _foo = str::trim_left("   aoeu");
@@ -9,18 +9,18 @@ note: the lint level is defined here
    |
 LL | #![deny(deprecated)]
    |         ^^^^^^^^^^
-help: replace the use of the deprecated associated function
+help: replace the use of the deprecated method
    |
 LL |     let _foo = str::trim_start("   aoeu");
    |                     ~~~~~~~~~~
 
-error: use of deprecated associated function `core::str::<impl str>::trim_left`: superseded by `trim_start`
+error: use of deprecated method `core::str::<impl str>::trim_left`: superseded by `trim_start`
   --> $DIR/issue-84637-deprecated-associated-function.rs:8:26
    |
 LL |     let _bar = "   aoeu".trim_left();
    |                          ^^^^^^^^^
    |
-help: replace the use of the deprecated associated function
+help: replace the use of the deprecated method
    |
 LL |     let _bar = "   aoeu".trim_start();
    |                          ~~~~~~~~~~
diff --git a/tests/ui/deprecation/suggestion.stderr b/tests/ui/deprecation/suggestion.stderr
index c5f2fc09125..5584b6d2f8f 100644
--- a/tests/ui/deprecation/suggestion.stderr
+++ b/tests/ui/deprecation/suggestion.stderr
@@ -14,13 +14,13 @@ help: replace the use of the deprecated function
 LL |     bar::replacement();
    |          ~~~~~~~~~~~
 
-error: use of deprecated associated function `Foo::deprecated`: replaced by `replacement`
+error: use of deprecated method `Foo::deprecated`: replaced by `replacement`
   --> $DIR/suggestion.rs:40:9
    |
 LL |     foo.deprecated();
    |         ^^^^^^^^^^
    |
-help: replace the use of the deprecated associated function
+help: replace the use of the deprecated method
    |
 LL |     foo.replacement();
    |         ~~~~~~~~~~~
diff --git a/tests/ui/error-codes/E0107.rs b/tests/ui/error-codes/E0107.rs
index d369fc2a565..fd23e7c00f2 100644
--- a/tests/ui/error-codes/E0107.rs
+++ b/tests/ui/error-codes/E0107.rs
@@ -11,39 +11,39 @@ enum Bar {
 
 struct Baz<'a, 'b, 'c> {
     buzz: Buzz<'a>,
-    //~^ ERROR this struct takes 2 lifetime arguments
+    //~^ ERROR struct takes 2 lifetime arguments
     //~| HELP add missing lifetime argument
 
     bar: Bar<'a>,
-    //~^ ERROR this enum takes 0 lifetime arguments
+    //~^ ERROR enum takes 0 lifetime arguments
     //~| HELP remove these generics
 
     foo2: Foo<'a, 'b, 'c>,
-    //~^ ERROR this struct takes 1 lifetime argument
+    //~^ ERROR struct takes 1 lifetime argument
     //~| HELP remove these lifetime arguments
 
     qux1: Qux<'a, 'b, i32>,
-    //~^ ERROR this struct takes 1 lifetime argument
+    //~^ ERROR struct takes 1 lifetime argument
     //~| HELP remove this lifetime argument
 
     qux2: Qux<'a, i32, 'b>,
-    //~^ ERROR this struct takes 1 lifetime argument
+    //~^ ERROR struct takes 1 lifetime argument
     //~| HELP remove this lifetime argument
 
     qux3: Qux<'a, 'b, 'c, i32>,
-    //~^ ERROR this struct takes 1 lifetime argument
+    //~^ ERROR struct takes 1 lifetime argument
     //~| HELP remove these lifetime arguments
 
     qux4: Qux<'a, i32, 'b, 'c>,
-    //~^ ERROR this struct takes 1 lifetime argument
+    //~^ ERROR struct takes 1 lifetime argument
     //~| HELP remove these lifetime arguments
 
     qux5: Qux<'a, 'b, i32, 'c>,
-    //~^ ERROR this struct takes 1 lifetime argument
+    //~^ ERROR struct takes 1 lifetime argument
     //~| HELP remove this lifetime argument
 
     quux: Quux<'a, i32, 'b>,
-    //~^ ERROR this struct takes 0 lifetime arguments
+    //~^ ERROR struct takes 0 lifetime arguments
     //~| HELP remove this lifetime argument
 }
 
@@ -53,7 +53,7 @@ pub trait T {
 }
 
 fn trait_bound_generic<I: T<u8, u16>>(_i: I) {
-    //~^ ERROR this trait takes 0 generic arguments
+    //~^ ERROR trait takes 0 generic arguments
     //~| HELP replace the generic bounds with the associated types
 }
 
diff --git a/tests/ui/error-codes/E0107.stderr b/tests/ui/error-codes/E0107.stderr
index 03430f8fa3a..3f540eb08bc 100644
--- a/tests/ui/error-codes/E0107.stderr
+++ b/tests/ui/error-codes/E0107.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/E0107.rs:13:11
    |
 LL |     buzz: Buzz<'a>,
@@ -16,7 +16,7 @@ help: add missing lifetime argument
 LL |     buzz: Buzz<'a, 'a>,
    |                  ++++
 
-error[E0107]: this enum takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: enum takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/E0107.rs:17:10
    |
 LL |     bar: Bar<'a>,
@@ -30,7 +30,7 @@ note: enum defined here, with 0 lifetime parameters
 LL | enum Bar {
    |      ^^^
 
-error[E0107]: this struct takes 1 lifetime argument but 3 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 3 lifetime arguments were supplied
   --> $DIR/E0107.rs:21:11
    |
 LL |     foo2: Foo<'a, 'b, 'c>,
@@ -44,7 +44,7 @@ note: struct defined here, with 1 lifetime parameter: `'a`
 LL | struct Foo<'a>(&'a str);
    |        ^^^ --
 
-error[E0107]: this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/E0107.rs:25:11
    |
 LL |     qux1: Qux<'a, 'b, i32>,
@@ -58,7 +58,7 @@ note: struct defined here, with 1 lifetime parameter: `'a`
 LL | struct Qux<'a, T>(&'a T);
    |        ^^^ --
 
-error[E0107]: this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/E0107.rs:29:11
    |
 LL |     qux2: Qux<'a, i32, 'b>,
@@ -72,7 +72,7 @@ note: struct defined here, with 1 lifetime parameter: `'a`
 LL | struct Qux<'a, T>(&'a T);
    |        ^^^ --
 
-error[E0107]: this struct takes 1 lifetime argument but 3 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 3 lifetime arguments were supplied
   --> $DIR/E0107.rs:33:11
    |
 LL |     qux3: Qux<'a, 'b, 'c, i32>,
@@ -86,7 +86,7 @@ note: struct defined here, with 1 lifetime parameter: `'a`
 LL | struct Qux<'a, T>(&'a T);
    |        ^^^ --
 
-error[E0107]: this struct takes 1 lifetime argument but 3 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 3 lifetime arguments were supplied
   --> $DIR/E0107.rs:37:11
    |
 LL |     qux4: Qux<'a, i32, 'b, 'c>,
@@ -100,7 +100,7 @@ note: struct defined here, with 1 lifetime parameter: `'a`
 LL | struct Qux<'a, T>(&'a T);
    |        ^^^ --
 
-error[E0107]: this struct takes 1 lifetime argument but 3 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 3 lifetime arguments were supplied
   --> $DIR/E0107.rs:41:11
    |
 LL |     qux5: Qux<'a, 'b, i32, 'c>,
@@ -114,7 +114,7 @@ note: struct defined here, with 1 lifetime parameter: `'a`
 LL | struct Qux<'a, T>(&'a T);
    |        ^^^ --
 
-error[E0107]: this struct takes 0 lifetime arguments but 2 lifetime arguments were supplied
+error[E0107]: struct takes 0 lifetime arguments but 2 lifetime arguments were supplied
   --> $DIR/E0107.rs:45:11
    |
 LL |     quux: Quux<'a, i32, 'b>,
@@ -128,7 +128,7 @@ note: struct defined here, with 0 lifetime parameters
 LL | struct Quux<T>(T);
    |        ^^^^
 
-error[E0107]: this trait takes 0 generic arguments but 2 generic arguments were supplied
+error[E0107]: trait takes 0 generic arguments but 2 generic arguments were supplied
   --> $DIR/E0107.rs:55:27
    |
 LL | fn trait_bound_generic<I: T<u8, u16>>(_i: I) {
diff --git a/tests/ui/error-codes/E0476.rs b/tests/ui/error-codes/E0476.rs
new file mode 100644
index 00000000000..d5e4b8d2372
--- /dev/null
+++ b/tests/ui/error-codes/E0476.rs
@@ -0,0 +1,13 @@
+#![feature(coerce_unsized)]
+#![feature(unsize)]
+
+use std::marker::Unsize;
+use std::ops::CoerceUnsized;
+
+struct Wrapper<T>(T);
+
+impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {}
+//~^ ERROR lifetime of the source pointer does not outlive lifetime bound of the object type [E0476]
+//~^^ ERROR E0119
+
+fn main() {}
diff --git a/tests/ui/error-codes/E0476.stderr b/tests/ui/error-codes/E0476.stderr
new file mode 100644
index 00000000000..a4bb26532a2
--- /dev/null
+++ b/tests/ui/error-codes/E0476.stderr
@@ -0,0 +1,31 @@
+error[E0119]: conflicting implementations of trait `CoerceUnsized<&Wrapper<_>>` for type `&Wrapper<_>`
+  --> $DIR/E0476.rs:9:1
+   |
+LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: conflicting implementation in crate `core`:
+           - impl<'a, 'b, T, U> CoerceUnsized<&'a U> for &'b T
+             where 'b: 'a, T: Unsize<U>, T: ?Sized, U: ?Sized;
+
+error[E0476]: lifetime of the source pointer does not outlive lifetime bound of the object type
+  --> $DIR/E0476.rs:9:1
+   |
+LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: object type is valid for the lifetime `'a` as defined here
+  --> $DIR/E0476.rs:9:6
+   |
+LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {}
+   |      ^^
+note: source pointer is only valid for the lifetime `'b` as defined here
+  --> $DIR/E0476.rs:9:10
+   |
+LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {}
+   |          ^^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0119, E0476.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/error-codes/E0624.rs b/tests/ui/error-codes/E0624.rs
index 4c68b70fb16..45f72a565ca 100644
--- a/tests/ui/error-codes/E0624.rs
+++ b/tests/ui/error-codes/E0624.rs
@@ -8,5 +8,5 @@ mod inner {
 
 fn main() {
     let foo = inner::Foo;
-    foo.method(); //~ ERROR associated function `method` is private [E0624]
+    foo.method(); //~ ERROR method `method` is private [E0624]
 }
diff --git a/tests/ui/error-codes/E0624.stderr b/tests/ui/error-codes/E0624.stderr
index e59b8a8ae35..23a8ea8a8c9 100644
--- a/tests/ui/error-codes/E0624.stderr
+++ b/tests/ui/error-codes/E0624.stderr
@@ -1,11 +1,11 @@
-error[E0624]: associated function `method` is private
+error[E0624]: method `method` is private
   --> $DIR/E0624.rs:11:9
    |
 LL |         fn method(&self) {}
-   |         ---------------- private associated function defined here
+   |         ---------------- private method defined here
 ...
 LL |     foo.method();
-   |         ^^^^^^ private associated function
+   |         ^^^^^^ private method
 
 error: aborting due to previous error
 
diff --git a/tests/ui/explore-issue-38412.stderr b/tests/ui/explore-issue-38412.stderr
index 08dadb4db85..d8b485c9dc3 100644
--- a/tests/ui/explore-issue-38412.stderr
+++ b/tests/ui/explore-issue-38412.stderr
@@ -79,38 +79,38 @@ LL |     r.unstable_undeclared();
    = note: see issue #38412 <https://github.com/rust-lang/rust/issues/38412> for more information
    = help: add `#![feature(unstable_undeclared)]` to the crate attributes to enable
 
-error[E0624]: associated function `pub_crate` is private
+error[E0624]: method `pub_crate` is private
   --> $DIR/explore-issue-38412.rs:48:7
    |
 LL |     r.pub_crate();
-   |       ^^^^^^^^^ private associated function
+   |       ^^^^^^^^^ private method
    |
   ::: $DIR/auxiliary/pub-and-stability.rs:114:9
    |
 LL |         pub(crate) fn pub_crate(&self) -> i32 { self.d_priv }
-   |         ------------------------------------- private associated function defined here
+   |         ------------------------------------- private method defined here
 
-error[E0624]: associated function `pub_mod` is private
+error[E0624]: method `pub_mod` is private
   --> $DIR/explore-issue-38412.rs:49:7
    |
 LL |     r.pub_mod();
-   |       ^^^^^^^ private associated function
+   |       ^^^^^^^ private method
    |
   ::: $DIR/auxiliary/pub-and-stability.rs:116:9
    |
 LL |         pub(in m) fn pub_mod(&self) -> i32 { self.d_priv }
-   |         ---------------------------------- private associated function defined here
+   |         ---------------------------------- private method defined here
 
-error[E0624]: associated function `private` is private
+error[E0624]: method `private` is private
   --> $DIR/explore-issue-38412.rs:50:7
    |
 LL |     r.private();
-   |       ^^^^^^^ private associated function
+   |       ^^^^^^^ private method
    |
   ::: $DIR/auxiliary/pub-and-stability.rs:118:9
    |
 LL |         fn private(&self) -> i32 { self.d_priv }
-   |         ------------------------ private associated function defined here
+   |         ------------------------ private method defined here
 
 error[E0658]: use of unstable library feature 'unstable_undeclared'
   --> $DIR/explore-issue-38412.rs:55:7
@@ -130,38 +130,38 @@ LL |     t.unstable_undeclared();
    = note: see issue #38412 <https://github.com/rust-lang/rust/issues/38412> for more information
    = help: add `#![feature(unstable_undeclared)]` to the crate attributes to enable
 
-error[E0624]: associated function `pub_crate` is private
+error[E0624]: method `pub_crate` is private
   --> $DIR/explore-issue-38412.rs:61:7
    |
 LL |     t.pub_crate();
-   |       ^^^^^^^^^ private associated function
+   |       ^^^^^^^^^ private method
    |
   ::: $DIR/auxiliary/pub-and-stability.rs:129:9
    |
 LL |         pub(crate) fn pub_crate(&self) -> i32 { self.0 }
-   |         ------------------------------------- private associated function defined here
+   |         ------------------------------------- private method defined here
 
-error[E0624]: associated function `pub_mod` is private
+error[E0624]: method `pub_mod` is private
   --> $DIR/explore-issue-38412.rs:62:7
    |
 LL |     t.pub_mod();
-   |       ^^^^^^^ private associated function
+   |       ^^^^^^^ private method
    |
   ::: $DIR/auxiliary/pub-and-stability.rs:130:9
    |
 LL |         pub(in m) fn pub_mod(&self) -> i32 { self.0 }
-   |         ---------------------------------- private associated function defined here
+   |         ---------------------------------- private method defined here
 
-error[E0624]: associated function `private` is private
+error[E0624]: method `private` is private
   --> $DIR/explore-issue-38412.rs:63:7
    |
 LL |     t.private();
-   |       ^^^^^^^ private associated function
+   |       ^^^^^^^ private method
    |
   ::: $DIR/auxiliary/pub-and-stability.rs:131:9
    |
 LL |         fn private(&self) -> i32 { self.0 }
-   |         ------------------------ private associated function defined here
+   |         ------------------------ private method defined here
 
 error: aborting due to 19 previous errors
 
diff --git a/tests/ui/expr/malformed_closure/missing_braces_around_block.fixed b/tests/ui/expr/malformed_closure/missing_braces_around_block.fixed
index c50b9a12b6d..a7a9db7d977 100644
--- a/tests/ui/expr/malformed_closure/missing_braces_around_block.fixed
+++ b/tests/ui/expr/malformed_closure/missing_braces_around_block.fixed
@@ -4,16 +4,23 @@
 // If this recovery happens, then plenty of errors are emitted. Here, we expect
 // only one error.
 //
-// This is part of issue #88065:
+// This is part of the following issues:
 // https://github.com/rust-lang/rust/issues/88065
+// https://github.com/rust-lang/rust/issues/107959
 
 // run-rustfix
 
 fn main() {
+    // Closure with multiple expressions delimited by semicolon.
     let num = 5;
     (1..num).reduce(|a, b| {
         //~^ ERROR: closure bodies that contain statements must be surrounded by braces
         println!("{}", a);
         a * b
     }).unwrap();
+
+    // Closure with a single expression ended by a semicolon.
+    let mut v = vec![1, 2, 3];
+    v.iter_mut().for_each(|x| {*x = *x+1;});
+        //~^ ERROR: closure bodies that contain statements must be surrounded by braces
 }
diff --git a/tests/ui/expr/malformed_closure/missing_braces_around_block.rs b/tests/ui/expr/malformed_closure/missing_braces_around_block.rs
index 58c81f3a6e2..b5690b2eca7 100644
--- a/tests/ui/expr/malformed_closure/missing_braces_around_block.rs
+++ b/tests/ui/expr/malformed_closure/missing_braces_around_block.rs
@@ -4,16 +4,23 @@
 // If this recovery happens, then plenty of errors are emitted. Here, we expect
 // only one error.
 //
-// This is part of issue #88065:
+// This is part of the following issues:
 // https://github.com/rust-lang/rust/issues/88065
+// https://github.com/rust-lang/rust/issues/107959
 
 // run-rustfix
 
 fn main() {
+    // Closure with multiple expressions delimited by semicolon.
     let num = 5;
     (1..num).reduce(|a, b|
         //~^ ERROR: closure bodies that contain statements must be surrounded by braces
         println!("{}", a);
         a * b
     ).unwrap();
+
+    // Closure with a single expression ended by a semicolon.
+    let mut v = vec![1, 2, 3];
+    v.iter_mut().for_each(|x|*x = *x+1;);
+        //~^ ERROR: closure bodies that contain statements must be surrounded by braces
 }
diff --git a/tests/ui/expr/malformed_closure/missing_braces_around_block.stderr b/tests/ui/expr/malformed_closure/missing_braces_around_block.stderr
index dac9a8cfc69..039eef909fc 100644
--- a/tests/ui/expr/malformed_closure/missing_braces_around_block.stderr
+++ b/tests/ui/expr/malformed_closure/missing_braces_around_block.stderr
@@ -1,5 +1,5 @@
 error: closure bodies that contain statements must be surrounded by braces
-  --> $DIR/missing_braces_around_block.rs:14:26
+  --> $DIR/missing_braces_around_block.rs:16:26
    |
 LL |     (1..num).reduce(|a, b|
    |                          ^
@@ -8,14 +8,14 @@ LL |     ).unwrap();
    |     ^
    |
 note: statement found outside of a block
-  --> $DIR/missing_braces_around_block.rs:16:26
+  --> $DIR/missing_braces_around_block.rs:18:26
    |
 LL |         println!("{}", a);
    |         -----------------^ this `;` turns the preceding closure into a statement
    |         |
    |         this expression is a statement because of the trailing semicolon
 note: the closure body may be incorrectly delimited
-  --> $DIR/missing_braces_around_block.rs:14:21
+  --> $DIR/missing_braces_around_block.rs:16:21
    |
 LL |       (1..num).reduce(|a, b|
    |  _____________________^
@@ -34,5 +34,30 @@ LL |         a * b
 LL ~     }).unwrap();
    |
 
-error: aborting due to previous error
+error: closure bodies that contain statements must be surrounded by braces
+  --> $DIR/missing_braces_around_block.rs:24:29
+   |
+LL |     v.iter_mut().for_each(|x|*x = *x+1;);
+   |                             ^          ^
+   |
+note: statement found outside of a block
+  --> $DIR/missing_braces_around_block.rs:24:39
+   |
+LL |     v.iter_mut().for_each(|x|*x = *x+1;);
+   |                              ---------^ this `;` turns the preceding closure into a statement
+   |                              |
+   |                              this expression is a statement because of the trailing semicolon
+note: the closure body may be incorrectly delimited
+  --> $DIR/missing_braces_around_block.rs:24:27
+   |
+LL |     v.iter_mut().for_each(|x|*x = *x+1;);
+   |                           ^^^^^^^^^^^^ - ...but likely you meant the closure to end here
+   |                           |
+   |                           this is the parsed closure...
+help: try adding braces
+   |
+LL |     v.iter_mut().for_each(|x| {*x = *x+1;});
+   |                               +          +
+
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr
index edbbf7db565..4233a8af9b6 100644
--- a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr
+++ b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr
@@ -115,19 +115,19 @@ LL |     let _: impl Tr1<As1: Copy> = S1;
    = note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
    = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const types
   --> $DIR/feature-gate-associated_type_bounds.rs:55:14
    |
 LL | const _cdef: impl Tr1<As1: Copy> = S1;
    |              ^^^^^^^^^^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const types
   --> $DIR/feature-gate-associated_type_bounds.rs:61:15
    |
 LL | static _sdef: impl Tr1<As1: Copy> = S1;
    |               ^^^^^^^^^^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings
   --> $DIR/feature-gate-associated_type_bounds.rs:68:12
    |
 LL |     let _: impl Tr1<As1: Copy> = S1;
diff --git a/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr b/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr
index 760dcb615c8..c8c3e13d7fc 100644
--- a/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr
+++ b/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr
@@ -1,4 +1,4 @@
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types
   --> $DIR/feature-gate-impl_trait_in_fn_trait_return.rs:1:24
    |
 LL | fn f() -> impl Fn() -> impl Sized { || () }
@@ -7,7 +7,7 @@ LL | fn f() -> impl Fn() -> impl Sized { || () }
    = note: see issue #99697 <https://github.com/rust-lang/rust/issues/99697> for more information
    = help: add `#![feature(impl_trait_in_fn_trait_return)]` to the crate attributes to enable
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types
   --> $DIR/feature-gate-impl_trait_in_fn_trait_return.rs:3:32
    |
 LL | fn g() -> &'static dyn Fn() -> impl Sized { &|| () }
diff --git a/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr b/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr
index aeabed4a6ab..0082b6fafee 100644
--- a/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr
+++ b/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr
@@ -1,4 +1,4 @@
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return types
   --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:8:17
    |
 LL |     fn bar() -> impl Sized;
@@ -7,7 +7,7 @@ LL |     fn bar() -> impl Sized;
    = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
    = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return types
   --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:9:21
    |
 LL |     fn baz() -> Box<impl std::fmt::Display>;
@@ -16,7 +16,7 @@ LL |     fn baz() -> Box<impl std::fmt::Display>;
    = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
    = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return types
   --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:15:23
    |
 LL |     async fn bar() -> impl Sized;
diff --git a/tests/ui/fn/issue-3044.stderr b/tests/ui/fn/issue-3044.stderr
index 2690ad71176..219029e2afd 100644
--- a/tests/ui/fn/issue-3044.stderr
+++ b/tests/ui/fn/issue-3044.stderr
@@ -7,7 +7,7 @@ LL | |
 LL | |     });
    | |______- an argument is missing
    |
-note: associated function defined here
+note: method defined here
   --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
 help: provide the argument
    |
diff --git a/tests/ui/generator/generator-yielding-or-returning-itself.stderr b/tests/ui/generator/generator-yielding-or-returning-itself.stderr
index 8f5d2429a28..a26dbf3f27c 100644
--- a/tests/ui/generator/generator-yielding-or-returning-itself.stderr
+++ b/tests/ui/generator/generator-yielding-or-returning-itself.stderr
@@ -19,7 +19,7 @@ note: required by a bound in `want_cyclic_generator_return`
   --> $DIR/generator-yielding-or-returning-itself.rs:10:36
    |
 LL | pub fn want_cyclic_generator_return<T>(_: T)
-   |        ---------------------------- required by a bound in this
+   |        ---------------------------- required by a bound in this function
 LL |     where T: Generator<Yield = (), Return = T>
    |                                    ^^^^^^^^^^ required by this bound in `want_cyclic_generator_return`
 
@@ -44,7 +44,7 @@ note: required by a bound in `want_cyclic_generator_yield`
   --> $DIR/generator-yielding-or-returning-itself.rs:23:24
    |
 LL | pub fn want_cyclic_generator_yield<T>(_: T)
-   |        --------------------------- required by a bound in this
+   |        --------------------------- required by a bound in this function
 LL |     where T: Generator<Yield = T, Return = ()>
    |                        ^^^^^^^^^ required by this bound in `want_cyclic_generator_yield`
 
diff --git a/tests/ui/generator/issue-102645.stderr b/tests/ui/generator/issue-102645.stderr
index f6d2440295e..3f9a4c2f3c5 100644
--- a/tests/ui/generator/issue-102645.stderr
+++ b/tests/ui/generator/issue-102645.stderr
@@ -4,7 +4,7 @@ error[E0061]: this method takes 1 argument but 0 arguments were supplied
 LL |     Pin::new(&mut b).resume();
    |                      ^^^^^^-- an argument of type `()` is missing
    |
-note: associated function defined here
+note: method defined here
   --> $SRC_DIR/core/src/ops/generator.rs:LL:COL
 help: provide the argument
    |
diff --git a/tests/ui/generic-associated-types/bugs/issue-88460.stderr b/tests/ui/generic-associated-types/bugs/issue-88460.stderr
index 6612c4b4944..a2047f103d4 100644
--- a/tests/ui/generic-associated-types/bugs/issue-88460.stderr
+++ b/tests/ui/generic-associated-types/bugs/issue-88460.stderr
@@ -11,7 +11,7 @@ note: required by a bound in `test`
   --> $DIR/issue-88460.rs:15:27
    |
 LL | fn test<T>(value: T)
-   |    ---- required by a bound in this
+   |    ---- required by a bound in this function
 ...
 LL |     for<'a> T::Assoc<'a>: Marker,
    |                           ^^^^^^ required by this bound in `test`
diff --git a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs
index 9eb069637c6..5738dfa83ee 100644
--- a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs
+++ b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs
@@ -5,12 +5,12 @@ trait X {
 fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
   //~^ ERROR: lifetime in trait object type must be followed by `+`
   //~| ERROR: parenthesized generic arguments cannot be used
-  //~| ERROR this associated type takes 0 generic arguments but 1 generic argument
-  //~| ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments
+  //~| ERROR associated type takes 0 generic arguments but 1 generic argument
+  //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
 
 
 fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {}
   //~^ ERROR: parenthesized generic arguments cannot be used
-  //~| ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments
+  //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
 
 fn main() {}
diff --git a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
index 165779796e0..461853379b5 100644
--- a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
+++ b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
@@ -23,7 +23,7 @@ LL | fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {}
    |                            |
    |                            help: remove these parentheses
 
-error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
   --> $DIR/gat-trait-path-parenthesised-args.rs:5:27
    |
 LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
@@ -39,7 +39,7 @@ help: add missing lifetime argument
 LL | fn foo<'a>(arg: Box<dyn X<Y('_, 'a) = &'a ()>>) {}
    |                             +++
 
-error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/gat-trait-path-parenthesised-args.rs:5:27
    |
 LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
@@ -53,7 +53,7 @@ note: associated type defined here, with 0 generic parameters
 LL |   type Y<'a>;
    |        ^
 
-error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
   --> $DIR/gat-trait-path-parenthesised-args.rs:12:27
    |
 LL | fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {}
diff --git a/tests/ui/generic-associated-types/issue-101020.stderr b/tests/ui/generic-associated-types/issue-101020.stderr
index 1f9273a8c4a..5c8db617c17 100644
--- a/tests/ui/generic-associated-types/issue-101020.stderr
+++ b/tests/ui/generic-associated-types/issue-101020.stderr
@@ -13,7 +13,7 @@ note: required by a bound in `LendingIterator::consume`
   --> $DIR/issue-101020.rs:9:33
    |
 LL |     fn consume<F>(self, _f: F)
-   |        ------- required by a bound in this
+   |        ------- required by a bound in this associated function
 ...
 LL |         for<'a> Self::Item<'a>: FuncInput<'a, Self::Item<'a>>,
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `LendingIterator::consume`
diff --git a/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs b/tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.rs
index 83655341d6a..83655341d6a 100644
--- a/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs
+++ b/tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.rs
diff --git a/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr b/tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.stderr
index baef38f6b80..4246f8c069d 100644
--- a/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr
+++ b/tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.stderr
@@ -1,5 +1,5 @@
 error[E0599]: the method `f` exists for struct `S`, but its trait bounds were not satisfied
-  --> $DIR/method-unsatified-assoc-type-predicate.rs:28:7
+  --> $DIR/method-unsatisfied-assoc-type-predicate.rs:28:7
    |
 LL | struct S;
    | --------
@@ -12,7 +12,7 @@ LL |     a.f();
    |       ^ method cannot be called on `S` due to unsatisfied trait bounds
    |
 note: trait bound `<S as X>::Y<i32> = i32` was not satisfied
-  --> $DIR/method-unsatified-assoc-type-predicate.rs:12:11
+  --> $DIR/method-unsatisfied-assoc-type-predicate.rs:12:11
    |
 LL | impl<T: X<Y<i32> = i32>> M for T {}
    |           ^^^^^^^^^^^^   -     -
diff --git a/tests/ui/generic-associated-types/missing_lifetime_args.rs b/tests/ui/generic-associated-types/missing_lifetime_args.rs
index 78def80925a..331511ba61a 100644
--- a/tests/ui/generic-associated-types/missing_lifetime_args.rs
+++ b/tests/ui/generic-associated-types/missing_lifetime_args.rs
@@ -12,9 +12,9 @@ fn foo<'c, 'd>(_arg: Box<dyn X<Y = (&'c u32, &'d u32)>>) {}
 //~^ ERROR missing generics for associated type
 
 fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b>) {}
-//~^ ERROR this struct takes 3 lifetime arguments but 2 lifetime
+//~^ ERROR struct takes 3 lifetime arguments but 2 lifetime
 
 fn f<'a>(_arg: Foo<'a>) {}
-//~^ ERROR this struct takes 3 lifetime arguments but 1 lifetime
+//~^ ERROR struct takes 3 lifetime arguments but 1 lifetime
 
 fn main() {}
diff --git a/tests/ui/generic-associated-types/missing_lifetime_args.stderr b/tests/ui/generic-associated-types/missing_lifetime_args.stderr
index 8f74b12c008..1a7a2e787a1 100644
--- a/tests/ui/generic-associated-types/missing_lifetime_args.stderr
+++ b/tests/ui/generic-associated-types/missing_lifetime_args.stderr
@@ -14,7 +14,7 @@ help: add missing lifetime arguments
 LL | fn foo<'c, 'd>(_arg: Box<dyn X<Y<'_, '_> = (&'c u32, &'d u32)>>) {}
    |                                 ++++++++
 
-error[E0107]: this struct takes 3 lifetime arguments but 2 lifetime arguments were supplied
+error[E0107]: struct takes 3 lifetime arguments but 2 lifetime arguments were supplied
   --> $DIR/missing_lifetime_args.rs:14:26
    |
 LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b>) {}
@@ -32,7 +32,7 @@ help: add missing lifetime argument
 LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b, 'a>) {}
    |                                    ++++
 
-error[E0107]: this struct takes 3 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 3 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing_lifetime_args.rs:17:16
    |
 LL | fn f<'a>(_arg: Foo<'a>) {}
diff --git a/tests/ui/generic-associated-types/missing_lifetime_const.rs b/tests/ui/generic-associated-types/missing_lifetime_const.rs
index 8b174b9e971..6e395dfdec1 100644
--- a/tests/ui/generic-associated-types/missing_lifetime_const.rs
+++ b/tests/ui/generic-associated-types/missing_lifetime_const.rs
@@ -4,7 +4,7 @@ trait Foo {
 
 fn foo<T: Foo>() {
     let _: <T as Foo>::Assoc<3>;
-      //~^ ERROR  this associated type
+      //~^ ERROR  associated type
 }
 
 fn main() {}
diff --git a/tests/ui/generic-associated-types/missing_lifetime_const.stderr b/tests/ui/generic-associated-types/missing_lifetime_const.stderr
index 62d2e9f49dd..41945aabfb5 100644
--- a/tests/ui/generic-associated-types/missing_lifetime_const.stderr
+++ b/tests/ui/generic-associated-types/missing_lifetime_const.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
   --> $DIR/missing_lifetime_const.rs:6:24
    |
 LL |     let _: <T as Foo>::Assoc<3>;
diff --git a/tests/ui/generic-associated-types/parameter_number_and_kind.rs b/tests/ui/generic-associated-types/parameter_number_and_kind.rs
index 8428e7763fb..ae2f7c00ea4 100644
--- a/tests/ui/generic-associated-types/parameter_number_and_kind.rs
+++ b/tests/ui/generic-associated-types/parameter_number_and_kind.rs
@@ -9,10 +9,10 @@ trait Foo {
     // Test parameters in default values
     type FOk<T> = Self::E<'static, T>;
     type FErr1 = Self::E<'static, 'static>;
-    //~^ ERROR this associated type takes 1 lifetime argument but 2 lifetime arguments were supplied
-    //~| ERROR this associated type takes 1
+    //~^ ERROR associated type takes 1 lifetime argument but 2 lifetime arguments were supplied
+    //~| ERROR associated type takes 1
     type FErr2<T> = Self::E<'static, T, u32>;
-    //~^ ERROR this associated type takes 1
+    //~^ ERROR associated type takes 1
 }
 
 fn main() {}
diff --git a/tests/ui/generic-associated-types/parameter_number_and_kind.stderr b/tests/ui/generic-associated-types/parameter_number_and_kind.stderr
index c20b9669e81..4523044b588 100644
--- a/tests/ui/generic-associated-types/parameter_number_and_kind.stderr
+++ b/tests/ui/generic-associated-types/parameter_number_and_kind.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated type takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: associated type takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/parameter_number_and_kind.rs:11:24
    |
 LL |     type FErr1 = Self::E<'static, 'static>;
@@ -12,7 +12,7 @@ note: associated type defined here, with 1 lifetime parameter: `'a`
 LL |     type E<'a, T>;
    |          ^ --
 
-error[E0107]: this associated type takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: associated type takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/parameter_number_and_kind.rs:11:24
    |
 LL |     type FErr1 = Self::E<'static, 'static>;
@@ -28,7 +28,7 @@ help: add missing generic argument
 LL |     type FErr1 = Self::E<'static, 'static, T>;
    |                                          +++
 
-error[E0107]: this associated type takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: associated type takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/parameter_number_and_kind.rs:14:27
    |
 LL |     type FErr2<T> = Self::E<'static, T, u32>;
diff --git a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs
index 1622b92aa0c..c58f9cf1dfc 100644
--- a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs
+++ b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs
@@ -4,8 +4,8 @@ trait X {
 
 const _: () = {
   fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
-      //~^ ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments
-      //~| ERROR this associated type takes 0 generic arguments but 1 generic argument
+      //~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
+      //~| ERROR associated type takes 0 generic arguments but 1 generic argument
 };
 
 fn main() {}
diff --git a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr
index 0a09ec5dc49..fab5b474d92 100644
--- a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr
+++ b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
   --> $DIR/trait-path-type-error-once-implemented.rs:6:29
    |
 LL |   fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
@@ -14,7 +14,7 @@ help: add missing lifetime argument
 LL |   fn f2<'a>(arg : Box<dyn X<Y<'_, 1> = &'a ()>>) {}
    |                               +++
 
-error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/trait-path-type-error-once-implemented.rs:6:29
    |
 LL |   fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
diff --git a/tests/ui/generic-associated-types/unsatified-item-lifetime-bound.rs b/tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.rs
index 1cc09aa6dd4..060ee8821d8 100644
--- a/tests/ui/generic-associated-types/unsatified-item-lifetime-bound.rs
+++ b/tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.rs
@@ -1,3 +1,5 @@
+#![warn(unused_lifetimes)]
+
 pub trait X {
     type Y<'a: 'static>;
     //~^ WARNING unnecessary lifetime parameter
diff --git a/tests/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr b/tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.stderr
index fbd79879d0f..a69cd0028c1 100644
--- a/tests/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr
+++ b/tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.stderr
@@ -1,45 +1,50 @@
 warning: unnecessary lifetime parameter `'a`
-  --> $DIR/unsatified-item-lifetime-bound.rs:2:12
+  --> $DIR/unsatisfied-item-lifetime-bound.rs:4:12
    |
 LL |     type Y<'a: 'static>;
    |            ^^
    |
    = help: you can use the `'static` lifetime directly, in place of `'a`
+note: the lint level is defined here
+  --> $DIR/unsatisfied-item-lifetime-bound.rs:1:9
+   |
+LL | #![warn(unused_lifetimes)]
+   |         ^^^^^^^^^^^^^^^^
 
 error[E0478]: lifetime bound not satisfied
-  --> $DIR/unsatified-item-lifetime-bound.rs:11:8
+  --> $DIR/unsatisfied-item-lifetime-bound.rs:13:8
    |
 LL |     f: <T as X>::Y<'a>,
    |        ^^^^^^^^^^^^^^^
    |
 note: lifetime parameter instantiated with the lifetime `'a` as defined here
-  --> $DIR/unsatified-item-lifetime-bound.rs:10:10
+  --> $DIR/unsatisfied-item-lifetime-bound.rs:12:10
    |
 LL | struct B<'a, T: for<'r> X<Y<'r> = &'r ()>> {
    |          ^^
    = note: but lifetime parameter must outlive the static lifetime
 
 error[E0478]: lifetime bound not satisfied
-  --> $DIR/unsatified-item-lifetime-bound.rs:16:8
+  --> $DIR/unsatisfied-item-lifetime-bound.rs:18:8
    |
 LL |     f: <T as X>::Y<'a>,
    |        ^^^^^^^^^^^^^^^
    |
 note: lifetime parameter instantiated with the lifetime `'a` as defined here
-  --> $DIR/unsatified-item-lifetime-bound.rs:15:10
+  --> $DIR/unsatisfied-item-lifetime-bound.rs:17:10
    |
 LL | struct C<'a, T: X> {
    |          ^^
    = note: but lifetime parameter must outlive the static lifetime
 
 error[E0478]: lifetime bound not satisfied
-  --> $DIR/unsatified-item-lifetime-bound.rs:21:8
+  --> $DIR/unsatisfied-item-lifetime-bound.rs:23:8
    |
 LL |     f: <() as X>::Y<'a>,
    |        ^^^^^^^^^^^^^^^^
    |
 note: lifetime parameter instantiated with the lifetime `'a` as defined here
-  --> $DIR/unsatified-item-lifetime-bound.rs:20:10
+  --> $DIR/unsatisfied-item-lifetime-bound.rs:22:10
    |
 LL | struct D<'a> {
    |          ^^
diff --git a/tests/ui/generics/bad-mid-path-type-params.rs b/tests/ui/generics/bad-mid-path-type-params.rs
index 23a5d1525d9..37d484cba0b 100644
--- a/tests/ui/generics/bad-mid-path-type-params.rs
+++ b/tests/ui/generics/bad-mid-path-type-params.rs
@@ -28,17 +28,17 @@ impl Trait<isize> for S2 {
 
 fn foo<'a>() {
     let _ = S::new::<isize,f64>(1, 1.0);
-    //~^ ERROR this associated function takes 1
+    //~^ ERROR associated function takes 1
 
     let _ = S::<'a,isize>::new::<f64>(1, 1.0);
-    //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+    //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument was supplied
 
     let _: S2 = Trait::new::<isize,f64>(1, 1.0);
-    //~^ ERROR this associated function takes 1
+    //~^ ERROR associated function takes 1
 
     let _: S2 = Trait::<'a,isize>::new::<f64,f64>(1, 1.0);
-    //~^ ERROR this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
-    //~| ERROR this associated function takes 1
+    //~^ ERROR trait takes 0 lifetime arguments but 1 lifetime argument was supplied
+    //~| ERROR associated function takes 1
 }
 
 fn main() {}
diff --git a/tests/ui/generics/bad-mid-path-type-params.stderr b/tests/ui/generics/bad-mid-path-type-params.stderr
index aee2b60159f..71e15dd4c92 100644
--- a/tests/ui/generics/bad-mid-path-type-params.stderr
+++ b/tests/ui/generics/bad-mid-path-type-params.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated function takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: associated function takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/bad-mid-path-type-params.rs:30:16
    |
 LL |     let _ = S::new::<isize,f64>(1, 1.0);
@@ -12,7 +12,7 @@ note: associated function defined here, with 1 generic parameter: `U`
 LL |     fn new<U>(x: T, _: U) -> S<T> {
    |        ^^^ -
 
-error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/bad-mid-path-type-params.rs:33:13
    |
 LL |     let _ = S::<'a,isize>::new::<f64>(1, 1.0);
@@ -26,7 +26,7 @@ note: struct defined here, with 0 lifetime parameters
 LL | struct S<T> {
    |        ^
 
-error[E0107]: this associated function takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: associated function takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/bad-mid-path-type-params.rs:36:24
    |
 LL |     let _: S2 = Trait::new::<isize,f64>(1, 1.0);
@@ -40,7 +40,7 @@ note: associated function defined here, with 1 generic parameter: `U`
 LL |     fn new<U>(x: T, y: U) -> Self;
    |        ^^^ -
 
-error[E0107]: this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/bad-mid-path-type-params.rs:39:17
    |
 LL |     let _: S2 = Trait::<'a,isize>::new::<f64,f64>(1, 1.0);
@@ -54,7 +54,7 @@ note: trait defined here, with 0 lifetime parameters
 LL | trait Trait<T> {
    |       ^^^^^
 
-error[E0107]: this associated function takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: associated function takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/bad-mid-path-type-params.rs:39:36
    |
 LL |     let _: S2 = Trait::<'a,isize>::new::<f64,f64>(1, 1.0);
diff --git a/tests/ui/generics/generic-arg-mismatch-recover.rs b/tests/ui/generics/generic-arg-mismatch-recover.rs
index 2cf7f1d657b..947f33414db 100644
--- a/tests/ui/generics/generic-arg-mismatch-recover.rs
+++ b/tests/ui/generics/generic-arg-mismatch-recover.rs
@@ -4,9 +4,9 @@ struct Bar<'a>(&'a ());
 
 fn main() {
     Foo::<'static, 'static, ()>(&0);
-    //~^ ERROR this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
+    //~^ ERROR struct takes 1 lifetime argument but 2 lifetime arguments were supplied
 
     Bar::<'static, 'static, ()>(&());
-    //~^ ERROR this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
-    //~| ERROR this struct takes 0
+    //~^ ERROR struct takes 1 lifetime argument but 2 lifetime arguments were supplied
+    //~| ERROR struct takes 0
 }
diff --git a/tests/ui/generics/generic-arg-mismatch-recover.stderr b/tests/ui/generics/generic-arg-mismatch-recover.stderr
index 45fea925f27..f549a7180fc 100644
--- a/tests/ui/generics/generic-arg-mismatch-recover.stderr
+++ b/tests/ui/generics/generic-arg-mismatch-recover.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/generic-arg-mismatch-recover.rs:6:5
    |
 LL |     Foo::<'static, 'static, ()>(&0);
@@ -12,7 +12,7 @@ note: struct defined here, with 1 lifetime parameter: `'a`
 LL | struct Foo<'a, T: 'a>(&'a T);
    |        ^^^ --
 
-error[E0107]: this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/generic-arg-mismatch-recover.rs:9:5
    |
 LL |     Bar::<'static, 'static, ()>(&());
@@ -26,7 +26,7 @@ note: struct defined here, with 1 lifetime parameter: `'a`
 LL | struct Bar<'a>(&'a ());
    |        ^^^ --
 
-error[E0107]: this struct takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/generic-arg-mismatch-recover.rs:9:5
    |
 LL |     Bar::<'static, 'static, ()>(&());
diff --git a/tests/ui/generics/generic-impl-less-params-with-defaults.rs b/tests/ui/generics/generic-impl-less-params-with-defaults.rs
index 66afbb58ad4..6c00411561e 100644
--- a/tests/ui/generics/generic-impl-less-params-with-defaults.rs
+++ b/tests/ui/generics/generic-impl-less-params-with-defaults.rs
@@ -9,5 +9,5 @@ impl<A, B, C> Foo<A, B, C> {
 
 fn main() {
     Foo::<isize>::new();
-    //~^ ERROR this struct takes at least 2 generic arguments but 1 generic argument
+    //~^ ERROR struct takes at least 2 generic arguments but 1 generic argument
 }
diff --git a/tests/ui/generics/generic-impl-less-params-with-defaults.stderr b/tests/ui/generics/generic-impl-less-params-with-defaults.stderr
index cdbb57902e4..262561fa81e 100644
--- a/tests/ui/generics/generic-impl-less-params-with-defaults.stderr
+++ b/tests/ui/generics/generic-impl-less-params-with-defaults.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes at least 2 generic arguments but 1 generic argument was supplied
+error[E0107]: struct takes at least 2 generic arguments but 1 generic argument was supplied
   --> $DIR/generic-impl-less-params-with-defaults.rs:11:5
    |
 LL |     Foo::<isize>::new();
diff --git a/tests/ui/generics/generic-impl-more-params-with-defaults.rs b/tests/ui/generics/generic-impl-more-params-with-defaults.rs
index a283323742a..be633ec464f 100644
--- a/tests/ui/generics/generic-impl-more-params-with-defaults.rs
+++ b/tests/ui/generics/generic-impl-more-params-with-defaults.rs
@@ -11,5 +11,5 @@ impl<T, A> Vec<T, A> {
 
 fn main() {
     Vec::<isize, Heap, bool>::new();
-    //~^ ERROR this struct takes at most 2 generic arguments but 3 generic arguments were supplied
+    //~^ ERROR struct takes at most 2 generic arguments but 3 generic arguments were supplied
 }
diff --git a/tests/ui/generics/generic-impl-more-params-with-defaults.stderr b/tests/ui/generics/generic-impl-more-params-with-defaults.stderr
index fe9b670da79..2f4682c4e5a 100644
--- a/tests/ui/generics/generic-impl-more-params-with-defaults.stderr
+++ b/tests/ui/generics/generic-impl-more-params-with-defaults.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes at most 2 generic arguments but 3 generic arguments were supplied
+error[E0107]: struct takes at most 2 generic arguments but 3 generic arguments were supplied
   --> $DIR/generic-impl-more-params-with-defaults.rs:13:5
    |
 LL |     Vec::<isize, Heap, bool>::new();
diff --git a/tests/ui/generics/generic-type-more-params-with-defaults.rs b/tests/ui/generics/generic-type-more-params-with-defaults.rs
index 3dab03297c9..b83fdb5c455 100644
--- a/tests/ui/generics/generic-type-more-params-with-defaults.rs
+++ b/tests/ui/generics/generic-type-more-params-with-defaults.rs
@@ -7,5 +7,5 @@ struct Vec<T, A = Heap>(
 
 fn main() {
     let _: Vec<isize, Heap, bool>;
-    //~^ ERROR this struct takes at most 2 generic arguments but 3 generic arguments
+    //~^ ERROR struct takes at most 2 generic arguments but 3 generic arguments
 }
diff --git a/tests/ui/generics/generic-type-more-params-with-defaults.stderr b/tests/ui/generics/generic-type-more-params-with-defaults.stderr
index 7f0198f0e84..4d01ba1f453 100644
--- a/tests/ui/generics/generic-type-more-params-with-defaults.stderr
+++ b/tests/ui/generics/generic-type-more-params-with-defaults.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes at most 2 generic arguments but 3 generic arguments were supplied
+error[E0107]: struct takes at most 2 generic arguments but 3 generic arguments were supplied
   --> $DIR/generic-type-more-params-with-defaults.rs:9:12
    |
 LL |     let _: Vec<isize, Heap, bool>;
diff --git a/tests/ui/generics/wrong-number-of-args.rs b/tests/ui/generics/wrong-number-of-args.rs
index cd2f96a1819..e4eaff21af1 100644
--- a/tests/ui/generics/wrong-number-of-args.rs
+++ b/tests/ui/generics/wrong-number-of-args.rs
@@ -4,18 +4,18 @@ mod no_generics {
     type A = Ty;
 
     type B = Ty<'static>;
-    //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument
+    //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument
     //~| HELP remove these generics
 
     type C = Ty<'static, usize>;
-    //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument
-    //~| ERROR this struct takes 0 generic arguments but 1 generic argument
+    //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument
+    //~| ERROR struct takes 0 generic arguments but 1 generic argument
     //~| HELP remove this lifetime argument
     //~| HELP remove this generic argument
 
     type D = Ty<'static, usize, { 0 }>;
-    //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument
-    //~| ERROR this struct takes 0 generic arguments but 2 generic arguments
+    //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument
+    //~| ERROR struct takes 0 generic arguments but 2 generic arguments
     //~| HELP remove this lifetime argument
     //~| HELP remove these generic arguments
 }
@@ -28,17 +28,17 @@ mod type_and_type {
     //~| HELP add missing
 
     type B = Ty<usize>;
-    //~^ ERROR this struct takes 2 generic arguments but 1 generic argument
+    //~^ ERROR struct takes 2 generic arguments but 1 generic argument
     //~| HELP add missing
 
     type C = Ty<usize, String>;
 
     type D = Ty<usize, String, char>;
-    //~^ ERROR this struct takes 2 generic arguments but 3 generic arguments
+    //~^ ERROR struct takes 2 generic arguments but 3 generic arguments
     //~| HELP remove this
 
     type E = Ty<>;
-    //~^ ERROR this struct takes 2 generic arguments but 0 generic arguments were supplied
+    //~^ ERROR struct takes 2 generic arguments but 0 generic arguments were supplied
     //~| HELP add missing
 }
 
@@ -52,7 +52,7 @@ mod lifetime_and_type {
     //~| HELP consider introducing
 
     type B = Ty<'static>;
-    //~^ ERROR this struct takes 1 generic argument but 0 generic arguments
+    //~^ ERROR struct takes 1 generic argument but 0 generic arguments
     //~| HELP add missing
 
     type C = Ty<usize>;
@@ -62,14 +62,14 @@ mod lifetime_and_type {
     type D = Ty<'static, usize>;
 
     type E = Ty<>;
-    //~^ ERROR this struct takes 1 generic argument but 0 generic arguments
+    //~^ ERROR struct takes 1 generic argument but 0 generic arguments
     //~| ERROR missing lifetime specifier
     //~| HELP consider introducing
     //~| HELP add missing
 
     type F = Ty<'static, usize, 'static, usize>;
-    //~^ ERROR this struct takes 1 lifetime argument but 2 lifetime arguments
-    //~| ERROR this struct takes 1 generic argument but 2 generic arguments
+    //~^ ERROR struct takes 1 lifetime argument but 2 lifetime arguments
+    //~| ERROR struct takes 1 generic argument but 2 generic arguments
     //~| HELP remove this lifetime argument
     //~| HELP remove this generic argument
 }
@@ -82,7 +82,7 @@ mod type_and_type_and_type {
     //~| HELP add missing
 
     type B = Ty<usize>;
-    //~^ ERROR this struct takes at least 2
+    //~^ ERROR struct takes at least 2
     //~| HELP add missing
 
     type C = Ty<usize, String>;
@@ -90,11 +90,11 @@ mod type_and_type_and_type {
     type D = Ty<usize, String, char>;
 
     type E = Ty<usize, String, char, f64>;
-    //~^ ERROR this struct takes at most 3
+    //~^ ERROR struct takes at most 3
     //~| HELP remove
 
     type F = Ty<>;
-    //~^ ERROR this struct takes at least 2 generic arguments but 0 generic arguments
+    //~^ ERROR struct takes at least 2 generic arguments but 0 generic arguments
     //~| HELP add missing
 }
 
@@ -114,7 +114,7 @@ mod r#trait {
     }
 
     type A = Box<dyn NonGeneric<usize>>;
-    //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+    //~^ ERROR trait takes 0 generic arguments but 1 generic argument
     //~| HELP remove
 
     type B = Box<dyn GenericLifetime>;
@@ -123,7 +123,7 @@ mod r#trait {
     //~| HELP consider making the bound lifetime-generic
 
     type C = Box<dyn GenericLifetime<'static, 'static>>;
-    //~^ ERROR this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+    //~^ ERROR trait takes 1 lifetime argument but 2 lifetime arguments were supplied
     //~| HELP remove
 
     type D = Box<dyn GenericType>;
@@ -131,7 +131,7 @@ mod r#trait {
     //~| HELP add missing
 
     type E = Box<dyn GenericType<String, usize>>;
-    //~^ ERROR this trait takes 1 generic argument but 2 generic arguments
+    //~^ ERROR trait takes 1 generic argument but 2 generic arguments
     //~| HELP remove
 
     type F = Box<dyn GenericLifetime<>>;
@@ -140,7 +140,7 @@ mod r#trait {
     //~| HELP consider making the bound lifetime-generic
 
     type G = Box<dyn GenericType<>>;
-    //~^ ERROR this trait takes 1 generic argument but 0 generic arguments
+    //~^ ERROR trait takes 1 generic argument but 0 generic arguments
     //~| HELP add missing
 }
 
@@ -151,7 +151,7 @@ mod associated_item {
         }
 
         type A = Box<dyn NonGenericAT<usize, AssocTy=()>>;
-        //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+        //~^ ERROR trait takes 0 generic arguments but 1 generic argument
         //~| HELP remove
     }
 
@@ -166,14 +166,14 @@ mod associated_item {
         //~| HELP consider making the bound lifetime-generic
 
         type B = Box<dyn GenericLifetimeAT<'static, 'static, AssocTy=()>>;
-        //~^ ERROR this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+        //~^ ERROR trait takes 1 lifetime argument but 2 lifetime arguments were supplied
         //~| HELP remove
 
         type C = Box<dyn GenericLifetimeAT<(), AssocTy=()>>;
         //~^ ERROR missing lifetime specifier
         //~| HELP consider introducing
         //~| HELP consider making the bound lifetime-generic
-        //~| ERROR this trait takes 0 generic arguments but 1 generic argument
+        //~| ERROR trait takes 0 generic arguments but 1 generic argument
         //~| HELP remove
     }
 
@@ -183,17 +183,17 @@ mod associated_item {
         }
 
         type A = Box<dyn GenericTypeAT<AssocTy=()>>;
-        //~^ ERROR this trait takes 1 generic argument but 0 generic arguments
+        //~^ ERROR trait takes 1 generic argument but 0 generic arguments
         //~| HELP add missing
 
         type B = Box<dyn GenericTypeAT<(), (), AssocTy=()>>;
-        //~^ ERROR this trait takes 1 generic argument but 2 generic arguments
+        //~^ ERROR trait takes 1 generic argument but 2 generic arguments
         //~| HELP remove
 
         type C = Box<dyn GenericTypeAT<'static, AssocTy=()>>;
-        //~^ ERROR this trait takes 1 generic argument but 0 generic arguments
+        //~^ ERROR trait takes 1 generic argument but 0 generic arguments
         //~| HELP add missing
-        //~| ERROR this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
+        //~| ERROR trait takes 0 lifetime arguments but 1 lifetime argument was supplied
         //~| HELP remove
     }
 
@@ -203,20 +203,20 @@ mod associated_item {
         }
 
         type A = Box<dyn GenericLifetimeTypeAT<AssocTy=()>>;
-        //~^ ERROR this trait takes 1 generic argument but 0 generic arguments
+        //~^ ERROR trait takes 1 generic argument but 0 generic arguments
         //~| HELP add missing
         //~| ERROR missing lifetime specifier
         //~| HELP consider introducing
         //~| HELP consider making the bound lifetime-generic
 
         type B = Box<dyn GenericLifetimeTypeAT<'static, AssocTy=()>>;
-        //~^ ERROR this trait takes 1 generic argument but 0 generic arguments were supplied
+        //~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied
         //~| HELP add missing
 
         type C = Box<dyn GenericLifetimeTypeAT<'static, 'static, AssocTy=()>>;
-        //~^ ERROR this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+        //~^ ERROR trait takes 1 lifetime argument but 2 lifetime arguments were supplied
         //~| HELP remove
-        //~| ERROR this trait takes 1 generic argument but 0 generic arguments
+        //~| ERROR trait takes 1 generic argument but 0 generic arguments
         //~| HELP add missing
 
         type D = Box<dyn GenericLifetimeTypeAT<(), AssocTy=()>>;
@@ -228,21 +228,21 @@ mod associated_item {
         //~^ ERROR missing lifetime specifier
         //~| HELP consider introducing
         //~| HELP consider making the bound lifetime-generic
-        //~| ERROR this trait takes 1 generic argument but 2 generic arguments
+        //~| ERROR trait takes 1 generic argument but 2 generic arguments
         //~| HELP remove
 
         type F = Box<dyn GenericLifetimeTypeAT<'static, 'static, (), AssocTy=()>>;
-        //~^ ERROR this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+        //~^ ERROR trait takes 1 lifetime argument but 2 lifetime arguments were supplied
         //~| HELP remove
 
         type G = Box<dyn GenericLifetimeTypeAT<'static, (), (), AssocTy=()>>;
-        //~^ ERROR this trait takes 1 generic argument but 2 generic arguments
+        //~^ ERROR trait takes 1 generic argument but 2 generic arguments
         //~| HELP remove
 
         type H = Box<dyn GenericLifetimeTypeAT<'static, 'static, (), (), AssocTy=()>>;
-        //~^ ERROR this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+        //~^ ERROR trait takes 1 lifetime argument but 2 lifetime arguments were supplied
         //~| HELP remove
-        //~| ERROR this trait takes 1 generic argument but 2 generic arguments
+        //~| ERROR trait takes 1 generic argument but 2 generic arguments
         //~| HELP remove
     }
 
@@ -252,15 +252,15 @@ mod associated_item {
         }
 
         type A = Box<dyn GenericTypeTypeAT<AssocTy=()>>;
-        //~^ ERROR this trait takes 2 generic arguments but 0 generic arguments
+        //~^ ERROR trait takes 2 generic arguments but 0 generic arguments
         //~| HELP add missing
 
         type B = Box<dyn GenericTypeTypeAT<(), AssocTy=()>>;
-        //~^ ERROR this trait takes 2 generic arguments but 1 generic argument
+        //~^ ERROR trait takes 2 generic arguments but 1 generic argument
         //~| HELP add missing
 
         type C = Box<dyn GenericTypeTypeAT<(), (), (), AssocTy=()>>;
-        //~^ ERROR this trait takes 2 generic arguments but 3 generic arguments
+        //~^ ERROR trait takes 2 generic arguments but 3 generic arguments
         //~| HELP remove
     }
 
@@ -275,7 +275,7 @@ mod associated_item {
         //~| HELP consider making the bound lifetime-generic
 
         type B = Box<dyn GenericLifetimeLifetimeAT<'static, AssocTy=()>>;
-        //~^ ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+        //~^ ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied
         //~| HELP add missing lifetime argument
     }
 
@@ -288,17 +288,17 @@ mod associated_item {
         //~^ ERROR missing lifetime specifier
         //~| HELP consider introducing
         //~| HELP consider making the bound lifetime-generic
-        //~| ERROR this trait takes 1 generic argument but 0 generic arguments
+        //~| ERROR trait takes 1 generic argument but 0 generic arguments
         //~| HELP add missing
 
         type B = Box<dyn GenericLifetimeLifetimeTypeAT<'static, AssocTy=()>>;
-        //~^ ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+        //~^ ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied
         //~| HELP add missing lifetime argument
-        //~| ERROR this trait takes 1 generic argument but 0 generic arguments
+        //~| ERROR trait takes 1 generic argument but 0 generic arguments
         //~| HELP add missing
 
         type C = Box<dyn GenericLifetimeLifetimeTypeAT<'static, (), AssocTy=()>>;
-        //~^ ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+        //~^ ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied
         //~| HELP add missing lifetime argument
     }
 }
@@ -312,21 +312,21 @@ mod stdlib {
         //~| HELP add missing
 
         type B = HashMap<String>;
-        //~^ ERROR this struct takes at least
+        //~^ ERROR struct takes at least
         //~| HELP add missing
 
         type C = HashMap<'static>;
-        //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument
+        //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument
         //~| HELP remove these generics
-        //~| ERROR this struct takes at least 2
+        //~| ERROR struct takes at least 2
         //~| HELP add missing
 
         type D = HashMap<usize, String, char, f64>;
-        //~^ ERROR this struct takes at most 3
+        //~^ ERROR struct takes at most 3
         //~| HELP remove this
 
         type E = HashMap<>;
-        //~^ ERROR this struct takes at least 2 generic arguments but 0 generic arguments
+        //~^ ERROR struct takes at least 2 generic arguments but 0 generic arguments
         //~| HELP add missing
     }
 
@@ -336,21 +336,21 @@ mod stdlib {
         //~| HELP add missing
 
         type B = Result<String>;
-        //~^ ERROR this enum takes 2 generic arguments but 1 generic argument
+        //~^ ERROR enum takes 2 generic arguments but 1 generic argument
         //~| HELP add missing
 
         type C = Result<'static>;
-        //~^ ERROR this enum takes 0 lifetime arguments but 1 lifetime argument
+        //~^ ERROR enum takes 0 lifetime arguments but 1 lifetime argument
         //~| HELP remove these generics
-        //~| ERROR this enum takes 2 generic arguments but 0 generic arguments
+        //~| ERROR enum takes 2 generic arguments but 0 generic arguments
         //~| HELP add missing
 
         type D = Result<usize, String, char>;
-        //~^ ERROR this enum takes 2 generic arguments but 3 generic arguments
+        //~^ ERROR enum takes 2 generic arguments but 3 generic arguments
         //~| HELP remove
 
         type E = Result<>;
-        //~^ ERROR this enum takes 2 generic arguments but 0 generic arguments
+        //~^ ERROR enum takes 2 generic arguments but 0 generic arguments
         //~| HELP add missing
     }
 }
diff --git a/tests/ui/generics/wrong-number-of-args.stderr b/tests/ui/generics/wrong-number-of-args.stderr
index 75e33f680ea..9006fb10b67 100644
--- a/tests/ui/generics/wrong-number-of-args.stderr
+++ b/tests/ui/generics/wrong-number-of-args.stderr
@@ -167,7 +167,7 @@ help: consider introducing a named lifetime parameter
 LL |         type A<'a> = Box<dyn GenericLifetimeLifetimeTypeAT<'a, 'a, AssocTy=()>>;
    |               ++++                                         +++++++
 
-error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/wrong-number-of-args.rs:6:14
    |
 LL |     type B = Ty<'static>;
@@ -181,7 +181,7 @@ note: struct defined here, with 0 lifetime parameters
 LL |     struct Ty;
    |            ^^
 
-error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/wrong-number-of-args.rs:10:14
    |
 LL |     type C = Ty<'static, usize>;
@@ -195,7 +195,7 @@ note: struct defined here, with 0 lifetime parameters
 LL |     struct Ty;
    |            ^^
 
-error[E0107]: this struct takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/wrong-number-of-args.rs:10:14
    |
 LL |     type C = Ty<'static, usize>;
@@ -209,7 +209,7 @@ note: struct defined here, with 0 generic parameters
 LL |     struct Ty;
    |            ^^
 
-error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/wrong-number-of-args.rs:16:14
    |
 LL |     type D = Ty<'static, usize, { 0 }>;
@@ -223,7 +223,7 @@ note: struct defined here, with 0 lifetime parameters
 LL |     struct Ty;
    |            ^^
 
-error[E0107]: this struct takes 0 generic arguments but 2 generic arguments were supplied
+error[E0107]: struct takes 0 generic arguments but 2 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:16:14
    |
 LL |     type D = Ty<'static, usize, { 0 }>;
@@ -253,7 +253,7 @@ help: add missing generic arguments
 LL |     type A = Ty<A, B>;
    |                ++++++
 
-error[E0107]: this struct takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: struct takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/wrong-number-of-args.rs:30:14
    |
 LL |     type B = Ty<usize>;
@@ -271,7 +271,7 @@ help: add missing generic argument
 LL |     type B = Ty<usize, B>;
    |                      +++
 
-error[E0107]: this struct takes 2 generic arguments but 3 generic arguments were supplied
+error[E0107]: struct takes 2 generic arguments but 3 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:36:14
    |
 LL |     type D = Ty<usize, String, char>;
@@ -285,7 +285,7 @@ note: struct defined here, with 2 generic parameters: `A`, `B`
 LL |     struct Ty<A, B>;
    |            ^^ -  -
 
-error[E0107]: this struct takes 2 generic arguments but 0 generic arguments were supplied
+error[E0107]: struct takes 2 generic arguments but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:40:14
    |
 LL |     type E = Ty<>;
@@ -317,7 +317,7 @@ help: add missing generic argument
 LL |     type A = Ty<T>;
    |                +++
 
-error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:54:14
    |
 LL |     type B = Ty<'static>;
@@ -333,7 +333,7 @@ help: add missing generic argument
 LL |     type B = Ty<'static, T>;
    |                        +++
 
-error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:64:14
    |
 LL |     type E = Ty<>;
@@ -349,7 +349,7 @@ help: add missing generic argument
 LL |     type E = Ty<T>;
    |                 +
 
-error[E0107]: this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/wrong-number-of-args.rs:70:14
    |
 LL |     type F = Ty<'static, usize, 'static, usize>;
@@ -363,7 +363,7 @@ note: struct defined here, with 1 lifetime parameter: `'a`
 LL |     struct Ty<'a, T>;
    |            ^^ --
 
-error[E0107]: this struct takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:70:14
    |
 LL |     type F = Ty<'static, usize, 'static, usize>;
@@ -393,7 +393,7 @@ help: add missing generic arguments
 LL |     type A = Ty<A, B>;
    |                ++++++
 
-error[E0107]: this struct takes at least 2 generic arguments but 1 generic argument was supplied
+error[E0107]: struct takes at least 2 generic arguments but 1 generic argument was supplied
   --> $DIR/wrong-number-of-args.rs:84:14
    |
 LL |     type B = Ty<usize>;
@@ -411,7 +411,7 @@ help: add missing generic argument
 LL |     type B = Ty<usize, B>;
    |                      +++
 
-error[E0107]: this struct takes at most 3 generic arguments but 4 generic arguments were supplied
+error[E0107]: struct takes at most 3 generic arguments but 4 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:92:14
    |
 LL |     type E = Ty<usize, String, char, f64>;
@@ -425,7 +425,7 @@ note: struct defined here, with at most 3 generic parameters: `A`, `B`, `C`
 LL |     struct Ty<A, B, C = &'static str>;
    |            ^^ -  -  ----------------
 
-error[E0107]: this struct takes at least 2 generic arguments but 0 generic arguments were supplied
+error[E0107]: struct takes at least 2 generic arguments but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:96:14
    |
 LL |     type F = Ty<>;
@@ -441,7 +441,7 @@ help: add missing generic arguments
 LL |     type F = Ty<A, B>;
    |                 ++++
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/wrong-number-of-args.rs:116:22
    |
 LL |     type A = Box<dyn NonGeneric<usize>>;
@@ -455,7 +455,7 @@ note: trait defined here, with 0 generic parameters
 LL |     trait NonGeneric {
    |           ^^^^^^^^^^
 
-error[E0107]: this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: trait takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/wrong-number-of-args.rs:125:22
    |
 LL |     type C = Box<dyn GenericLifetime<'static, 'static>>;
@@ -485,7 +485,7 @@ help: add missing generic argument
 LL |     type D = Box<dyn GenericType<A>>;
    |                                 +++
 
-error[E0107]: this trait takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:133:22
    |
 LL |     type E = Box<dyn GenericType<String, usize>>;
@@ -499,7 +499,7 @@ note: trait defined here, with 1 generic parameter: `A`
 LL |     trait GenericType<A> {
    |           ^^^^^^^^^^^ -
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:142:22
    |
 LL |     type G = Box<dyn GenericType<>>;
@@ -515,7 +515,7 @@ help: add missing generic argument
 LL |     type G = Box<dyn GenericType<A>>;
    |                                  +
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/wrong-number-of-args.rs:153:26
    |
 LL |         type A = Box<dyn NonGenericAT<usize, AssocTy=()>>;
@@ -529,7 +529,7 @@ note: trait defined here, with 0 generic parameters
 LL |         trait NonGenericAT {
    |               ^^^^^^^^^^^^
 
-error[E0107]: this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: trait takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/wrong-number-of-args.rs:168:26
    |
 LL |         type B = Box<dyn GenericLifetimeAT<'static, 'static, AssocTy=()>>;
@@ -543,7 +543,7 @@ note: trait defined here, with 1 lifetime parameter: `'a`
 LL |         trait GenericLifetimeAT<'a> {
    |               ^^^^^^^^^^^^^^^^^ --
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/wrong-number-of-args.rs:172:26
    |
 LL |         type C = Box<dyn GenericLifetimeAT<(), AssocTy=()>>;
@@ -557,7 +557,7 @@ note: trait defined here, with 0 generic parameters
 LL |         trait GenericLifetimeAT<'a> {
    |               ^^^^^^^^^^^^^^^^^
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:185:26
    |
 LL |         type A = Box<dyn GenericTypeAT<AssocTy=()>>;
@@ -573,7 +573,7 @@ help: add missing generic argument
 LL |         type A = Box<dyn GenericTypeAT<A, AssocTy=()>>;
    |                                        ++
 
-error[E0107]: this trait takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:189:26
    |
 LL |         type B = Box<dyn GenericTypeAT<(), (), AssocTy=()>>;
@@ -587,7 +587,7 @@ note: trait defined here, with 1 generic parameter: `A`
 LL |         trait GenericTypeAT<A> {
    |               ^^^^^^^^^^^^^ -
 
-error[E0107]: this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/wrong-number-of-args.rs:193:26
    |
 LL |         type C = Box<dyn GenericTypeAT<'static, AssocTy=()>>;
@@ -601,7 +601,7 @@ note: trait defined here, with 0 lifetime parameters
 LL |         trait GenericTypeAT<A> {
    |               ^^^^^^^^^^^^^
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:193:26
    |
 LL |         type C = Box<dyn GenericTypeAT<'static, AssocTy=()>>;
@@ -617,7 +617,7 @@ help: add missing generic argument
 LL |         type C = Box<dyn GenericTypeAT<'static, A, AssocTy=()>>;
    |                                               +++
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:205:26
    |
 LL |         type A = Box<dyn GenericLifetimeTypeAT<AssocTy=()>>;
@@ -633,7 +633,7 @@ help: add missing generic argument
 LL |         type A = Box<dyn GenericLifetimeTypeAT<A, AssocTy=()>>;
    |                                                ++
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:212:26
    |
 LL |         type B = Box<dyn GenericLifetimeTypeAT<'static, AssocTy=()>>;
@@ -649,7 +649,7 @@ help: add missing generic argument
 LL |         type B = Box<dyn GenericLifetimeTypeAT<'static, A, AssocTy=()>>;
    |                                                       +++
 
-error[E0107]: this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: trait takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/wrong-number-of-args.rs:216:26
    |
 LL |         type C = Box<dyn GenericLifetimeTypeAT<'static, 'static, AssocTy=()>>;
@@ -663,7 +663,7 @@ note: trait defined here, with 1 lifetime parameter: `'a`
 LL |         trait GenericLifetimeTypeAT<'a, A> {
    |               ^^^^^^^^^^^^^^^^^^^^^ --
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:216:26
    |
 LL |         type C = Box<dyn GenericLifetimeTypeAT<'static, 'static, AssocTy=()>>;
@@ -679,7 +679,7 @@ help: add missing generic argument
 LL |         type C = Box<dyn GenericLifetimeTypeAT<'static, 'static, A, AssocTy=()>>;
    |                                                                +++
 
-error[E0107]: this trait takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:227:26
    |
 LL |         type E = Box<dyn GenericLifetimeTypeAT<(), (), AssocTy=()>>;
@@ -693,7 +693,7 @@ note: trait defined here, with 1 generic parameter: `A`
 LL |         trait GenericLifetimeTypeAT<'a, A> {
    |               ^^^^^^^^^^^^^^^^^^^^^     -
 
-error[E0107]: this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: trait takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/wrong-number-of-args.rs:234:26
    |
 LL |         type F = Box<dyn GenericLifetimeTypeAT<'static, 'static, (), AssocTy=()>>;
@@ -707,7 +707,7 @@ note: trait defined here, with 1 lifetime parameter: `'a`
 LL |         trait GenericLifetimeTypeAT<'a, A> {
    |               ^^^^^^^^^^^^^^^^^^^^^ --
 
-error[E0107]: this trait takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:238:26
    |
 LL |         type G = Box<dyn GenericLifetimeTypeAT<'static, (), (), AssocTy=()>>;
@@ -721,7 +721,7 @@ note: trait defined here, with 1 generic parameter: `A`
 LL |         trait GenericLifetimeTypeAT<'a, A> {
    |               ^^^^^^^^^^^^^^^^^^^^^     -
 
-error[E0107]: this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: trait takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/wrong-number-of-args.rs:242:26
    |
 LL |         type H = Box<dyn GenericLifetimeTypeAT<'static, 'static, (), (), AssocTy=()>>;
@@ -735,7 +735,7 @@ note: trait defined here, with 1 lifetime parameter: `'a`
 LL |         trait GenericLifetimeTypeAT<'a, A> {
    |               ^^^^^^^^^^^^^^^^^^^^^ --
 
-error[E0107]: this trait takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:242:26
    |
 LL |         type H = Box<dyn GenericLifetimeTypeAT<'static, 'static, (), (), AssocTy=()>>;
@@ -749,7 +749,7 @@ note: trait defined here, with 1 generic parameter: `A`
 LL |         trait GenericLifetimeTypeAT<'a, A> {
    |               ^^^^^^^^^^^^^^^^^^^^^     -
 
-error[E0107]: this trait takes 2 generic arguments but 0 generic arguments were supplied
+error[E0107]: trait takes 2 generic arguments but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:254:26
    |
 LL |         type A = Box<dyn GenericTypeTypeAT<AssocTy=()>>;
@@ -765,7 +765,7 @@ help: add missing generic arguments
 LL |         type A = Box<dyn GenericTypeTypeAT<A, B, AssocTy=()>>;
    |                                            +++++
 
-error[E0107]: this trait takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/wrong-number-of-args.rs:258:26
    |
 LL |         type B = Box<dyn GenericTypeTypeAT<(), AssocTy=()>>;
@@ -783,7 +783,7 @@ help: add missing generic argument
 LL |         type B = Box<dyn GenericTypeTypeAT<(), B, AssocTy=()>>;
    |                                              +++
 
-error[E0107]: this trait takes 2 generic arguments but 3 generic arguments were supplied
+error[E0107]: trait takes 2 generic arguments but 3 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:262:26
    |
 LL |         type C = Box<dyn GenericTypeTypeAT<(), (), (), AssocTy=()>>;
@@ -797,7 +797,7 @@ note: trait defined here, with 2 generic parameters: `A`, `B`
 LL |         trait GenericTypeTypeAT<A, B> {
    |               ^^^^^^^^^^^^^^^^^ -  -
 
-error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/wrong-number-of-args.rs:277:26
    |
 LL |         type B = Box<dyn GenericLifetimeLifetimeAT<'static, AssocTy=()>>;
@@ -815,7 +815,7 @@ help: add missing lifetime argument
 LL |         type B = Box<dyn GenericLifetimeLifetimeAT<'static, 'static, AssocTy=()>>;
    |                                                           +++++++++
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:287:26
    |
 LL |         type A = Box<dyn GenericLifetimeLifetimeTypeAT<AssocTy=()>>;
@@ -831,7 +831,7 @@ help: add missing generic argument
 LL |         type A = Box<dyn GenericLifetimeLifetimeTypeAT<A, AssocTy=()>>;
    |                                                        ++
 
-error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/wrong-number-of-args.rs:294:26
    |
 LL |         type B = Box<dyn GenericLifetimeLifetimeTypeAT<'static, AssocTy=()>>;
@@ -849,7 +849,7 @@ help: add missing lifetime argument
 LL |         type B = Box<dyn GenericLifetimeLifetimeTypeAT<'static, 'static, AssocTy=()>>;
    |                                                               +++++++++
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:294:26
    |
 LL |         type B = Box<dyn GenericLifetimeLifetimeTypeAT<'static, AssocTy=()>>;
@@ -865,7 +865,7 @@ help: add missing generic argument
 LL |         type B = Box<dyn GenericLifetimeLifetimeTypeAT<'static, A, AssocTy=()>>;
    |                                                               +++
 
-error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/wrong-number-of-args.rs:300:26
    |
 LL |         type C = Box<dyn GenericLifetimeLifetimeTypeAT<'static, (), AssocTy=()>>;
@@ -894,7 +894,7 @@ help: add missing generic arguments
 LL |         type A = HashMap<K, V>;
    |                         ++++++
 
-error[E0107]: this struct takes at least 2 generic arguments but 1 generic argument was supplied
+error[E0107]: struct takes at least 2 generic arguments but 1 generic argument was supplied
   --> $DIR/wrong-number-of-args.rs:314:18
    |
 LL |         type B = HashMap<String>;
@@ -907,7 +907,7 @@ help: add missing generic argument
 LL |         type B = HashMap<String, V>;
    |                                +++
 
-error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/wrong-number-of-args.rs:318:18
    |
 LL |         type C = HashMap<'static>;
@@ -915,7 +915,7 @@ LL |         type C = HashMap<'static>;
    |                  |
    |                  expected 0 lifetime arguments
 
-error[E0107]: this struct takes at least 2 generic arguments but 0 generic arguments were supplied
+error[E0107]: struct takes at least 2 generic arguments but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:318:18
    |
 LL |         type C = HashMap<'static>;
@@ -926,7 +926,7 @@ help: add missing generic arguments
 LL |         type C = HashMap<'static, K, V>;
    |                                 ++++++
 
-error[E0107]: this struct takes at most 3 generic arguments but 4 generic arguments were supplied
+error[E0107]: struct takes at most 3 generic arguments but 4 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:324:18
    |
 LL |         type D = HashMap<usize, String, char, f64>;
@@ -934,7 +934,7 @@ LL |         type D = HashMap<usize, String, char, f64>;
    |                  |
    |                  expected at most 3 generic arguments
 
-error[E0107]: this struct takes at least 2 generic arguments but 0 generic arguments were supplied
+error[E0107]: struct takes at least 2 generic arguments but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:328:18
    |
 LL |         type E = HashMap<>;
@@ -956,7 +956,7 @@ help: add missing generic arguments
 LL |         type A = Result<T, E>;
    |                        ++++++
 
-error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: enum takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/wrong-number-of-args.rs:338:18
    |
 LL |         type B = Result<String>;
@@ -969,7 +969,7 @@ help: add missing generic argument
 LL |         type B = Result<String, E>;
    |                               +++
 
-error[E0107]: this enum takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: enum takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/wrong-number-of-args.rs:342:18
    |
 LL |         type C = Result<'static>;
@@ -977,7 +977,7 @@ LL |         type C = Result<'static>;
    |                  |
    |                  expected 0 lifetime arguments
 
-error[E0107]: this enum takes 2 generic arguments but 0 generic arguments were supplied
+error[E0107]: enum takes 2 generic arguments but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:342:18
    |
 LL |         type C = Result<'static>;
@@ -988,7 +988,7 @@ help: add missing generic arguments
 LL |         type C = Result<'static, T, E>;
    |                                ++++++
 
-error[E0107]: this enum takes 2 generic arguments but 3 generic arguments were supplied
+error[E0107]: enum takes 2 generic arguments but 3 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:348:18
    |
 LL |         type D = Result<usize, String, char>;
@@ -996,7 +996,7 @@ LL |         type D = Result<usize, String, char>;
    |                  |
    |                  expected 2 generic arguments
 
-error[E0107]: this enum takes 2 generic arguments but 0 generic arguments were supplied
+error[E0107]: enum takes 2 generic arguments but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:352:18
    |
 LL |         type E = Result<>;
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr
index 8cda76b9490..b1b8ffa8c54 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr
+++ b/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `want_bar_for_any_ccx`
   --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:32:15
    |
 LL | fn want_bar_for_any_ccx<B>(b: &B)
-   |    -------------------- required by a bound in this
+   |    -------------------- required by a bound in this function
 LL |     where B : for<'ccx> Bar<'ccx>
    |               ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx`
 help: consider further restricting this bound
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr
index 88793a1525b..7f96909b6e7 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr
+++ b/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `want_foo_for_any_tcx`
   --> $DIR/hrtb-higher-ranker-supertraits.rs:22:15
    |
 LL | fn want_foo_for_any_tcx<F>(f: &F)
-   |    -------------------- required by a bound in this
+   |    -------------------- required by a bound in this function
 LL |     where F : for<'tcx> Foo<'tcx>
    |               ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_foo_for_any_tcx`
 help: consider further restricting this bound
@@ -30,7 +30,7 @@ note: required by a bound in `want_bar_for_any_ccx`
   --> $DIR/hrtb-higher-ranker-supertraits.rs:39:15
    |
 LL | fn want_bar_for_any_ccx<B>(b: &B)
-   |    -------------------- required by a bound in this
+   |    -------------------- required by a bound in this function
 LL |     where B : for<'ccx> Bar<'ccx>
    |               ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx`
 help: consider further restricting this bound
diff --git a/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr b/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr
index 86198c3f7fd..4d470ae7022 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr
+++ b/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr
@@ -25,7 +25,7 @@ note: required by a bound in `T1::m`
   --> $DIR/issue-62203-hrtb-ice.rs:27:51
    |
 LL |     fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1
-   |        - required by a bound in this
+   |        - required by a bound in this associated function
 LL |     where
 LL |         F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>,
    |                                                   ^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m`
@@ -56,7 +56,7 @@ note: required by a bound in `T1::m`
   --> $DIR/issue-62203-hrtb-ice.rs:27:12
    |
 LL |     fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1
-   |        - required by a bound in this
+   |        - required by a bound in this associated function
 LL |     where
 LL |         F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>,
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m`
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr
index 62d0128fd85..edef6ccd34e 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr
+++ b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr
@@ -15,7 +15,7 @@ note: required by a bound in `StackContext`
   --> $DIR/issue-89118.rs:9:14
    |
 LL | trait StackContext
-   |       ------------ required by a bound in this
+   |       ------------ required by a bound in this trait
 LL | where
 LL |     Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>,
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StackContext`
@@ -37,7 +37,7 @@ note: required by a bound in `EthernetWorker`
   --> $DIR/issue-89118.rs:28:14
    |
 LL | struct EthernetWorker<C>(C)
-   |        -------------- required by a bound in this
+   |        -------------- required by a bound in this struct
 LL | where
 LL |     Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>;
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `EthernetWorker`
@@ -59,7 +59,7 @@ note: required by a bound in `StackContext`
   --> $DIR/issue-89118.rs:9:14
    |
 LL | trait StackContext
-   |       ------------ required by a bound in this
+   |       ------------ required by a bound in this trait
 LL | where
 LL |     Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>,
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StackContext`
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr
index 6206b167b0b..5be33bccdc3 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr
+++ b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr
@@ -11,7 +11,7 @@ note: required by a bound in `upcast`
   --> $DIR/issue-90950.rs:27:42
    |
 LL | fn upcast<Y>(x: Yoke<Y>) -> Yoke<Box<dyn IsCovariant<'static> + 'static>> where
-   |    ------ required by a bound in this
+   |    ------ required by a bound in this function
 LL |     Y: for<'a> Yokeable<'a>,
 LL |     for<'a> <Y as Yokeable<'a>>::Output: IsCovariant<'a>
    |                                          ^^^^^^^^^^^^^^^ required by this bound in `upcast`
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr
index 51c9646004a..73388a72574 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr
+++ b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr
@@ -8,7 +8,7 @@ note: required by a bound in `weird_bound`
   --> $DIR/norm-before-method-resolution.rs:18:40
    |
 LL | fn weird_bound<X>() -> X
-   |    ----------- required by a bound in this
+   |    ----------- required by a bound in this function
 ...
 LL |         for<'a> <X as Trait<'a>>::Out: Copy
    |                                        ^^^^ required by this bound in `weird_bound`
diff --git a/tests/ui/impl-trait/equal-hidden-lifetimes.rs b/tests/ui/impl-trait/equal-hidden-lifetimes.rs
index 79db88828b9..a6dbf3f08f2 100644
--- a/tests/ui/impl-trait/equal-hidden-lifetimes.rs
+++ b/tests/ui/impl-trait/equal-hidden-lifetimes.rs
@@ -5,7 +5,6 @@
 
 // `'a == 'static` so `&'a i32` is fine as the return type
 fn equal_regions_static<'a: 'static>(x: &'a i32) -> impl Sized {
-    //~^ WARNING unnecessary lifetime parameter `'a`
     x
 }
 
diff --git a/tests/ui/impl-trait/equal-hidden-lifetimes.stderr b/tests/ui/impl-trait/equal-hidden-lifetimes.stderr
deleted file mode 100644
index 3e48aef553b..00000000000
--- a/tests/ui/impl-trait/equal-hidden-lifetimes.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-warning: unnecessary lifetime parameter `'a`
-  --> $DIR/equal-hidden-lifetimes.rs:7:25
-   |
-LL | fn equal_regions_static<'a: 'static>(x: &'a i32) -> impl Sized {
-   |                         ^^
-   |
-   = help: you can use the `'static` lifetime directly, in place of `'a`
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr b/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr
index c8b82783ea8..9c101101870 100644
--- a/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr
+++ b/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this function takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: function takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/explicit-generic-args-for-impl.rs:4:5
    |
 LL |     foo::<str, String>("".to_string());
diff --git a/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr b/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr
index 9d6db88d364..a26460c8ecc 100644
--- a/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr
+++ b/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: function takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/not-enough-args.rs:4:5
    |
 LL |     f::<[u8]>("a", b"a");
diff --git a/tests/ui/impl-trait/in-trait/default-method-constraint.rs b/tests/ui/impl-trait/in-trait/default-method-constraint.rs
new file mode 100644
index 00000000000..8c50cc29586
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/default-method-constraint.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+// This didn't work in the previous default RPITIT method hack attempt
+
+#![feature(return_position_impl_trait_in_trait)]
+//~^ WARN the feature `return_position_impl_trait_in_trait` is incomplete
+
+trait Foo {
+    fn bar(x: bool) -> impl Sized {
+        if x {
+            let _: u32 = Self::bar(!x);
+        }
+        Default::default()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/default-method-constraint.stderr b/tests/ui/impl-trait/in-trait/default-method-constraint.stderr
new file mode 100644
index 00000000000..5e18605aa4c
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/default-method-constraint.stderr
@@ -0,0 +1,11 @@
+warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/default-method-constraint.rs:5:12
+   |
+LL | #![feature(return_position_impl_trait_in_trait)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/impl-trait/issues/issue-54600.stderr b/tests/ui/impl-trait/issues/issue-54600.stderr
index 316566a57a8..7ef063af952 100644
--- a/tests/ui/impl-trait/issues/issue-54600.stderr
+++ b/tests/ui/impl-trait/issues/issue-54600.stderr
@@ -1,4 +1,4 @@
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings
   --> $DIR/issue-54600.rs:4:19
    |
 LL |     let x: Option<impl Debug> = Some(44_u32);
diff --git a/tests/ui/impl-trait/issues/issue-54840.stderr b/tests/ui/impl-trait/issues/issue-54840.stderr
index 8d82133ac90..1d1316f0e11 100644
--- a/tests/ui/impl-trait/issues/issue-54840.stderr
+++ b/tests/ui/impl-trait/issues/issue-54840.stderr
@@ -1,4 +1,4 @@
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings
   --> $DIR/issue-54840.rs:5:13
    |
 LL |     let j: &impl Add = &i;
diff --git a/tests/ui/impl-trait/issues/issue-58504.stderr b/tests/ui/impl-trait/issues/issue-58504.stderr
index 6656e9fc3fb..26ec2a4f9cf 100644
--- a/tests/ui/impl-trait/issues/issue-58504.stderr
+++ b/tests/ui/impl-trait/issues/issue-58504.stderr
@@ -1,4 +1,4 @@
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings
   --> $DIR/issue-58504.rs:10:16
    |
 LL |     let gens: [impl Generator<Return=!, Yield=()>;2] = [ mk_gen(), mk_gen() ];
diff --git a/tests/ui/impl-trait/issues/issue-58956.stderr b/tests/ui/impl-trait/issues/issue-58956.stderr
index f591c07bcf5..2b4d0abdffc 100644
--- a/tests/ui/impl-trait/issues/issue-58956.stderr
+++ b/tests/ui/impl-trait/issues/issue-58956.stderr
@@ -1,10 +1,10 @@
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const types
   --> $DIR/issue-58956.rs:7:11
    |
 LL | const _A: impl Lam = {
    |           ^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings
   --> $DIR/issue-58956.rs:9:17
    |
 LL |     let x: Wrap<impl Lam> = Wrap(B);
diff --git a/tests/ui/impl-trait/issues/issue-70971.stderr b/tests/ui/impl-trait/issues/issue-70971.stderr
index 4dda4c22aa2..d066256bfb0 100644
--- a/tests/ui/impl-trait/issues/issue-70971.stderr
+++ b/tests/ui/impl-trait/issues/issue-70971.stderr
@@ -1,4 +1,4 @@
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings
   --> $DIR/issue-70971.rs:2:14
    |
 LL |     let x : (impl Copy,) = (true,);
diff --git a/tests/ui/impl-trait/issues/issue-79099.stderr b/tests/ui/impl-trait/issues/issue-79099.stderr
index 362c67dafd2..580250a62fe 100644
--- a/tests/ui/impl-trait/issues/issue-79099.stderr
+++ b/tests/ui/impl-trait/issues/issue-79099.stderr
@@ -9,7 +9,7 @@ LL |         let f: impl core::future::Future<Output = u8> = async { 1 };
    = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings
   --> $DIR/issue-79099.rs:3:16
    |
 LL |         let f: impl core::future::Future<Output = u8> = async { 1 };
diff --git a/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr b/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr
index a227f0ba7d1..656bd047061 100644
--- a/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr
+++ b/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr
@@ -1,10 +1,10 @@
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults
   --> $DIR/issue-83929-impl-trait-in-generic-default.rs:1:16
    |
 LL | struct Foo<T = impl Copy>(T);
    |                ^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults
   --> $DIR/issue-83929-impl-trait-in-generic-default.rs:4:20
    |
 LL | type Result<T, E = impl std::error::Error> = std::result::Result<T, E>;
diff --git a/tests/ui/impl-trait/issues/issue-84919.stderr b/tests/ui/impl-trait/issues/issue-84919.stderr
index 5abe1bd8779..36010fdef36 100644
--- a/tests/ui/impl-trait/issues/issue-84919.stderr
+++ b/tests/ui/impl-trait/issues/issue-84919.stderr
@@ -1,4 +1,4 @@
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings
   --> $DIR/issue-84919.rs:5:13
    |
 LL |     let _x: impl Trait = ();
diff --git a/tests/ui/impl-trait/issues/issue-86642.stderr b/tests/ui/impl-trait/issues/issue-86642.stderr
index a137777840b..b6f8a54f35a 100644
--- a/tests/ui/impl-trait/issues/issue-86642.stderr
+++ b/tests/ui/impl-trait/issues/issue-86642.stderr
@@ -1,4 +1,4 @@
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const types
   --> $DIR/issue-86642.rs:1:11
    |
 LL | static x: impl Fn(&str) -> Result<&str, ()> = move |source| {
diff --git a/tests/ui/impl-trait/issues/issue-87295.stderr b/tests/ui/impl-trait/issues/issue-87295.stderr
index 0b043056b84..ec59b719c10 100644
--- a/tests/ui/impl-trait/issues/issue-87295.stderr
+++ b/tests/ui/impl-trait/issues/issue-87295.stderr
@@ -1,4 +1,4 @@
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings
   --> $DIR/issue-87295.rs:16:31
    |
 LL |     let _do_not_waste: Struct<impl Trait<Output = i32>> = Struct::new(());
diff --git a/tests/ui/impl-trait/nested_impl_trait.stderr b/tests/ui/impl-trait/nested_impl_trait.stderr
index 9a8f5a34068..ffe84b8e86f 100644
--- a/tests/ui/impl-trait/nested_impl_trait.stderr
+++ b/tests/ui/impl-trait/nested_impl_trait.stderr
@@ -34,7 +34,7 @@ LL |     fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
    |                                  |         nested `impl Trait` here
    |                                  outer `impl Trait`
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types
   --> $DIR/nested_impl_trait.rs:10:32
    |
 LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
diff --git a/tests/ui/impl-trait/normalize-tait-in-const.rs b/tests/ui/impl-trait/normalize-tait-in-const.rs
index 020bcbb8396..d2e34c00b64 100644
--- a/tests/ui/impl-trait/normalize-tait-in-const.rs
+++ b/tests/ui/impl-trait/normalize-tait-in-const.rs
@@ -2,6 +2,7 @@
 // failure-status: 101
 // normalize-stderr-test "note: .*\n\n" -> ""
 // normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
+// normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
 // rustc-env:RUST_BACKTRACE=0
 
 #![feature(type_alias_impl_trait)]
diff --git a/tests/ui/impl-trait/normalize-tait-in-const.stderr b/tests/ui/impl-trait/normalize-tait-in-const.stderr
index 99eed29207b..84b00918724 100644
--- a/tests/ui/impl-trait/normalize-tait-in-const.stderr
+++ b/tests/ui/impl-trait/normalize-tait-in-const.stderr
@@ -1,4 +1,4 @@
-error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:201:90: Failed to normalize <for<'a, 'b> fn(&'a Alias<'b>) {foo} as std::ops::FnOnce<(&&S,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead
+error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:LL:CC: Failed to normalize <for<'a, 'b> fn(&'a Alias<'b>) {foo} as std::ops::FnOnce<(&&S,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead
 
 query stack during panic:
 #0 [eval_to_allocation_raw] const-evaluating + checking `BAR`
diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr
index 201aba3adff..1cae3f77cc5 100644
--- a/tests/ui/impl-trait/where-allowed.stderr
+++ b/tests/ui/impl-trait/where-allowed.stderr
@@ -43,109 +43,109 @@ LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
    = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer param
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer params
   --> $DIR/where-allowed.rs:16:40
    |
 LL | fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() }
    |                                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types
   --> $DIR/where-allowed.rs:20:42
    |
 LL | fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() }
    |                                          ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer param
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer params
   --> $DIR/where-allowed.rs:24:38
    |
 LL | fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() }
    |                                      ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types
   --> $DIR/where-allowed.rs:28:40
    |
 LL | fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() }
    |                                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params
   --> $DIR/where-allowed.rs:32:49
    |
 LL | fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() }
    |                                                 ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types
   --> $DIR/where-allowed.rs:36:51
    |
 LL | fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() }
    |                                                   ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params
   --> $DIR/where-allowed.rs:40:55
    |
 LL | fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
    |                                                       ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params
   --> $DIR/where-allowed.rs:47:51
    |
 LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
    |                                                   ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types
   --> $DIR/where-allowed.rs:52:53
    |
 LL | fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
    |                                                     ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params
   --> $DIR/where-allowed.rs:56:57
    |
 LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
    |                                                         ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params
   --> $DIR/where-allowed.rs:64:38
    |
 LL | fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
    |                                      ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types
   --> $DIR/where-allowed.rs:68:40
    |
 LL | fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() }
    |                                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types
   --> $DIR/where-allowed.rs:81:32
    |
 LL | struct InBraceStructField { x: impl Debug }
    |                                ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types
   --> $DIR/where-allowed.rs:85:41
    |
 LL | struct InAdtInBraceStructField { x: Vec<impl Debug> }
    |                                         ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types
   --> $DIR/where-allowed.rs:89:27
    |
 LL | struct InTupleStructField(impl Debug);
    |                           ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types
   --> $DIR/where-allowed.rs:94:25
    |
 LL |     InBraceVariant { x: impl Debug },
    |                         ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types
   --> $DIR/where-allowed.rs:96:20
    |
 LL |     InTupleVariant(impl Debug),
    |                    ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return types
   --> $DIR/where-allowed.rs:107:23
    |
 LL |     fn in_return() -> impl Debug;
@@ -154,7 +154,7 @@ LL |     fn in_return() -> impl Debug;
    = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
    = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types
   --> $DIR/where-allowed.rs:124:34
    |
 LL |     fn in_trait_impl_return() -> impl Debug { () }
@@ -163,121 +163,121 @@ LL |     fn in_trait_impl_return() -> impl Debug { () }
    = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
    = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` param
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` params
   --> $DIR/where-allowed.rs:137:33
    |
 LL |     fn in_foreign_parameters(_: impl Debug);
    |                                 ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` return
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` return types
   --> $DIR/where-allowed.rs:140:31
    |
 LL |     fn in_foreign_return() -> impl Debug;
    |                               ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types
   --> $DIR/where-allowed.rs:156:39
    |
 LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    |                                       ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in traits
   --> $DIR/where-allowed.rs:161:16
    |
 LL | impl PartialEq<impl Debug> for () {
    |                ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl headers
   --> $DIR/where-allowed.rs:166:24
    |
 LL | impl PartialEq<()> for impl Debug {
    |                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl headers
   --> $DIR/where-allowed.rs:171:6
    |
 LL | impl impl Debug {
    |      ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl headers
   --> $DIR/where-allowed.rs:177:24
    |
 LL | impl InInherentImplAdt<impl Debug> {
    |                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bound
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bounds
   --> $DIR/where-allowed.rs:183:11
    |
 LL |     where impl Debug: Debug
    |           ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bound
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bounds
   --> $DIR/where-allowed.rs:190:15
    |
 LL |     where Vec<impl Debug>: Debug
    |               ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bound
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bounds
   --> $DIR/where-allowed.rs:197:24
    |
 LL |     where T: PartialEq<impl Debug>
    |                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params
   --> $DIR/where-allowed.rs:204:17
    |
 LL |     where T: Fn(impl Debug)
    |                 ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types
   --> $DIR/where-allowed.rs:211:22
    |
 LL |     where T: Fn() -> impl Debug
    |                      ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults
   --> $DIR/where-allowed.rs:217:40
    |
 LL | struct InStructGenericParamDefault<T = impl Debug>(T);
    |                                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults
   --> $DIR/where-allowed.rs:221:36
    |
 LL | enum InEnumGenericParamDefault<T = impl Debug> { Variant(T) }
    |                                    ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults
   --> $DIR/where-allowed.rs:225:38
    |
 LL | trait InTraitGenericParamDefault<T = impl Debug> {}
    |                                      ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults
   --> $DIR/where-allowed.rs:229:41
    |
 LL | type InTypeAliasGenericParamDefault<T = impl Debug> = T;
    |                                         ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults
   --> $DIR/where-allowed.rs:233:11
    |
 LL | impl <T = impl Debug> T {}
    |           ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults
   --> $DIR/where-allowed.rs:240:40
    |
 LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    |                                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings
   --> $DIR/where-allowed.rs:246:29
    |
 LL |     let _in_local_variable: impl Fn() = || {};
    |                             ^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in closure return
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in closure return types
   --> $DIR/where-allowed.rs:248:46
    |
 LL |     let _in_return_in_local_variable = || -> impl Fn() { || {} };
diff --git a/tests/ui/implied-bounds/issue-100690.stderr b/tests/ui/implied-bounds/issue-100690.stderr
index 3f6af70d8ed..dba0353377f 100644
--- a/tests/ui/implied-bounds/issue-100690.stderr
+++ b/tests/ui/implied-bounds/issue-100690.stderr
@@ -12,7 +12,7 @@ note: required by a bound in `real_dispatch`
   --> $DIR/issue-100690.rs:9:8
    |
 LL | fn real_dispatch<T, F>(f: F) -> Result<(), io::Error>
-   |    ------------- required by a bound in this
+   |    ------------- required by a bound in this function
 ...
 LL |     F: FnOnce(&mut UIView<T>) -> Result<(), io::Error> + Send + 'static,
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `real_dispatch`
diff --git a/tests/ui/inference/inference_unstable.rs b/tests/ui/inference/inference_unstable.rs
index daf0cf042c4..ad76499591c 100644
--- a/tests/ui/inference/inference_unstable.rs
+++ b/tests/ui/inference/inference_unstable.rs
@@ -14,16 +14,16 @@ use inference_unstable_itertools::IpuItertools;
 
 fn main() {
     assert_eq!('x'.ipu_flatten(), 1);
-//~^ WARN an associated function with this name may be added to the standard library in the future
+//~^ WARN a method with this name may be added to the standard library in the future
 //~| WARN once this associated item is added to the standard library, the ambiguity may cause an
     assert_eq!('x'.ipu_by_value_vs_by_ref(), 1);
-//~^ WARN an associated function with this name may be added to the standard library in the future
+//~^ WARN a method with this name may be added to the standard library in the future
 //~| WARN once this associated item is added to the standard library, the ambiguity may cause an
     assert_eq!('x'.ipu_by_ref_vs_by_ref_mut(), 1);
-//~^ WARN an associated function with this name may be added to the standard library in the future
+//~^ WARN a method with this name may be added to the standard library in the future
 //~| WARN once this associated item is added to the standard library, the ambiguity may cause an
     assert_eq!((&mut 'x' as *mut char).ipu_by_mut_ptr_vs_by_const_ptr(), 1);
-//~^ WARN an associated function with this name may be added to the standard library in the future
+//~^ WARN a method with this name may be added to the standard library in the future
 //~| WARN once this associated item is added to the standard library, the ambiguity may cause an
     assert_eq!(char::C, 1);
 //~^ WARN an associated constant with this name may be added to the standard library in the future
diff --git a/tests/ui/inference/inference_unstable.stderr b/tests/ui/inference/inference_unstable.stderr
index ecbf2641bec..c48aaf9f495 100644
--- a/tests/ui/inference/inference_unstable.stderr
+++ b/tests/ui/inference/inference_unstable.stderr
@@ -1,4 +1,4 @@
-warning: an associated function with this name may be added to the standard library in the future
+warning: a method with this name may be added to the standard library in the future
   --> $DIR/inference_unstable.rs:16:20
    |
 LL |     assert_eq!('x'.ipu_flatten(), 1);
@@ -10,7 +10,7 @@ LL |     assert_eq!('x'.ipu_flatten(), 1);
    = help: add `#![feature(ipu_flatten)]` to the crate attributes to enable `inference_unstable_iterator::IpuIterator::ipu_flatten`
    = note: `#[warn(unstable_name_collisions)]` on by default
 
-warning: an associated function with this name may be added to the standard library in the future
+warning: a method with this name may be added to the standard library in the future
   --> $DIR/inference_unstable.rs:19:20
    |
 LL |     assert_eq!('x'.ipu_by_value_vs_by_ref(), 1);
@@ -21,7 +21,7 @@ LL |     assert_eq!('x'.ipu_by_value_vs_by_ref(), 1);
    = help: call with fully qualified syntax `inference_unstable_itertools::IpuItertools::ipu_by_value_vs_by_ref(...)` to keep using the current method
    = help: add `#![feature(ipu_flatten)]` to the crate attributes to enable `inference_unstable_iterator::IpuIterator::ipu_by_value_vs_by_ref`
 
-warning: an associated function with this name may be added to the standard library in the future
+warning: a method with this name may be added to the standard library in the future
   --> $DIR/inference_unstable.rs:22:20
    |
 LL |     assert_eq!('x'.ipu_by_ref_vs_by_ref_mut(), 1);
@@ -32,7 +32,7 @@ LL |     assert_eq!('x'.ipu_by_ref_vs_by_ref_mut(), 1);
    = help: call with fully qualified syntax `inference_unstable_itertools::IpuItertools::ipu_by_ref_vs_by_ref_mut(...)` to keep using the current method
    = help: add `#![feature(ipu_flatten)]` to the crate attributes to enable `inference_unstable_iterator::IpuIterator::ipu_by_ref_vs_by_ref_mut`
 
-warning: an associated function with this name may be added to the standard library in the future
+warning: a method with this name may be added to the standard library in the future
   --> $DIR/inference_unstable.rs:25:40
    |
 LL |     assert_eq!((&mut 'x' as *mut char).ipu_by_mut_ptr_vs_by_const_ptr(), 1);
diff --git a/tests/ui/inference/inference_unstable_featured.stderr b/tests/ui/inference/inference_unstable_featured.stderr
index 4ddede29c85..dc43abf52c6 100644
--- a/tests/ui/inference/inference_unstable_featured.stderr
+++ b/tests/ui/inference/inference_unstable_featured.stderr
@@ -6,11 +6,11 @@ LL |     assert_eq!('x'.ipu_flatten(), 0);
    |
    = note: candidate #1 is defined in an impl of the trait `IpuIterator` for the type `char`
    = note: candidate #2 is defined in an impl of the trait `IpuItertools` for the type `char`
-help: disambiguate the associated function for candidate #1
+help: disambiguate the method for candidate #1
    |
 LL |     assert_eq!(IpuIterator::ipu_flatten(&'x'), 0);
    |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: disambiguate the associated function for candidate #2
+help: disambiguate the method for candidate #2
    |
 LL |     assert_eq!(IpuItertools::ipu_flatten(&'x'), 0);
    |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/tests/ui/inference/issue-71732.stderr b/tests/ui/inference/issue-71732.stderr
index 01b37f2acaa..e89e4dca619 100644
--- a/tests/ui/inference/issue-71732.stderr
+++ b/tests/ui/inference/issue-71732.stderr
@@ -4,7 +4,7 @@ error[E0283]: type annotations needed
 LL |         .get(&"key".into())
    |          ^^^ ------------- type must be known at this point
    |          |
-   |          cannot infer type of the type parameter `Q` declared on the associated function `get`
+   |          cannot infer type of the type parameter `Q` declared on the method `get`
    |
    = note: multiple `impl`s satisfying `String: Borrow<_>` found in the following crates: `alloc`, `core`:
            - impl Borrow<str> for String;
diff --git a/tests/ui/inference/question-mark-type-infer.stderr b/tests/ui/inference/question-mark-type-infer.stderr
index a9cb7e5257c..7a1e850d157 100644
--- a/tests/ui/inference/question-mark-type-infer.stderr
+++ b/tests/ui/inference/question-mark-type-infer.stderr
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/question-mark-type-infer.rs:10:21
    |
 LL |     l.iter().map(f).collect()?
-   |                     ^^^^^^^ cannot infer type of the type parameter `B` declared on the associated function `collect`
+   |                     ^^^^^^^ cannot infer type of the type parameter `B` declared on the method `collect`
    |
 help: consider specifying the generic argument
    |
diff --git a/tests/ui/infinite/auxiliary/alias.rs b/tests/ui/infinite/auxiliary/alias.rs
new file mode 100644
index 00000000000..59add7eb18b
--- /dev/null
+++ b/tests/ui/infinite/auxiliary/alias.rs
@@ -0,0 +1,2 @@
+pub struct W<T>(T);
+pub type Wrapper<T> = W<T>;
diff --git a/tests/ui/infinite/infinite-alias.rs b/tests/ui/infinite/infinite-alias.rs
new file mode 100644
index 00000000000..45356f359ce
--- /dev/null
+++ b/tests/ui/infinite/infinite-alias.rs
@@ -0,0 +1,9 @@
+// aux-build: alias.rs
+// regression test for 108160
+
+extern crate alias;
+
+use alias::Wrapper;
+struct Rec(Wrapper<Rec>); //~ ERROR recursive type `Rec` has infinite
+
+fn main() {}
diff --git a/tests/ui/infinite/infinite-alias.stderr b/tests/ui/infinite/infinite-alias.stderr
new file mode 100644
index 00000000000..9d9265f8c36
--- /dev/null
+++ b/tests/ui/infinite/infinite-alias.stderr
@@ -0,0 +1,14 @@
+error[E0072]: recursive type `Rec` has infinite size
+  --> $DIR/infinite-alias.rs:7:1
+   |
+LL | struct Rec(Wrapper<Rec>);
+   | ^^^^^^^^^^ ------------ recursive without indirection
+   |
+help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
+   |
+LL | struct Rec(Box<Wrapper<Rec>>);
+   |            ++++            +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0072`.
diff --git a/tests/ui/issues/issue-106755.rs b/tests/ui/issues/issue-106755.rs
new file mode 100644
index 00000000000..46ece725fb7
--- /dev/null
+++ b/tests/ui/issues/issue-106755.rs
@@ -0,0 +1,19 @@
+// compile-flags:-Ztranslate-lang=en_US
+
+#![feature(negative_impls)]
+#![feature(marker_trait_attr)]
+
+#[marker]
+trait MyTrait {}
+
+struct TestType<T>(::std::marker::PhantomData<T>);
+
+unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
+
+impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR found both positive and negative implementation
+
+unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations
+
+impl !Send for TestType<i32> {}
+
+fn main() {}
diff --git a/tests/ui/issues/issue-106755.stderr b/tests/ui/issues/issue-106755.stderr
new file mode 100644
index 00000000000..54397034062
--- /dev/null
+++ b/tests/ui/issues/issue-106755.stderr
@@ -0,0 +1,22 @@
+error[E0751]: found both positive and negative implementation of trait `Send` for type `TestType<_>`:
+  --> $DIR/issue-106755.rs:13:1
+   |
+LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
+   | ------------------------------------------------------ positive implementation here
+LL |
+LL | impl<T: MyTrait> !Send for TestType<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
+
+error[E0119]: conflicting implementations of trait `Send` for type `TestType<_>`
+  --> $DIR/issue-106755.rs:15:1
+   |
+LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
+   | ------------------------------------------------------ first implementation here
+...
+LL | unsafe impl<T: 'static> Send for TestType<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0119, E0751.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/issues/issue-11374.stderr b/tests/ui/issues/issue-11374.stderr
index ef28c81d857..6e1fb1540bb 100644
--- a/tests/ui/issues/issue-11374.stderr
+++ b/tests/ui/issues/issue-11374.stderr
@@ -10,7 +10,7 @@ LL |     c.read_to(v);
    |
    = note: expected mutable reference `&mut [u8]`
                          found struct `Vec<_>`
-note: associated function defined here
+note: method defined here
   --> $DIR/issue-11374.rs:13:12
    |
 LL |     pub fn read_to(&mut self, vec: &mut [u8]) {
diff --git a/tests/ui/issues/issue-17337.stderr b/tests/ui/issues/issue-17337.stderr
index 34c2eb05fff..55e51e566d9 100644
--- a/tests/ui/issues/issue-17337.stderr
+++ b/tests/ui/issues/issue-17337.stderr
@@ -1,4 +1,4 @@
-error: use of deprecated associated function `Foo::foo`: text
+error: use of deprecated method `Foo::foo`: text
   --> $DIR/issue-17337.rs:16:6
    |
 LL |     .foo();
diff --git a/tests/ui/issues/issue-18423.rs b/tests/ui/issues/issue-18423.rs
index a81b32f050c..675fd041154 100644
--- a/tests/ui/issues/issue-18423.rs
+++ b/tests/ui/issues/issue-18423.rs
@@ -2,7 +2,7 @@
 
 struct Foo<'a> {
     x: Box<'a, isize>
-    //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+    //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument was supplied
 }
 
 fn main() { }
diff --git a/tests/ui/issues/issue-18423.stderr b/tests/ui/issues/issue-18423.stderr
index bbf79366244..5d154dbbbdd 100644
--- a/tests/ui/issues/issue-18423.stderr
+++ b/tests/ui/issues/issue-18423.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/issue-18423.rs:4:8
    |
 LL |     x: Box<'a, isize>
diff --git a/tests/ui/issues/issue-18446.stderr b/tests/ui/issues/issue-18446.stderr
index 939cf029253..602b80c6824 100644
--- a/tests/ui/issues/issue-18446.stderr
+++ b/tests/ui/issues/issue-18446.stderr
@@ -14,7 +14,7 @@ note: candidate #2 is defined in the trait `T`
    |
 LL |     fn foo(&self);
    |     ^^^^^^^^^^^^^^
-help: disambiguate the associated function for candidate #2
+help: disambiguate the method for candidate #2
    |
 LL |     T::foo(&x);
    |     ~~~~~~~~~~
diff --git a/tests/ui/issues/issue-21202.rs b/tests/ui/issues/issue-21202.rs
index f62de7ce7db..2c5f1394449 100644
--- a/tests/ui/issues/issue-21202.rs
+++ b/tests/ui/issues/issue-21202.rs
@@ -8,7 +8,7 @@ mod B {
     use crate1::A::Foo;
     fn bar(f: Foo) {
         Foo::foo(&f);
-        //~^ ERROR: associated function `foo` is private
+        //~^ ERROR: method `foo` is private
     }
 }
 
diff --git a/tests/ui/issues/issue-21202.stderr b/tests/ui/issues/issue-21202.stderr
index 1d2816feda9..e7c3f2f9a07 100644
--- a/tests/ui/issues/issue-21202.stderr
+++ b/tests/ui/issues/issue-21202.stderr
@@ -1,13 +1,13 @@
-error[E0624]: associated function `foo` is private
+error[E0624]: method `foo` is private
   --> $DIR/issue-21202.rs:10:14
    |
 LL |         Foo::foo(&f);
-   |              ^^^ private associated function
+   |              ^^^ private method
    |
   ::: $DIR/auxiliary/issue-21202.rs:4:9
    |
 LL |         fn foo(&self) { }
-   |         ------------- private associated function defined here
+   |         ------------- private method defined here
 
 error: aborting due to previous error
 
diff --git a/tests/ui/issues/issue-23041.stderr b/tests/ui/issues/issue-23041.stderr
index 6592b76a39f..4271c67c3bc 100644
--- a/tests/ui/issues/issue-23041.stderr
+++ b/tests/ui/issues/issue-23041.stderr
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/issue-23041.rs:6:7
    |
 LL |     b.downcast_ref::<fn(_)->_>();
-   |       ^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the associated function `downcast_ref`
+   |       ^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the method `downcast_ref`
    |
 help: consider specifying the generic argument
    |
diff --git a/tests/ui/issues/issue-26094.rs b/tests/ui/issues/issue-26094.rs
index abf3543ddb9..2742529edd3 100644
--- a/tests/ui/issues/issue-26094.rs
+++ b/tests/ui/issues/issue-26094.rs
@@ -1,7 +1,7 @@
 macro_rules! some_macro {
-    ($other: expr) => ({
+    ($other: expr) => {{
         $other(None) //~ NOTE unexpected argument of type `Option<_>`
-    })
+    }};
 }
 
 fn some_function() {} //~ NOTE defined here
@@ -9,5 +9,4 @@ fn some_function() {} //~ NOTE defined here
 fn main() {
     some_macro!(some_function);
     //~^ ERROR function takes 0 arguments but 1 argument was supplied
-    //~| NOTE in this expansion of some_macro!
 }
diff --git a/tests/ui/issues/issue-26094.stderr b/tests/ui/issues/issue-26094.stderr
index 608d2c7aff9..ecdf48470f7 100644
--- a/tests/ui/issues/issue-26094.stderr
+++ b/tests/ui/issues/issue-26094.stderr
@@ -2,10 +2,7 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/issue-26094.rs:10:17
    |
 LL |         $other(None)
-   |                ----
-   |                |
-   |                unexpected argument of type `Option<_>`
-   |                help: remove the extra argument
+   |                ---- unexpected argument of type `Option<_>`
 ...
 LL |     some_macro!(some_function);
    |                 ^^^^^^^^^^^^^
diff --git a/tests/ui/issues/issue-30438-c.rs b/tests/ui/issues/issue-30438-c.rs
index 4cf634245be..813c1d3e2cc 100644
--- a/tests/ui/issues/issue-30438-c.rs
+++ b/tests/ui/issues/issue-30438-c.rs
@@ -5,7 +5,6 @@ trait Trait { type Out; }
 struct Test<'a> { s: &'a str }
 
 fn silly<'y, 'z>(_s: &'y Test<'z>) -> &'y <Test<'z> as Trait>::Out where 'z: 'static {
-    //~^ WARN unnecessary lifetime parameter `'z`
     let x = Test { s: "this cannot last" };
     &x
     //~^ ERROR: cannot return reference to local variable `x`
diff --git a/tests/ui/issues/issue-30438-c.stderr b/tests/ui/issues/issue-30438-c.stderr
index a7a5c0500fd..7c001088097 100644
--- a/tests/ui/issues/issue-30438-c.stderr
+++ b/tests/ui/issues/issue-30438-c.stderr
@@ -1,17 +1,9 @@
-warning: unnecessary lifetime parameter `'z`
-  --> $DIR/issue-30438-c.rs:7:74
-   |
-LL | fn silly<'y, 'z>(_s: &'y Test<'z>) -> &'y <Test<'z> as Trait>::Out where 'z: 'static {
-   |                                                                          ^^
-   |
-   = help: you can use the `'static` lifetime directly, in place of `'z`
-
 error[E0515]: cannot return reference to local variable `x`
-  --> $DIR/issue-30438-c.rs:10:5
+  --> $DIR/issue-30438-c.rs:9:5
    |
 LL |     &x
    |     ^^ returns a reference to data owned by the current function
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0515`.
diff --git a/tests/ui/issues/issue-3214.rs b/tests/ui/issues/issue-3214.rs
index 928a65938b7..e3c07bb3f72 100644
--- a/tests/ui/issues/issue-3214.rs
+++ b/tests/ui/issues/issue-3214.rs
@@ -4,7 +4,7 @@ fn foo<T>() {
     }
 
     impl<T> Drop for Foo<T> {
-        //~^ ERROR this struct takes 0 generic arguments but 1 generic argument
+        //~^ ERROR struct takes 0 generic arguments but 1 generic argument
         fn drop(&mut self) {}
     }
 }
diff --git a/tests/ui/issues/issue-3214.stderr b/tests/ui/issues/issue-3214.stderr
index aa0b5ce64b4..7a2d772f0a1 100644
--- a/tests/ui/issues/issue-3214.stderr
+++ b/tests/ui/issues/issue-3214.stderr
@@ -8,7 +8,7 @@ LL |     struct Foo {
 LL |         x: T,
    |            ^ use of generic parameter from outer function
 
-error[E0107]: this struct takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-3214.rs:6:22
    |
 LL |     impl<T> Drop for Foo<T> {
diff --git a/tests/ui/issues/issue-3702-2.stderr b/tests/ui/issues/issue-3702-2.stderr
index 1fd64ca90aa..0b94c3135a1 100644
--- a/tests/ui/issues/issue-3702-2.stderr
+++ b/tests/ui/issues/issue-3702-2.stderr
@@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `Add` for the type `isize`
    |
 LL |     fn to_int(&self) -> isize { *self }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
-help: disambiguate the associated function for candidate #1
+help: disambiguate the method for candidate #1
    |
 LL |         ToPrimitive::to_int(&self) + other.to_int()
    |         ~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: disambiguate the associated function for candidate #2
+help: disambiguate the method for candidate #2
    |
 LL |         Add::to_int(&self) + other.to_int()
    |         ~~~~~~~~~~~~~~~~~~
diff --git a/tests/ui/issues/issue-3763.rs b/tests/ui/issues/issue-3763.rs
index 2e72d39cb32..893009a2cd9 100644
--- a/tests/ui/issues/issue-3763.rs
+++ b/tests/ui/issues/issue-3763.rs
@@ -20,9 +20,9 @@ fn main() {
     let _woohoo = (Box::new(my_struct)).priv_field;
     //~^ ERROR field `priv_field` of struct `MyStruct` is private
 
-    (&my_struct).happyfun();               //~ ERROR associated function `happyfun` is private
+    (&my_struct).happyfun();               //~ ERROR method `happyfun` is private
 
-    (Box::new(my_struct)).happyfun();          //~ ERROR associated function `happyfun` is private
+    (Box::new(my_struct)).happyfun();          //~ ERROR method `happyfun` is private
     let nope = my_struct.priv_field;
     //~^ ERROR field `priv_field` of struct `MyStruct` is private
 }
diff --git a/tests/ui/issues/issue-3763.stderr b/tests/ui/issues/issue-3763.stderr
index a09c8421bb7..d101e4c33ad 100644
--- a/tests/ui/issues/issue-3763.stderr
+++ b/tests/ui/issues/issue-3763.stderr
@@ -10,23 +10,23 @@ error[E0616]: field `priv_field` of struct `MyStruct` is private
 LL |     let _woohoo = (Box::new(my_struct)).priv_field;
    |                                         ^^^^^^^^^^ private field
 
-error[E0624]: associated function `happyfun` is private
+error[E0624]: method `happyfun` is private
   --> $DIR/issue-3763.rs:23:18
    |
 LL |         fn happyfun(&self) {}
-   |         ------------------ private associated function defined here
+   |         ------------------ private method defined here
 ...
 LL |     (&my_struct).happyfun();
-   |                  ^^^^^^^^ private associated function
+   |                  ^^^^^^^^ private method
 
-error[E0624]: associated function `happyfun` is private
+error[E0624]: method `happyfun` is private
   --> $DIR/issue-3763.rs:25:27
    |
 LL |         fn happyfun(&self) {}
-   |         ------------------ private associated function defined here
+   |         ------------------ private method defined here
 ...
 LL |     (Box::new(my_struct)).happyfun();
-   |                           ^^^^^^^^ private associated function
+   |                           ^^^^^^^^ private method
 
 error[E0616]: field `priv_field` of struct `MyStruct` is private
   --> $DIR/issue-3763.rs:26:26
diff --git a/tests/ui/issues/issue-47715.stderr b/tests/ui/issues/issue-47715.stderr
index 0ee9388bf2b..dadea34b688 100644
--- a/tests/ui/issues/issue-47715.stderr
+++ b/tests/ui/issues/issue-47715.stderr
@@ -1,22 +1,22 @@
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generics
   --> $DIR/issue-47715.rs:9:37
    |
 LL | struct Container<T: Iterable<Item = impl Foo>> {
    |                                     ^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generics
   --> $DIR/issue-47715.rs:14:30
    |
 LL | enum Enum<T: Iterable<Item = impl Foo>> {
    |                              ^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generics
   --> $DIR/issue-47715.rs:19:32
    |
 LL | union Union<T: Iterable<Item = impl Foo> + Copy> {
    |                                ^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generics
   --> $DIR/issue-47715.rs:24:30
    |
 LL | type Type<T: Iterable<Item = impl Foo>> = T;
diff --git a/tests/ui/issues/issue-48364.stderr b/tests/ui/issues/issue-48364.stderr
index a4c88fd880a..cac4af6a7f3 100644
--- a/tests/ui/issues/issue-48364.stderr
+++ b/tests/ui/issues/issue-48364.stderr
@@ -8,7 +8,7 @@ LL |     b"".starts_with(stringify!(foo))
    |
    = note: expected reference `&[u8]`
               found reference `&'static str`
-note: associated function defined here
+note: method defined here
   --> $SRC_DIR/core/src/slice/mod.rs:LL:COL
    = note: this error originates in the macro `stringify` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/tests/ui/issues/issue-53251.rs b/tests/ui/issues/issue-53251.rs
index 240826a161d..da3ba63ef67 100644
--- a/tests/ui/issues/issue-53251.rs
+++ b/tests/ui/issues/issue-53251.rs
@@ -9,8 +9,8 @@ macro_rules! impl_add {
         $(
             fn $n() {
                 S::f::<i64>();
-                //~^ ERROR this associated function takes 0 generic
-                //~| ERROR this associated function takes 0 generic
+                //~^ ERROR associated function takes 0 generic
+                //~| ERROR associated function takes 0 generic
             }
         )*
     }
diff --git a/tests/ui/issues/issue-53251.stderr b/tests/ui/issues/issue-53251.stderr
index cee9a5deb05..d5f14e8deb9 100644
--- a/tests/ui/issues/issue-53251.stderr
+++ b/tests/ui/issues/issue-53251.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: associated function takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-53251.rs:11:20
    |
 LL |                 S::f::<i64>();
@@ -16,7 +16,7 @@ LL |     fn f() {}
    |        ^
    = note: this error originates in the macro `impl_add` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: associated function takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-53251.rs:11:20
    |
 LL |                 S::f::<i64>();
diff --git a/tests/ui/issues/issue-60218.stderr b/tests/ui/issues/issue-60218.stderr
index dd72b6515dd..563690c9a5d 100644
--- a/tests/ui/issues/issue-60218.stderr
+++ b/tests/ui/issues/issue-60218.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `trigger_error`
   --> $DIR/issue-60218.rs:13:72
    |
 LL | pub fn trigger_error<I, F>(iterable: I, functor: F)
-   |        ------------- required by a bound in this
+   |        ------------- required by a bound in this function
 ...
 LL | for<'t> <Map<<&'t I as IntoIterator>::IntoIter, F> as Iterator>::Item: Foo,
    |                                                                        ^^^ required by this bound in `trigger_error`
diff --git a/tests/ui/issues/issue-60622.rs b/tests/ui/issues/issue-60622.rs
index 8e230c615bc..7b9443eee50 100644
--- a/tests/ui/issues/issue-60622.rs
+++ b/tests/ui/issues/issue-60622.rs
@@ -9,7 +9,7 @@ impl Borked {
 fn run_wild<T>(b: &Borked) {
     b.a::<'_, T>();
     //~^ ERROR cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
-    //~| ERROR this associated function takes 0 generic arguments but 1 generic argument
+    //~| ERROR method takes 0 generic arguments but 1 generic argument
     //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 }
 
diff --git a/tests/ui/issues/issue-60622.stderr b/tests/ui/issues/issue-60622.stderr
index ecf1ae758dd..43da2773940 100644
--- a/tests/ui/issues/issue-60622.stderr
+++ b/tests/ui/issues/issue-60622.stderr
@@ -16,7 +16,7 @@ LL | #![deny(warnings)]
    |         ^^^^^^^^
    = note: `#[deny(late_bound_lifetime_arguments)]` implied by `#[deny(warnings)]`
 
-error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-60622.rs:10:7
    |
 LL |     b.a::<'_, T>();
@@ -24,7 +24,7 @@ LL |     b.a::<'_, T>();
    |       |
    |       expected 0 generic arguments
    |
-note: associated function defined here, with 0 generic parameters
+note: method defined here, with 0 generic parameters
   --> $DIR/issue-60622.rs:6:8
    |
 LL |     fn a(&self) {}
diff --git a/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2015.stderr b/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2015.stderr
index d0cb16995af..4af3672ef72 100644
--- a/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2015.stderr
+++ b/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2015.stderr
@@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `await` for the type `r#fn
    |
 LL |     fn r#struct(&self) {
    |     ^^^^^^^^^^^^^^^^^^
-help: disambiguate the associated function for candidate #1
+help: disambiguate the method for candidate #1
    |
 LL |     async::r#struct(&r#fn {});
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~
-help: disambiguate the associated function for candidate #2
+help: disambiguate the method for candidate #2
    |
 LL |     await::r#struct(&r#fn {});
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2018.stderr b/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2018.stderr
index a75c1c41363..2b96a0fb5e5 100644
--- a/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2018.stderr
+++ b/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2018.stderr
@@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `r#await` for the type `r#
    |
 LL |     fn r#struct(&self) {
    |     ^^^^^^^^^^^^^^^^^^
-help: disambiguate the associated function for candidate #1
+help: disambiguate the method for candidate #1
    |
 LL |     r#async::r#struct(&r#fn {});
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: disambiguate the associated function for candidate #2
+help: disambiguate the method for candidate #2
    |
 LL |     r#await::r#struct(&r#fn {});
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/tests/ui/issues/issue-69455.stderr b/tests/ui/issues/issue-69455.stderr
index fc343bb54aa..d3e307fba2c 100644
--- a/tests/ui/issues/issue-69455.stderr
+++ b/tests/ui/issues/issue-69455.stderr
@@ -2,7 +2,7 @@ error[E0284]: type annotations needed
   --> $DIR/issue-69455.rs:29:41
    |
 LL |     println!("{}", 23u64.test(xs.iter().sum()));
-   |                          ----           ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum`
+   |                          ----           ^^^ cannot infer type of the type parameter `S` declared on the method `sum`
    |                          |
    |                          type must be known at this point
    |
@@ -16,7 +16,7 @@ error[E0283]: type annotations needed
   --> $DIR/issue-69455.rs:29:41
    |
 LL |     println!("{}", 23u64.test(xs.iter().sum()));
-   |                          ----           ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum`
+   |                          ----           ^^^ cannot infer type of the type parameter `S` declared on the method `sum`
    |                          |
    |                          required by a bound introduced by this call
    |
diff --git a/tests/ui/issues/issue-69683.stderr b/tests/ui/issues/issue-69683.stderr
index 193de1a35cf..c428ea9ea2c 100644
--- a/tests/ui/issues/issue-69683.stderr
+++ b/tests/ui/issues/issue-69683.stderr
@@ -31,7 +31,7 @@ LL |     u8: Element<I>,
    |         ^^^^^^^^^^ required by this bound in `Foo::foo`
 LL | {
 LL |     fn foo(self, x: <u8 as Element<I>>::Array);
-   |        --- required by a bound in this
+   |        --- required by a bound in this associated function
 help: try using a fully qualified path to specify the expected types
    |
 LL |     <u16 as Foo<I>>::foo(0u16, b);
diff --git a/tests/ui/issues/issue-70093/issue-70093-link-directives.rs b/tests/ui/issues/issue-70093/issue-70093-link-directives.rs
new file mode 100644
index 00000000000..83f9b16c408
--- /dev/null
+++ b/tests/ui/issues/issue-70093/issue-70093-link-directives.rs
@@ -0,0 +1,10 @@
+// run-pass
+// compile-flags: -Zlink-directives=no
+// ignore-windows - this will probably only work on unixish systems
+// ignore-fuchsia - missing __libc_start_main for some reason (#84733)
+// ignore-cross-compile - default-linker-libraries=yes doesn't play well with cross compiling
+
+#[link(name = "some-random-non-existent-library", kind = "static")]
+extern "C" {}
+
+fn main() {}
diff --git a/tests/ui/issues/issue-70093.rs b/tests/ui/issues/issue-70093/issue-70093.rs
index 86459dc904a..86459dc904a 100644
--- a/tests/ui/issues/issue-70093.rs
+++ b/tests/ui/issues/issue-70093/issue-70093.rs
diff --git a/tests/ui/lang-items/bad-add-impl.rs b/tests/ui/lang-items/bad-add-impl.rs
new file mode 100644
index 00000000000..0c44edbe51a
--- /dev/null
+++ b/tests/ui/lang-items/bad-add-impl.rs
@@ -0,0 +1,18 @@
+#![feature(no_core)]
+#![feature(lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "add"]
+trait Add<T> {
+    const add: u32 = 1u32;
+}
+
+impl Add<u32> for u32 {}
+
+fn main() {
+    1u32 + 1u32;
+    //~^ ERROR cannot add `u32` to `u32`
+}
diff --git a/tests/ui/lang-items/bad-add-impl.stderr b/tests/ui/lang-items/bad-add-impl.stderr
new file mode 100644
index 00000000000..3143729f99b
--- /dev/null
+++ b/tests/ui/lang-items/bad-add-impl.stderr
@@ -0,0 +1,11 @@
+error[E0369]: cannot add `u32` to `u32`
+  --> $DIR/bad-add-impl.rs:16:10
+   |
+LL |     1u32 + 1u32;
+   |     ---- ^ ---- u32
+   |     |
+   |     u32
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_item.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_item.stderr
new file mode 100644
index 00000000000..ff603111e94
--- /dev/null
+++ b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_item.stderr
@@ -0,0 +1,18 @@
+error: failed to find an overloaded call trait for closure call
+  --> $DIR/fn-fn_mut-call-ill-formed.rs:39:5
+   |
+LL |     a();
+   |     ^^^
+   |
+   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
+
+error: failed to find an overloaded call trait for closure call
+  --> $DIR/fn-fn_mut-call-ill-formed.rs:43:5
+   |
+LL |     b();
+   |     ^^^
+   |
+   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_sig.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_sig.stderr
new file mode 100644
index 00000000000..ff603111e94
--- /dev/null
+++ b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_sig.stderr
@@ -0,0 +1,18 @@
+error: failed to find an overloaded call trait for closure call
+  --> $DIR/fn-fn_mut-call-ill-formed.rs:39:5
+   |
+LL |     a();
+   |     ^^^
+   |
+   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
+
+error: failed to find an overloaded call trait for closure call
+  --> $DIR/fn-fn_mut-call-ill-formed.rs:43:5
+   |
+LL |     b();
+   |     ^^^
+   |
+   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_item.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_item.stderr
new file mode 100644
index 00000000000..02e33c597fe
--- /dev/null
+++ b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_item.stderr
@@ -0,0 +1,18 @@
+error: failed to find an overloaded call trait for closure call
+  --> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
+   |
+LL |     a();
+   |     ^^^
+   |
+   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
+
+error: failed to find an overloaded call trait for closure call
+  --> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
+   |
+LL |     b();
+   |     ^^^
+   |
+   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_sig.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_sig.stderr
new file mode 100644
index 00000000000..02e33c597fe
--- /dev/null
+++ b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_sig.stderr
@@ -0,0 +1,18 @@
+error: failed to find an overloaded call trait for closure call
+  --> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
+   |
+LL |     a();
+   |     ^^^
+   |
+   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
+
+error: failed to find an overloaded call trait for closure call
+  --> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
+   |
+LL |     b();
+   |     ^^^
+   |
+   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_item.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_item.stderr
new file mode 100644
index 00000000000..02e33c597fe
--- /dev/null
+++ b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_item.stderr
@@ -0,0 +1,18 @@
+error: failed to find an overloaded call trait for closure call
+  --> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
+   |
+LL |     a();
+   |     ^^^
+   |
+   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
+
+error: failed to find an overloaded call trait for closure call
+  --> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
+   |
+LL |     b();
+   |     ^^^
+   |
+   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_sig.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_sig.stderr
new file mode 100644
index 00000000000..02e33c597fe
--- /dev/null
+++ b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_sig.stderr
@@ -0,0 +1,18 @@
+error: failed to find an overloaded call trait for closure call
+  --> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
+   |
+LL |     a();
+   |     ^^^
+   |
+   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
+
+error: failed to find an overloaded call trait for closure call
+  --> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
+   |
+LL |     b();
+   |     ^^^
+   |
+   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_item.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_item.stderr
new file mode 100644
index 00000000000..02e33c597fe
--- /dev/null
+++ b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_item.stderr
@@ -0,0 +1,18 @@
+error: failed to find an overloaded call trait for closure call
+  --> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
+   |
+LL |     a();
+   |     ^^^
+   |
+   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
+
+error: failed to find an overloaded call trait for closure call
+  --> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
+   |
+LL |     b();
+   |     ^^^
+   |
+   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_sig.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_sig.stderr
new file mode 100644
index 00000000000..02e33c597fe
--- /dev/null
+++ b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_sig.stderr
@@ -0,0 +1,18 @@
+error: failed to find an overloaded call trait for closure call
+  --> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
+   |
+LL |     a();
+   |     ^^^
+   |
+   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
+
+error: failed to find an overloaded call trait for closure call
+  --> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
+   |
+LL |     b();
+   |     ^^^
+   |
+   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.rs b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.rs
index 52bd8136d9c..757c6538d05 100644
--- a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.rs
+++ b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.rs
@@ -1,27 +1,49 @@
-// Make sure that an error is reported if the `call` function of the
-// `fn`/`fn_mut` lang item is grossly ill-formed.
+// revisions: fn_once_bad_item fn_once_bad_sig fn_mut_bad_item fn_mut_bad_sig fn_bad_item fn_bad_sig
 
 #![feature(lang_items)]
 #![feature(no_core)]
 #![no_core]
 
+#[lang = "sized"]
+trait Sized {}
+
+#[cfg(any(fn_bad_item, fn_bad_sig))]
 #[lang = "fn"]
 trait MyFn<T> {
+    #[cfg(fn_bad_sig)]
+    fn call(i: i32) -> i32 { 0 }
+
+    #[cfg(fn_bad_item)]
     const call: i32 = 42;
-    //~^ ERROR: `call` trait item in `fn` lang item must be a function
 }
 
+#[cfg(any(fn_mut_bad_item, fn_mut_bad_sig))]
 #[lang = "fn_mut"]
 trait MyFnMut<T> {
-    fn call(i: i32, j: i32) -> i32 { i + j }
-    //~^ ERROR: first argument of `call` in `fn_mut` lang item must be a reference
+    #[cfg(fn_mut_bad_sig)]
+    fn call_mut(i: i32) -> i32 { 0 }
+
+    #[cfg(fn_mut_bad_item)]
+    const call_mut: i32 = 42;
+}
+
+#[cfg(any(fn_once_bad_item, fn_once_bad_sig))]
+#[lang = "fn_once"]
+trait MyFnOnce<T> {
+    #[cfg(fn_once_bad_sig)]
+    fn call_once(i: i32) -> i32 { 0 }
+
+    #[cfg(fn_once_bad_item)]
+    const call_once: i32 = 42;
 }
 
 fn main() {
     let a = || 42;
     a();
+    //~^ ERROR failed to find an overloaded call trait for closure call
 
     let mut i = 0;
-    let mut b = || { i += 1; };
+    let mut b = || { };
     b();
+    //~^ ERROR failed to find an overloaded call trait for closure call
 }
diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.stderr
deleted file mode 100644
index 82bdae270c8..00000000000
--- a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error: `call` trait item in `fn` lang item must be a function
-  --> $DIR/fn-fn_mut-call-ill-formed.rs:10:5
-   |
-LL |     const call: i32 = 42;
-   |     ^^^^^^^^^^^^^^^^^^^^^
-
-error: first argument of `call` in `fn_mut` lang item must be a reference
-  --> $DIR/fn-fn_mut-call-ill-formed.rs:16:16
-   |
-LL |     fn call(i: i32, j: i32) -> i32 { i + j }
-   |                ^^^
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/lang-items/issue-86238.stderr b/tests/ui/lang-items/issue-86238.stderr
index 767e6de2263..c6e811a94fe 100644
--- a/tests/ui/lang-items/issue-86238.stderr
+++ b/tests/ui/lang-items/issue-86238.stderr
@@ -4,7 +4,7 @@ error: failed to find an overloaded call trait for closure call
 LL |     one()
    |     ^^^^^
    |
-   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have associated `call`/`call_mut`/`call_once` functions
+   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
 
 error: aborting due to previous error
 
diff --git a/tests/ui/late-bound-lifetimes/mismatched_arg_count.rs b/tests/ui/late-bound-lifetimes/mismatched_arg_count.rs
index 0b331e2039f..792563fd82b 100644
--- a/tests/ui/late-bound-lifetimes/mismatched_arg_count.rs
+++ b/tests/ui/late-bound-lifetimes/mismatched_arg_count.rs
@@ -7,6 +7,6 @@ trait Trait<'a> {
 type Alias<'a, T> = <T as Trait<'a>>::Assoc;
 
 fn bar<'a, T: Trait<'a>>(_: Alias<'a, 'a, T>) {}
-//~^ error: this type alias takes 1 lifetime argument but 2 lifetime arguments were supplied
+//~^ error: type alias takes 1 lifetime argument but 2 lifetime arguments were supplied
 
 fn main() {}
diff --git a/tests/ui/late-bound-lifetimes/mismatched_arg_count.stderr b/tests/ui/late-bound-lifetimes/mismatched_arg_count.stderr
index 3704d9bb957..de58a014ee8 100644
--- a/tests/ui/late-bound-lifetimes/mismatched_arg_count.stderr
+++ b/tests/ui/late-bound-lifetimes/mismatched_arg_count.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this type alias takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: type alias takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/mismatched_arg_count.rs:9:29
    |
 LL | fn bar<'a, T: Trait<'a>>(_: Alias<'a, 'a, T>) {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr
index 4bcd7cf9578..6fd7f67d15e 100644
--- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr
@@ -7,7 +7,7 @@ LL |   fn foo<'a>(&self, x: &'a i32) -> &i32 {
    |          lifetime `'a` defined here
 LL |
 LL |     x
-   |     ^ associated function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a`
+   |     ^ method was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr
index 34a64f8a63e..2687266e098 100644
--- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr
@@ -7,7 +7,7 @@ LL |     fn foo<'a>(&self, x: &'a Foo) -> &'a Foo {
    |            lifetime `'a` defined here
 LL |
 LL |         if true { x } else { self }
-   |                              ^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
+   |                              ^^^^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr
index 5601335d275..9ff5e42d732 100644
--- a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr
@@ -6,7 +6,7 @@ LL |   fn foo<'a>(&self, x: &i32) -> &i32 {
    |              |
    |              let's call the lifetime of this reference `'2`
 LL |     x
-   |     ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |     ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr
index e221902c4a9..e4c855e11fe 100644
--- a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr
@@ -6,7 +6,7 @@ LL |     fn foo<'a>(&self, x: &Foo) -> &Foo {
    |                |
    |                let's call the lifetime of this reference `'2`
 LL |         if true { x } else { self }
-   |                   ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |                   ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
diff --git a/tests/ui/lint/dead-code/in-closure.rs b/tests/ui/lint/dead-code/in-closure.rs
new file mode 100644
index 00000000000..c55634405ed
--- /dev/null
+++ b/tests/ui/lint/dead-code/in-closure.rs
@@ -0,0 +1,16 @@
+// edition: 2021
+
+#![deny(dead_code)]
+
+pub fn foo() {
+    let closure = || {
+        fn a() {}   //~ ERROR function `a` is never used
+    };
+    closure()
+}
+
+pub async fn async_foo() {
+    const A: usize = 1; //~ ERROR constant `A` is never used
+}
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/in-closure.stderr b/tests/ui/lint/dead-code/in-closure.stderr
new file mode 100644
index 00000000000..deb276be702
--- /dev/null
+++ b/tests/ui/lint/dead-code/in-closure.stderr
@@ -0,0 +1,20 @@
+error: function `a` is never used
+  --> $DIR/in-closure.rs:7:12
+   |
+LL |         fn a() {}
+   |            ^
+   |
+note: the lint level is defined here
+  --> $DIR/in-closure.rs:3:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: constant `A` is never used
+  --> $DIR/in-closure.rs:13:11
+   |
+LL |     const A: usize = 1;
+   |           ^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/dead-code/issue-85255.rs b/tests/ui/lint/dead-code/issue-85255.rs
index 043f68137b8..1978bd4e824 100644
--- a/tests/ui/lint/dead-code/issue-85255.rs
+++ b/tests/ui/lint/dead-code/issue-85255.rs
@@ -11,8 +11,8 @@ struct Foo {
 struct Bar;
 
 impl Bar {
-    fn a(&self) -> i32 { 5 } //~ WARNING: associated function `a` is never used
-    pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function `b` is never used
+    fn a(&self) -> i32 { 5 } //~ WARNING: method `a` is never used
+    pub fn b(&self) -> i32 { 6 } //~ WARNING: method `b` is never used
 }
 
 pub(crate) struct Foo1 {
@@ -23,8 +23,8 @@ pub(crate) struct Foo1 {
 pub(crate) struct Bar1;
 
 impl Bar1 {
-    fn a(&self) -> i32 { 5 } //~ WARNING: associated function `a` is never used
-    pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function `b` is never used
+    fn a(&self) -> i32 { 5 } //~ WARNING: method `a` is never used
+    pub fn b(&self) -> i32 { 6 } //~ WARNING: method `b` is never used
 }
 
 pub(crate) struct Foo2 {
@@ -35,8 +35,8 @@ pub(crate) struct Foo2 {
 pub(crate) struct Bar2;
 
 impl Bar2 {
-    fn a(&self) -> i32 { 5 } //~ WARNING: associated function `a` is never used
-    pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function `b` is never used
+    fn a(&self) -> i32 { 5 } //~ WARNING: method `a` is never used
+    pub fn b(&self) -> i32 { 6 } //~ WARNING: method `b` is never used
 }
 
 
diff --git a/tests/ui/lint/dead-code/issue-85255.stderr b/tests/ui/lint/dead-code/issue-85255.stderr
index 3497b952fdd..58a19cf3c99 100644
--- a/tests/ui/lint/dead-code/issue-85255.stderr
+++ b/tests/ui/lint/dead-code/issue-85255.stderr
@@ -34,37 +34,37 @@ LL |     a: i32,
 LL |     pub b: i32,
    |         ^
 
-warning: associated function `a` is never used
+warning: method `a` is never used
   --> $DIR/issue-85255.rs:14:8
    |
 LL |     fn a(&self) -> i32 { 5 }
    |        ^
 
-warning: associated function `b` is never used
+warning: method `b` is never used
   --> $DIR/issue-85255.rs:15:12
    |
 LL |     pub fn b(&self) -> i32 { 6 }
    |            ^
 
-warning: associated function `a` is never used
+warning: method `a` is never used
   --> $DIR/issue-85255.rs:26:8
    |
 LL |     fn a(&self) -> i32 { 5 }
    |        ^
 
-warning: associated function `b` is never used
+warning: method `b` is never used
   --> $DIR/issue-85255.rs:27:12
    |
 LL |     pub fn b(&self) -> i32 { 6 }
    |            ^
 
-warning: associated function `a` is never used
+warning: method `a` is never used
   --> $DIR/issue-85255.rs:38:8
    |
 LL |     fn a(&self) -> i32 { 5 }
    |        ^
 
-warning: associated function `b` is never used
+warning: method `b` is never used
   --> $DIR/issue-85255.rs:39:12
    |
 LL |     pub fn b(&self) -> i32 { 6 }
diff --git a/tests/ui/lint/dead-code/lint-dead-code-3.rs b/tests/ui/lint/dead-code/lint-dead-code-3.rs
index 293fcdbc5ee..20b568054df 100644
--- a/tests/ui/lint/dead-code/lint-dead-code-3.rs
+++ b/tests/ui/lint/dead-code/lint-dead-code-3.rs
@@ -13,7 +13,7 @@ extern "C" {
 
 struct Foo; //~ ERROR: struct `Foo` is never constructed
 impl Foo {
-    fn foo(&self) { //~ ERROR: associated function `foo` is never used
+    fn foo(&self) { //~ ERROR: method `foo` is never used
         bar()
     }
 }
diff --git a/tests/ui/lint/dead-code/lint-dead-code-3.stderr b/tests/ui/lint/dead-code/lint-dead-code-3.stderr
index 26fc13bae08..797b7559c01 100644
--- a/tests/ui/lint/dead-code/lint-dead-code-3.stderr
+++ b/tests/ui/lint/dead-code/lint-dead-code-3.stderr
@@ -34,7 +34,7 @@ error: function `blah` is never used
 LL |         fn blah() {}
    |            ^^^^
 
-error: associated function `foo` is never used
+error: method `foo` is never used
   --> $DIR/lint-dead-code-3.rs:16:8
    |
 LL |     fn foo(&self) {
diff --git a/tests/ui/lint/invalid_value.stderr b/tests/ui/lint/invalid_value.stderr
index 48fd4169da7..57531b0968f 100644
--- a/tests/ui/lint/invalid_value.stderr
+++ b/tests/ui/lint/invalid_value.stderr
@@ -61,10 +61,7 @@ error: the type `!` does not permit zero-initialization
   --> $DIR/invalid_value.rs:65:23
    |
 LL |         let _val: ! = mem::zeroed();
-   |                       ^^^^^^^^^^^^^
-   |                       |
-   |                       this code causes undefined behavior when executed
-   |                       help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |                       ^^^^^^^^^^^^^ this code causes undefined behavior when executed
    |
    = note: the `!` type has no valid value
 
@@ -72,10 +69,7 @@ error: the type `!` does not permit being left uninitialized
   --> $DIR/invalid_value.rs:66:23
    |
 LL |         let _val: ! = mem::uninitialized();
-   |                       ^^^^^^^^^^^^^^^^^^^^
-   |                       |
-   |                       this code causes undefined behavior when executed
-   |                       help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |                       ^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
    |
    = note: the `!` type has no valid value
 
@@ -83,10 +77,7 @@ error: the type `(i32, !)` does not permit zero-initialization
   --> $DIR/invalid_value.rs:68:30
    |
 LL |         let _val: (i32, !) = mem::zeroed();
-   |                              ^^^^^^^^^^^^^
-   |                              |
-   |                              this code causes undefined behavior when executed
-   |                              help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |                              ^^^^^^^^^^^^^ this code causes undefined behavior when executed
    |
    = note: the `!` type has no valid value
 
@@ -94,10 +85,7 @@ error: the type `(i32, !)` does not permit being left uninitialized
   --> $DIR/invalid_value.rs:69:30
    |
 LL |         let _val: (i32, !) = mem::uninitialized();
-   |                              ^^^^^^^^^^^^^^^^^^^^
-   |                              |
-   |                              this code causes undefined behavior when executed
-   |                              help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |                              ^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
    |
    = note: integers must be initialized
 
@@ -105,10 +93,7 @@ error: the type `Void` does not permit zero-initialization
   --> $DIR/invalid_value.rs:71:26
    |
 LL |         let _val: Void = mem::zeroed();
-   |                          ^^^^^^^^^^^^^
-   |                          |
-   |                          this code causes undefined behavior when executed
-   |                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |                          ^^^^^^^^^^^^^ this code causes undefined behavior when executed
    |
 note: enums with no inhabited variants have no valid value
   --> $DIR/invalid_value.rs:12:1
@@ -120,10 +105,7 @@ error: the type `Void` does not permit being left uninitialized
   --> $DIR/invalid_value.rs:72:26
    |
 LL |         let _val: Void = mem::uninitialized();
-   |                          ^^^^^^^^^^^^^^^^^^^^
-   |                          |
-   |                          this code causes undefined behavior when executed
-   |                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |                          ^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
    |
 note: enums with no inhabited variants have no valid value
   --> $DIR/invalid_value.rs:12:1
@@ -405,10 +387,7 @@ error: the type `TwoUninhabited` does not permit zero-initialization
   --> $DIR/invalid_value.rs:104:36
    |
 LL |         let _val: TwoUninhabited = mem::zeroed();
-   |                                    ^^^^^^^^^^^^^
-   |                                    |
-   |                                    this code causes undefined behavior when executed
-   |                                    help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |                                    ^^^^^^^^^^^^^ this code causes undefined behavior when executed
    |
 note: enums with no inhabited variants have no valid value
   --> $DIR/invalid_value.rs:42:1
@@ -420,10 +399,7 @@ error: the type `TwoUninhabited` does not permit being left uninitialized
   --> $DIR/invalid_value.rs:105:36
    |
 LL |         let _val: TwoUninhabited = mem::uninitialized();
-   |                                    ^^^^^^^^^^^^^^^^^^^^
-   |                                    |
-   |                                    this code causes undefined behavior when executed
-   |                                    help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |                                    ^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
    |
 note: enums with no inhabited variants have no valid value
   --> $DIR/invalid_value.rs:42:1
diff --git a/tests/ui/lint/issue-106991.rs b/tests/ui/lint/issue-106991.rs
new file mode 100644
index 00000000000..e4d7f765b4a
--- /dev/null
+++ b/tests/ui/lint/issue-106991.rs
@@ -0,0 +1,13 @@
+fn foo(items: &mut Vec<u8>) {
+    items.sort();
+}
+
+fn bar() -> impl Iterator<Item = i32> {
+    //~^ ERROR expected `foo` to be a fn item that returns `i32`, but it returns `()` [E0271]
+    let mut x: Vec<Vec<u8>> = vec![vec![0, 2, 1], vec![5, 4, 3]];
+    x.iter_mut().map(foo)
+}
+
+fn main() {
+    bar();
+}
diff --git a/tests/ui/lint/issue-106991.stderr b/tests/ui/lint/issue-106991.stderr
new file mode 100644
index 00000000000..7b43f0b2ca8
--- /dev/null
+++ b/tests/ui/lint/issue-106991.stderr
@@ -0,0 +1,11 @@
+error[E0271]: expected `foo` to be a fn item that returns `i32`, but it returns `()`
+  --> $DIR/issue-106991.rs:5:13
+   |
+LL | fn bar() -> impl Iterator<Item = i32> {
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `i32`
+   |
+   = note: required for `Map<std::slice::IterMut<'_, Vec<u8>>, for<'a> fn(&'a mut Vec<u8>) {foo}>` to implement `Iterator`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/lint/lint-missing-doc.rs b/tests/ui/lint/lint-missing-doc.rs
index 2297257919e..4a234d2651a 100644
--- a/tests/ui/lint/lint-missing-doc.rs
+++ b/tests/ui/lint/lint-missing-doc.rs
@@ -50,8 +50,10 @@ trait B {
 }
 
 pub trait C { //~ ERROR: missing documentation for a trait
-    fn foo(&self); //~ ERROR: missing documentation for an associated function
-    fn foo_with_impl(&self) {} //~ ERROR: missing documentation for an associated function
+    fn foo(&self); //~ ERROR: missing documentation for a method
+    fn foo_with_impl(&self) {} //~ ERROR: missing documentation for a method
+    fn foo_no_self(); //~ ERROR: missing documentation for an associated function
+    fn foo_no_self_with_impl() {} //~ ERROR: missing documentation for an associated function
 }
 
 #[allow(missing_docs)]
diff --git a/tests/ui/lint/lint-missing-doc.stderr b/tests/ui/lint/lint-missing-doc.stderr
index d68472d4b66..733d062a08b 100644
--- a/tests/ui/lint/lint-missing-doc.stderr
+++ b/tests/ui/lint/lint-missing-doc.stderr
@@ -40,101 +40,113 @@ error: missing documentation for a trait
 LL | pub trait C {
    | ^^^^^^^^^^^
 
-error: missing documentation for an associated function
+error: missing documentation for a method
   --> $DIR/lint-missing-doc.rs:53:5
    |
 LL |     fn foo(&self);
    |     ^^^^^^^^^^^^^^
 
-error: missing documentation for an associated function
+error: missing documentation for a method
   --> $DIR/lint-missing-doc.rs:54:5
    |
 LL |     fn foo_with_impl(&self) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
+error: missing documentation for an associated function
+  --> $DIR/lint-missing-doc.rs:55:5
+   |
+LL |     fn foo_no_self();
+   |     ^^^^^^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+  --> $DIR/lint-missing-doc.rs:56:5
+   |
+LL |     fn foo_no_self_with_impl() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error: missing documentation for an associated type
-  --> $DIR/lint-missing-doc.rs:64:5
+  --> $DIR/lint-missing-doc.rs:66:5
    |
 LL |     type AssociatedType;
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for an associated type
-  --> $DIR/lint-missing-doc.rs:65:5
+  --> $DIR/lint-missing-doc.rs:67:5
    |
 LL |     type AssociatedTypeDef = Self;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for an associated function
-  --> $DIR/lint-missing-doc.rs:81:5
+  --> $DIR/lint-missing-doc.rs:83:5
    |
 LL |     pub fn foo() {}
    |     ^^^^^^^^^^^^
 
 error: missing documentation for an enum
-  --> $DIR/lint-missing-doc.rs:118:1
+  --> $DIR/lint-missing-doc.rs:120:1
    |
 LL | pub enum PubBaz {
    | ^^^^^^^^^^^^^^^
 
 error: missing documentation for a variant
-  --> $DIR/lint-missing-doc.rs:119:5
+  --> $DIR/lint-missing-doc.rs:121:5
    |
 LL |     PubBazA {
    |     ^^^^^^^
 
 error: missing documentation for a struct field
-  --> $DIR/lint-missing-doc.rs:120:9
+  --> $DIR/lint-missing-doc.rs:122:9
    |
 LL |         a: isize,
    |         ^^^^^^^^
 
 error: missing documentation for a constant
-  --> $DIR/lint-missing-doc.rs:151:1
+  --> $DIR/lint-missing-doc.rs:153:1
    |
 LL | pub const FOO4: u32 = 0;
    | ^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a static
-  --> $DIR/lint-missing-doc.rs:161:1
+  --> $DIR/lint-missing-doc.rs:163:1
    |
 LL | pub static BAR4: u32 = 0;
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a function
-  --> $DIR/lint-missing-doc.rs:167:5
+  --> $DIR/lint-missing-doc.rs:169:5
    |
 LL |     pub fn undocumented1() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a function
-  --> $DIR/lint-missing-doc.rs:168:5
+  --> $DIR/lint-missing-doc.rs:170:5
    |
 LL |     pub fn undocumented2() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a function
-  --> $DIR/lint-missing-doc.rs:174:9
+  --> $DIR/lint-missing-doc.rs:176:9
    |
 LL |         pub fn also_undocumented1() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a function
-  --> $DIR/lint-missing-doc.rs:189:5
+  --> $DIR/lint-missing-doc.rs:191:5
    |
 LL |     pub fn extern_fn_undocumented(f: f32) -> f32;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a static
-  --> $DIR/lint-missing-doc.rs:194:5
+  --> $DIR/lint-missing-doc.rs:196:5
    |
 LL |     pub static EXTERN_STATIC_UNDOCUMENTED: u8;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for a foreign type
-  --> $DIR/lint-missing-doc.rs:199:5
+  --> $DIR/lint-missing-doc.rs:201:5
    |
 LL |     pub type ExternTyUndocumented;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 22 previous errors
+error: aborting due to 24 previous errors
 
diff --git a/tests/ui/lint/lint-stability-deprecated.rs b/tests/ui/lint/lint-stability-deprecated.rs
index 74c35083e60..a56a37228e5 100644
--- a/tests/ui/lint/lint-stability-deprecated.rs
+++ b/tests/ui/lint/lint-stability-deprecated.rs
@@ -22,40 +22,40 @@ mod cross_crate {
         let foo = MethodTester;
 
         deprecated(); //~ WARN use of deprecated function `lint_stability::deprecated`
-        foo.method_deprecated(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated`
-        Foo::method_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated`
-        <Foo>::method_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated`
-        foo.trait_deprecated(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
-        Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
-        <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
-        <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
+        foo.method_deprecated(); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated`
+        Foo::method_deprecated(&foo); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated`
+        <Foo>::method_deprecated(&foo); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated`
+        foo.trait_deprecated(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated`
+        Trait::trait_deprecated(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated`
+        <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated`
+        <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated`
 
         deprecated_text(); //~ WARN use of deprecated function `lint_stability::deprecated_text`: text
-        foo.method_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
-        Foo::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
-        <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
-        foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
-        Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
-        <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
-        <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+        foo.method_deprecated_text(); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated_text`: text
+        Foo::method_deprecated_text(&foo); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated_text`: text
+        <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated_text`: text
+        foo.trait_deprecated_text(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
+        Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
+        <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
 
         deprecated_unstable(); //~ WARN use of deprecated function `lint_stability::deprecated_unstable`
-        foo.method_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`
-        Foo::method_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`
-        <Foo>::method_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`
-        foo.trait_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
-        Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
-        <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
-        <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
+        foo.method_deprecated_unstable(); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable`
+        Foo::method_deprecated_unstable(&foo); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable`
+        <Foo>::method_deprecated_unstable(&foo); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable`
+        foo.trait_deprecated_unstable(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`
+        Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`
+        <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`
+        <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`
 
         deprecated_unstable_text(); //~ WARN use of deprecated function `lint_stability::deprecated_unstable_text`: text
-        foo.method_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
-        Foo::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
-        <Foo>::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
-        foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
-        Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
-        <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
-        <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+        foo.method_deprecated_unstable_text(); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable_text`: text
+        Foo::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable_text`: text
+        <Foo>::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable_text`: text
+        foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
+        Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
+        <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
+        <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
 
         unstable();
         foo.method_unstable();
@@ -141,22 +141,22 @@ mod cross_crate {
     }
 
     fn test_method_param<Foo: Trait>(foo: Foo) {
-        foo.trait_deprecated(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
-        Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
-        <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
-        <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
-        foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
-        Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
-        <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
-        <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
-        foo.trait_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
-        Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
-        <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
-        <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
-        foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
-        Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
-        <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
-        <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+        foo.trait_deprecated(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated`
+        Trait::trait_deprecated(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated`
+        <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated`
+        <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated`
+        foo.trait_deprecated_text(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
+        Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
+        <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
+        foo.trait_deprecated_unstable(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`
+        Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`
+        <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`
+        <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`
+        foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
+        Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
+        <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
+        <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
         foo.trait_unstable();
         Trait::trait_unstable(&foo);
         <Foo>::trait_unstable(&foo);
@@ -172,10 +172,10 @@ mod cross_crate {
     }
 
     fn test_method_object(foo: &dyn Trait) {
-        foo.trait_deprecated(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
-        foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
-        foo.trait_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
-        foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+        foo.trait_deprecated(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated`
+        foo.trait_deprecated_text(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
+        foo.trait_deprecated_unstable(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`
+        foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
         foo.trait_unstable();
         foo.trait_unstable_text();
         foo.trait_stable();
@@ -328,22 +328,22 @@ mod this_crate {
         let foo = MethodTester;
 
         deprecated(); //~ WARN use of deprecated function `this_crate::deprecated`
-        foo.method_deprecated(); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated`
-        Foo::method_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated`
-        <Foo>::method_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated`
-        foo.trait_deprecated(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
-        Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
-        <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
-        <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
+        foo.method_deprecated(); //~ WARN use of deprecated method `this_crate::MethodTester::method_deprecated`
+        Foo::method_deprecated(&foo); //~ WARN use of deprecated method `this_crate::MethodTester::method_deprecated`
+        <Foo>::method_deprecated(&foo); //~ WARN use of deprecated method `this_crate::MethodTester::method_deprecated`
+        foo.trait_deprecated(); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated`
+        Trait::trait_deprecated(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated`
+        <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated`
+        <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated`
 
         deprecated_text(); //~ WARN use of deprecated function `this_crate::deprecated_text`: text
-        foo.method_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
-        Foo::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
-        <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
-        foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-        Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-        <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-        <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+        foo.method_deprecated_text(); //~ WARN use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text
+        Foo::method_deprecated_text(&foo); //~ WARN use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text
+        <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text
+        foo.trait_deprecated_text(); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
+        Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
+        <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
 
         unstable();
         foo.method_unstable();
@@ -402,14 +402,14 @@ mod this_crate {
     }
 
     fn test_method_param<Foo: Trait>(foo: Foo) {
-        foo.trait_deprecated(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
-        Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
-        <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
-        <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
-        foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-        Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-        <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-        <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+        foo.trait_deprecated(); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated`
+        Trait::trait_deprecated(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated`
+        <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated`
+        <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated`
+        foo.trait_deprecated_text(); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
+        Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
+        <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
         foo.trait_unstable();
         Trait::trait_unstable(&foo);
         <Foo>::trait_unstable(&foo);
@@ -425,8 +425,8 @@ mod this_crate {
     }
 
     fn test_method_object(foo: &dyn Trait) {
-        foo.trait_deprecated(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
-        foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+        foo.trait_deprecated(); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated`
+        foo.trait_deprecated_text(); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
         foo.trait_unstable();
         foo.trait_unstable_text();
         foo.trait_stable();
diff --git a/tests/ui/lint/lint-stability-deprecated.stderr b/tests/ui/lint/lint-stability-deprecated.stderr
index 9f1e7b281e9..19a4649e168 100644
--- a/tests/ui/lint/lint-stability-deprecated.stderr
+++ b/tests/ui/lint/lint-stability-deprecated.stderr
@@ -10,13 +10,13 @@ note: the lint level is defined here
 LL | #![warn(deprecated)]
    |         ^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:29:16
    |
 LL |         Trait::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:31:25
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
@@ -28,17 +28,17 @@ warning: use of deprecated function `lint_stability::deprecated_text`: text
 LL |         deprecated_text();
    |         ^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:38:16
    |
-LL | ...   Trait::trait_deprecated_text(&foo);
-   |              ^^^^^^^^^^^^^^^^^^^^^
+LL |         Trait::trait_deprecated_text(&foo);
+   |                ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:40:25
    |
-LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
-   |                       ^^^^^^^^^^^^^^^^^^^^^
+LL |         <Foo as Trait>::trait_deprecated_text(&foo);
+   |                         ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated function `lint_stability::deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:42:9
@@ -46,13 +46,13 @@ warning: use of deprecated function `lint_stability::deprecated_unstable`: text
 LL |         deprecated_unstable();
    |         ^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:47:16
    |
-LL | ...   Trait::trait_deprecated_unstable(&foo);
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         Trait::trait_deprecated_unstable(&foo);
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:49:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_unstable(&foo);
@@ -64,13 +64,13 @@ warning: use of deprecated function `lint_stability::deprecated_unstable_text`:
 LL |         deprecated_unstable_text();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:56:16
    |
 LL | ...   Trait::trait_deprecated_unstable_text(&foo);
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:58:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_unstable_text(&foo);
@@ -142,49 +142,49 @@ warning: use of deprecated function `lint_stability::deprecated_text`: text
 LL |         macro_test_arg!(macro_test_arg!(deprecated_text()));
    |                                         ^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:145:16
    |
 LL |         Trait::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:147:25
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
    |                         ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:149:16
    |
-LL | ...   Trait::trait_deprecated_text(&foo);
-   |              ^^^^^^^^^^^^^^^^^^^^^
+LL |         Trait::trait_deprecated_text(&foo);
+   |                ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:151:25
    |
-LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
-   |                       ^^^^^^^^^^^^^^^^^^^^^
+LL |         <Foo as Trait>::trait_deprecated_text(&foo);
+   |                         ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:153:16
    |
-LL | ...   Trait::trait_deprecated_unstable(&foo);
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         Trait::trait_deprecated_unstable(&foo);
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:155:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_unstable(&foo);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:157:16
    |
 LL | ...   Trait::trait_deprecated_unstable_text(&foo);
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:159:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_unstable_text(&foo);
@@ -214,13 +214,13 @@ warning: use of deprecated function `this_crate::deprecated`: text
 LL |         deprecated();
    |         ^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:335:16
    |
 LL |         Trait::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:337:25
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
@@ -232,17 +232,17 @@ warning: use of deprecated function `this_crate::deprecated_text`: text
 LL |         deprecated_text();
    |         ^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:344:16
    |
 LL |         Trait::trait_deprecated_text(&foo);
    |                ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:346:25
    |
-LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
-   |                       ^^^^^^^^^^^^^^^^^^^^^
+LL |         <Foo as Trait>::trait_deprecated_text(&foo);
+   |                         ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated struct `this_crate::DeprecatedStruct`: text
   --> $DIR/lint-stability-deprecated.rs:384:17
@@ -268,29 +268,29 @@ warning: use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`: tex
 LL |         let _ = DeprecatedTupleStruct (1);
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:406:16
    |
 LL |         Trait::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:408:25
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
    |                         ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:410:16
    |
 LL |         Trait::trait_deprecated_text(&foo);
    |                ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:412:25
    |
-LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
-   |                       ^^^^^^^^^^^^^^^^^^^^^
+LL |         <Foo as Trait>::trait_deprecated_text(&foo);
+   |                         ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated function `this_crate::test_fn_body::fn_in_body`: text
   --> $DIR/lint-stability-deprecated.rs:439:9
@@ -328,121 +328,121 @@ warning: use of deprecated associated type `lint_stability::TraitWithAssociatedT
 LL |             TypeDeprecated = u16,
    |             ^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text
+warning: use of deprecated method `lint_stability::MethodTester::method_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:25:13
    |
 LL |         foo.method_deprecated();
    |             ^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text
+warning: use of deprecated method `lint_stability::MethodTester::method_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:26:14
    |
 LL |         Foo::method_deprecated(&foo);
    |              ^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text
+warning: use of deprecated method `lint_stability::MethodTester::method_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:27:16
    |
 LL |         <Foo>::method_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:28:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:30:16
    |
 LL |         <Foo>::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
+warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:34:13
    |
-LL | ...   foo.method_deprecated_text();
-   |           ^^^^^^^^^^^^^^^^^^^^^^
+LL |         foo.method_deprecated_text();
+   |             ^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
+warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:35:14
    |
-LL | ...   Foo::method_deprecated_text(&foo);
-   |            ^^^^^^^^^^^^^^^^^^^^^^
+LL |         Foo::method_deprecated_text(&foo);
+   |              ^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
+warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:36:16
    |
-LL | ...   <Foo>::method_deprecated_text(&foo);
-   |              ^^^^^^^^^^^^^^^^^^^^^^
+LL |         <Foo>::method_deprecated_text(&foo);
+   |                ^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:37:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:39:16
    |
-LL | ...   <Foo>::trait_deprecated_text(&foo);
-   |              ^^^^^^^^^^^^^^^^^^^^^
+LL |         <Foo>::trait_deprecated_text(&foo);
+   |                ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text
+warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:43:13
    |
-LL | ...   foo.method_deprecated_unstable();
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         foo.method_deprecated_unstable();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text
+warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:44:14
    |
-LL | ...   Foo::method_deprecated_unstable(&foo);
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         Foo::method_deprecated_unstable(&foo);
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text
+warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:45:16
    |
 LL | ...   <Foo>::method_deprecated_unstable(&foo);
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:46:13
    |
 LL |         foo.trait_deprecated_unstable();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:48:16
    |
-LL | ...   <Foo>::trait_deprecated_unstable(&foo);
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         <Foo>::trait_deprecated_unstable(&foo);
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
+warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:52:13
    |
 LL | ...   foo.method_deprecated_unstable_text();
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
+warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:53:14
    |
 LL | ...   Foo::method_deprecated_unstable_text(&foo);
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
+warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:54:16
    |
 LL | ...   <Foo>::method_deprecated_unstable_text(&foo);
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:55:13
    |
 LL | ...   foo.trait_deprecated_unstable_text();
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:57:16
    |
 LL | ...   <Foo>::trait_deprecated_unstable_text(&foo);
@@ -460,133 +460,133 @@ warning: use of deprecated field `lint_stability::DeprecatedUnstableStruct::i`:
 LL |             i: 0
    |             ^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:144:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:146:16
    |
 LL |         <Foo>::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:148:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:150:16
    |
-LL | ...   <Foo>::trait_deprecated_text(&foo);
-   |              ^^^^^^^^^^^^^^^^^^^^^
+LL |         <Foo>::trait_deprecated_text(&foo);
+   |                ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:152:13
    |
 LL |         foo.trait_deprecated_unstable();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:154:16
    |
-LL | ...   <Foo>::trait_deprecated_unstable(&foo);
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         <Foo>::trait_deprecated_unstable(&foo);
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:156:13
    |
 LL | ...   foo.trait_deprecated_unstable_text();
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:158:16
    |
 LL | ...   <Foo>::trait_deprecated_unstable_text(&foo);
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:175:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:176:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:177:13
    |
 LL |         foo.trait_deprecated_unstable();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:178:13
    |
 LL | ...   foo.trait_deprecated_unstable_text();
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text
+warning: use of deprecated method `this_crate::MethodTester::method_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:331:13
    |
 LL |         foo.method_deprecated();
    |             ^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text
+warning: use of deprecated method `this_crate::MethodTester::method_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:332:14
    |
 LL |         Foo::method_deprecated(&foo);
    |              ^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text
+warning: use of deprecated method `this_crate::MethodTester::method_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:333:16
    |
 LL |         <Foo>::method_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:334:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:336:16
    |
 LL |         <Foo>::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
+warning: use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:340:13
    |
-LL | ...   foo.method_deprecated_text();
-   |           ^^^^^^^^^^^^^^^^^^^^^^
+LL |         foo.method_deprecated_text();
+   |             ^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
+warning: use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:341:14
    |
-LL | ...   Foo::method_deprecated_text(&foo);
-   |            ^^^^^^^^^^^^^^^^^^^^^^
+LL |         Foo::method_deprecated_text(&foo);
+   |              ^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
+warning: use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:342:16
    |
-LL | ...   <Foo>::method_deprecated_text(&foo);
-   |              ^^^^^^^^^^^^^^^^^^^^^^
+LL |         <Foo>::method_deprecated_text(&foo);
+   |                ^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:343:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:345:16
    |
 LL |         <Foo>::trait_deprecated_text(&foo);
@@ -598,37 +598,37 @@ warning: use of deprecated field `this_crate::DeprecatedStruct::i`: text
 LL |             i: 0
    |             ^^^^
 
-warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:405:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:407:16
    |
 LL |         <Foo>::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:409:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:411:16
    |
 LL |         <Foo>::trait_deprecated_text(&foo);
    |                ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:428:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:429:13
    |
 LL |         foo.trait_deprecated_text();
diff --git a/tests/ui/lint/lint_map_unit_fn.rs b/tests/ui/lint/lint_map_unit_fn.rs
new file mode 100644
index 00000000000..dc1ecbf8424
--- /dev/null
+++ b/tests/ui/lint/lint_map_unit_fn.rs
@@ -0,0 +1,20 @@
+#![deny(map_unit_fn)]
+
+fn foo(items: &mut Vec<u8>) {
+    items.sort();
+}
+
+fn main() {
+    let mut x: Vec<Vec<u8>> = vec![vec![0, 2, 1], vec![5, 4, 3]];
+    x.iter_mut().map(foo);
+    //~^ ERROR `Iterator::map` call that discard the iterator's values
+    x.iter_mut().map(|items| {
+    //~^ ERROR `Iterator::map` call that discard the iterator's values
+        items.sort();
+    });
+    let f = |items: &mut Vec<u8>| {
+        items.sort();
+    };
+    x.iter_mut().map(f);
+    //~^ ERROR `Iterator::map` call that discard the iterator's values
+}
diff --git a/tests/ui/lint/lint_map_unit_fn.stderr b/tests/ui/lint/lint_map_unit_fn.stderr
new file mode 100644
index 00000000000..fbf689c5421
--- /dev/null
+++ b/tests/ui/lint/lint_map_unit_fn.stderr
@@ -0,0 +1,66 @@
+error: `Iterator::map` call that discard the iterator's values
+  --> $DIR/lint_map_unit_fn.rs:9:18
+   |
+LL | fn foo(items: &mut Vec<u8>) {
+   | --------------------------- this function returns `()`, which is likely not what you wanted
+...
+LL |     x.iter_mut().map(foo);
+   |                  ^^^^---^
+   |                  |   |
+   |                  |   called `Iterator::map` with callable that returns `()`
+   |                  after this call to map, the resulting iterator is `impl Iterator<Item = ()>`, which means the only information carried by the iterator is the number of items
+   |
+   = note: `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated
+note: the lint level is defined here
+  --> $DIR/lint_map_unit_fn.rs:1:9
+   |
+LL | #![deny(map_unit_fn)]
+   |         ^^^^^^^^^^^
+help: you might have meant to use `Iterator::for_each`
+   |
+LL |     x.iter_mut().for_each(foo);
+   |                  ~~~~~~~~
+
+error: `Iterator::map` call that discard the iterator's values
+  --> $DIR/lint_map_unit_fn.rs:11:18
+   |
+LL |         x.iter_mut().map(|items| {
+   |                      ^   -------
+   |                      |   |
+   |  ____________________|___this function returns `()`, which is likely not what you wanted
+   | |  __________________|
+   | | |
+LL | | |
+LL | | |         items.sort();
+LL | | |     });
+   | | |     -^ after this call to map, the resulting iterator is `impl Iterator<Item = ()>`, which means the only information carried by the iterator is the number of items
+   | | |_____||
+   | |_______|
+   |         called `Iterator::map` with callable that returns `()`
+   |
+   = note: `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated
+help: you might have meant to use `Iterator::for_each`
+   |
+LL |     x.iter_mut().for_each(|items| {
+   |                  ~~~~~~~~
+
+error: `Iterator::map` call that discard the iterator's values
+  --> $DIR/lint_map_unit_fn.rs:18:18
+   |
+LL |     let f = |items: &mut Vec<u8>| {
+   |             --------------------- this function returns `()`, which is likely not what you wanted
+...
+LL |     x.iter_mut().map(f);
+   |                  ^^^^-^
+   |                  |   |
+   |                  |   called `Iterator::map` with callable that returns `()`
+   |                  after this call to map, the resulting iterator is `impl Iterator<Item = ()>`, which means the only information carried by the iterator is the number of items
+   |
+   = note: `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated
+help: you might have meant to use `Iterator::for_each`
+   |
+LL |     x.iter_mut().for_each(f);
+   |                  ~~~~~~~~
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/match/match-ref-mut-invariance.stderr b/tests/ui/match/match-ref-mut-invariance.stderr
index 3b7e53cd527..b353d3514fe 100644
--- a/tests/ui/match/match-ref-mut-invariance.stderr
+++ b/tests/ui/match/match-ref-mut-invariance.stderr
@@ -6,7 +6,7 @@ LL | impl<'b> S<'b> {
 LL |     fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
    |            -- lifetime `'a` defined here
 LL |         match self.0 { ref mut x => x }
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
    |
    = help: consider adding the following bound: `'a: 'b`
    = note: requirement occurs because of a mutable reference to `&i32`
diff --git a/tests/ui/match/match-ref-mut-let-invariance.stderr b/tests/ui/match/match-ref-mut-let-invariance.stderr
index f4d1cea670b..bb0fcdb9990 100644
--- a/tests/ui/match/match-ref-mut-let-invariance.stderr
+++ b/tests/ui/match/match-ref-mut-let-invariance.stderr
@@ -7,7 +7,7 @@ LL |     fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
    |            -- lifetime `'a` defined here
 LL |         let ref mut x = self.0;
 LL |         x
-   |         ^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+   |         ^ method was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
    |
    = help: consider adding the following bound: `'a: 'b`
    = note: requirement occurs because of a mutable reference to `&i32`
diff --git a/tests/ui/methods/issues/issue-105732.stderr b/tests/ui/methods/issues/issue-105732.stderr
index 7696642548d..19ccd2de685 100644
--- a/tests/ui/methods/issues/issue-105732.stderr
+++ b/tests/ui/methods/issues/issue-105732.stderr
@@ -2,7 +2,7 @@ error[E0380]: auto traits cannot have associated items
   --> $DIR/issue-105732.rs:4:8
    |
 LL | auto trait Foo {
-   |            --- auto trait cannot have associated items
+   |            --- auto traits cannot have associated items
 LL |     fn g(&self);
    |     ---^-------- help: remove these associated items
 
diff --git a/tests/ui/methods/issues/issue-61525.stderr b/tests/ui/methods/issues/issue-61525.stderr
index 32e269b7ad8..a8afdeb8401 100644
--- a/tests/ui/methods/issues/issue-61525.stderr
+++ b/tests/ui/methods/issues/issue-61525.stderr
@@ -27,7 +27,7 @@ LL |         1.query::<dyn ToString>("")
    |
    = note: expected trait object `dyn ToString`
                  found reference `&'static str`
-note: associated function defined here
+note: method defined here
   --> $DIR/issue-61525.rs:2:8
    |
 LL |     fn query<Q>(self, q: Q);
diff --git a/tests/ui/methods/method-ambig-two-traits-cross-crate.stderr b/tests/ui/methods/method-ambig-two-traits-cross-crate.stderr
index 4b2597eed3c..5132d92777b 100644
--- a/tests/ui/methods/method-ambig-two-traits-cross-crate.stderr
+++ b/tests/ui/methods/method-ambig-two-traits-cross-crate.stderr
@@ -10,11 +10,11 @@ note: candidate #2 is defined in an impl of the trait `Me2` for the type `usize`
    |
 LL | impl Me2 for usize { fn me(&self) -> usize { *self } }
    |                      ^^^^^^^^^^^^^^^^^^^^^
-help: disambiguate the associated function for candidate #1
+help: disambiguate the method for candidate #1
    |
 LL | fn main() { Me::me(&1_usize); }
    |             ~~~~~~~~~~~~~~~~
-help: disambiguate the associated function for candidate #2
+help: disambiguate the method for candidate #2
    |
 LL | fn main() { Me2::me(&1_usize); }
    |             ~~~~~~~~~~~~~~~~~
diff --git a/tests/ui/methods/method-ambig-two-traits-from-bounds.stderr b/tests/ui/methods/method-ambig-two-traits-from-bounds.stderr
index 1feaa2c73e0..601e6bbb006 100644
--- a/tests/ui/methods/method-ambig-two-traits-from-bounds.stderr
+++ b/tests/ui/methods/method-ambig-two-traits-from-bounds.stderr
@@ -14,11 +14,11 @@ note: candidate #2 is defined in the trait `B`
    |
 LL | trait B { fn foo(&self); }
    |           ^^^^^^^^^^^^^^
-help: disambiguate the associated function for candidate #1
+help: disambiguate the method for candidate #1
    |
 LL |     A::foo(t);
    |     ~~~~~~~~~
-help: disambiguate the associated function for candidate #2
+help: disambiguate the method for candidate #2
    |
 LL |     B::foo(t);
    |     ~~~~~~~~~
diff --git a/tests/ui/methods/method-ambig-two-traits-from-impls.stderr b/tests/ui/methods/method-ambig-two-traits-from-impls.stderr
index f69b5689239..31359143391 100644
--- a/tests/ui/methods/method-ambig-two-traits-from-impls.stderr
+++ b/tests/ui/methods/method-ambig-two-traits-from-impls.stderr
@@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `B` for the type `AB`
    |
 LL |     fn foo(self) {}
    |     ^^^^^^^^^^^^
-help: disambiguate the associated function for candidate #1
+help: disambiguate the method for candidate #1
    |
 LL |     A::foo(AB {});
    |     ~~~~~~~~~~~~~
-help: disambiguate the associated function for candidate #2
+help: disambiguate the method for candidate #2
    |
 LL |     B::foo(AB {});
    |     ~~~~~~~~~~~~~
diff --git a/tests/ui/methods/method-ambig-two-traits-with-default-method.stderr b/tests/ui/methods/method-ambig-two-traits-with-default-method.stderr
index e84dff8bab7..df01966b3a2 100644
--- a/tests/ui/methods/method-ambig-two-traits-with-default-method.stderr
+++ b/tests/ui/methods/method-ambig-two-traits-with-default-method.stderr
@@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `Bar` for the type `usize`
    |
 LL | trait Bar { fn method(&self) {} }
    |             ^^^^^^^^^^^^^^^^
-help: disambiguate the associated function for candidate #1
+help: disambiguate the method for candidate #1
    |
 LL |     Foo::method(&1_usize);
    |     ~~~~~~~~~~~~~~~~~~~~~
-help: disambiguate the associated function for candidate #2
+help: disambiguate the method for candidate #2
    |
 LL |     Bar::method(&1_usize);
    |     ~~~~~~~~~~~~~~~~~~~~~
diff --git a/tests/ui/methods/method-call-err-msg.stderr b/tests/ui/methods/method-call-err-msg.stderr
index 0f37e8f09a9..c340c2d32b3 100644
--- a/tests/ui/methods/method-call-err-msg.stderr
+++ b/tests/ui/methods/method-call-err-msg.stderr
@@ -7,7 +7,7 @@ LL |     x.zero(0)
    |            unexpected argument of type `{integer}`
    |            help: remove the extra argument
    |
-note: associated function defined here
+note: method defined here
   --> $DIR/method-call-err-msg.rs:5:8
    |
 LL |     fn zero(self) -> Foo { self }
@@ -19,7 +19,7 @@ error[E0061]: this method takes 1 argument but 0 arguments were supplied
 LL |      .one()
    |       ^^^-- an argument of type `isize` is missing
    |
-note: associated function defined here
+note: method defined here
   --> $DIR/method-call-err-msg.rs:6:8
    |
 LL |     fn one(self, _: isize) -> Foo { self }
@@ -35,7 +35,7 @@ error[E0061]: this method takes 2 arguments but 1 argument was supplied
 LL |      .two(0);
    |       ^^^--- an argument of type `isize` is missing
    |
-note: associated function defined here
+note: method defined here
   --> $DIR/method-call-err-msg.rs:7:8
    |
 LL |     fn two(self, _: isize, _: isize) -> Foo { self }
@@ -72,7 +72,7 @@ error[E0061]: this method takes 3 arguments but 0 arguments were supplied
 LL |     y.three::<usize>();
    |       ^^^^^^^^^^^^^^-- three arguments of type `usize`, `usize`, and `usize` are missing
    |
-note: associated function defined here
+note: method defined here
   --> $DIR/method-call-err-msg.rs:8:8
    |
 LL |     fn three<T>(self, _: T, _: T, _: T) -> Foo { self }
diff --git a/tests/ui/methods/method-call-lifetime-args-fail.rs b/tests/ui/methods/method-call-lifetime-args-fail.rs
index 6bf55844da8..1f13de094bb 100644
--- a/tests/ui/methods/method-call-lifetime-args-fail.rs
+++ b/tests/ui/methods/method-call-lifetime-args-fail.rs
@@ -14,9 +14,9 @@ impl S {
 fn method_call() {
     S.early(); // OK
     S.early::<'static>();
-    //~^ ERROR this associated function takes 2 lifetime arguments but 1 lifetime argument
+    //~^ ERROR method takes 2 lifetime arguments but 1 lifetime argument
     S.early::<'static, 'static, 'static>();
-    //~^ ERROR this associated function takes 2 lifetime arguments but 3 lifetime arguments were supplied
+    //~^ ERROR method takes 2 lifetime arguments but 3 lifetime arguments were supplied
     let _: &u8 = S.life_and_type::<'static>();
     S.life_and_type::<u8>();
     S.life_and_type::<'static, u8>();
@@ -61,9 +61,9 @@ fn ufcs() {
 
     S::early(S); // OK
     S::early::<'static>(S);
-    //~^ ERROR this associated function takes 2 lifetime arguments but 1 lifetime argument
+    //~^ ERROR method takes 2 lifetime arguments but 1 lifetime argument
     S::early::<'static, 'static, 'static>(S);
-    //~^ ERROR this associated function takes 2 lifetime arguments but 3 lifetime arguments were supplied
+    //~^ ERROR method takes 2 lifetime arguments but 3 lifetime arguments were supplied
     let _: &u8 = S::life_and_type::<'static>(S);
     S::life_and_type::<u8>(S);
     S::life_and_type::<'static, u8>(S);
diff --git a/tests/ui/methods/method-call-lifetime-args-fail.stderr b/tests/ui/methods/method-call-lifetime-args-fail.stderr
index 249b48ab194..34526256f99 100644
--- a/tests/ui/methods/method-call-lifetime-args-fail.stderr
+++ b/tests/ui/methods/method-call-lifetime-args-fail.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated function takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: method takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/method-call-lifetime-args-fail.rs:16:7
    |
 LL |     S.early::<'static>();
@@ -6,7 +6,7 @@ LL |     S.early::<'static>();
    |       |
    |       expected 2 lifetime arguments
    |
-note: associated function defined here, with 2 lifetime parameters: `'a`, `'b`
+note: method defined here, with 2 lifetime parameters: `'a`, `'b`
   --> $DIR/method-call-lifetime-args-fail.rs:6:8
    |
 LL |     fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} }
@@ -16,7 +16,7 @@ help: add missing lifetime argument
 LL |     S.early::<'static, 'static>();
    |                      +++++++++
 
-error[E0107]: this associated function takes 2 lifetime arguments but 3 lifetime arguments were supplied
+error[E0107]: method takes 2 lifetime arguments but 3 lifetime arguments were supplied
   --> $DIR/method-call-lifetime-args-fail.rs:18:7
    |
 LL |     S.early::<'static, 'static, 'static>();
@@ -24,7 +24,7 @@ LL |     S.early::<'static, 'static, 'static>();
    |       |
    |       expected 2 lifetime arguments
    |
-note: associated function defined here, with 2 lifetime parameters: `'a`, `'b`
+note: method defined here, with 2 lifetime parameters: `'a`, `'b`
   --> $DIR/method-call-lifetime-args-fail.rs:6:8
    |
 LL |     fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} }
@@ -198,7 +198,7 @@ note: the late bound lifetime parameter is introduced here
 LL |     fn late_unused_early<'a, 'b>(self) -> &'b u8 { loop {} }
    |                          ^^
 
-error[E0107]: this associated function takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: method takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/method-call-lifetime-args-fail.rs:63:8
    |
 LL |     S::early::<'static>(S);
@@ -206,7 +206,7 @@ LL |     S::early::<'static>(S);
    |        |
    |        expected 2 lifetime arguments
    |
-note: associated function defined here, with 2 lifetime parameters: `'a`, `'b`
+note: method defined here, with 2 lifetime parameters: `'a`, `'b`
   --> $DIR/method-call-lifetime-args-fail.rs:6:8
    |
 LL |     fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} }
@@ -216,7 +216,7 @@ help: add missing lifetime argument
 LL |     S::early::<'static, 'static>(S);
    |                       +++++++++
 
-error[E0107]: this associated function takes 2 lifetime arguments but 3 lifetime arguments were supplied
+error[E0107]: method takes 2 lifetime arguments but 3 lifetime arguments were supplied
   --> $DIR/method-call-lifetime-args-fail.rs:65:8
    |
 LL |     S::early::<'static, 'static, 'static>(S);
@@ -224,7 +224,7 @@ LL |     S::early::<'static, 'static, 'static>(S);
    |        |
    |        expected 2 lifetime arguments
    |
-note: associated function defined here, with 2 lifetime parameters: `'a`, `'b`
+note: method defined here, with 2 lifetime parameters: `'a`, `'b`
   --> $DIR/method-call-lifetime-args-fail.rs:6:8
    |
 LL |     fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} }
diff --git a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr
index 82addab9479..4e83e4b77f1 100644
--- a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr
+++ b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr
@@ -44,15 +44,15 @@ note: candidate #3 is defined in the trait `FinalFoo`
    |
 LL |     fn foo(&self) -> u8;
    |     ^^^^^^^^^^^^^^^^^^^^
-help: disambiguate the associated function for candidate #1
+help: disambiguate the method for candidate #1
    |
 LL |     let z = X::foo(x);
    |             ~~~~~~~~~
-help: disambiguate the associated function for candidate #2
+help: disambiguate the method for candidate #2
    |
 LL |     let z = NuisanceFoo::foo(x);
    |             ~~~~~~~~~~~~~~~~~~~
-help: disambiguate the associated function for candidate #3
+help: disambiguate the method for candidate #3
    |
 LL |     let z = FinalFoo::foo(x);
    |             ~~~~~~~~~~~~~~~~
diff --git a/tests/ui/methods/method-self-arg-1.stderr b/tests/ui/methods/method-self-arg-1.stderr
index 32ab8dced21..9241a8be58f 100644
--- a/tests/ui/methods/method-self-arg-1.stderr
+++ b/tests/ui/methods/method-self-arg-1.stderr
@@ -8,7 +8,7 @@ LL |     Foo::bar(x);
    |     |        help: consider borrowing here: `&x`
    |     arguments to this function are incorrect
    |
-note: associated function defined here
+note: method defined here
   --> $DIR/method-self-arg-1.rs:6:8
    |
 LL |     fn bar(&self) {}
@@ -24,7 +24,7 @@ LL |     Foo::bar(&42);
    |
    = note: expected reference `&Foo`
               found reference `&{integer}`
-note: associated function defined here
+note: method defined here
   --> $DIR/method-self-arg-1.rs:6:8
    |
 LL |     fn bar(&self) {}
diff --git a/tests/ui/mismatched_types/issue-47706.stderr b/tests/ui/mismatched_types/issue-47706.stderr
index d9d408844d0..69d6ee5cbd5 100644
--- a/tests/ui/mismatched_types/issue-47706.stderr
+++ b/tests/ui/mismatched_types/issue-47706.stderr
@@ -27,7 +27,7 @@ note: required by a bound in `foo`
   --> $DIR/issue-47706.rs:22:8
    |
 LL | fn foo<F>(f: F)
-   |    --- required by a bound in this
+   |    --- required by a bound in this function
 LL | where
 LL |     F: Fn(),
    |        ^^^^ required by this bound in `foo`
diff --git a/tests/ui/nll/outlives-suggestion-simple.stderr b/tests/ui/nll/outlives-suggestion-simple.stderr
index a8368c494ed..bcffd575aed 100644
--- a/tests/ui/nll/outlives-suggestion-simple.stderr
+++ b/tests/ui/nll/outlives-suggestion-simple.stderr
@@ -73,7 +73,7 @@ LL | impl<'a> Bar<'a> {
 LL |     pub fn get<'b>(&self) -> &'b usize {
    |                -- lifetime `'b` defined here
 LL |         self.x
-   |         ^^^^^^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+   |         ^^^^^^ method was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
    |
    = help: consider adding the following bound: `'a: 'b`
 
@@ -85,7 +85,7 @@ LL | impl<'a> Baz<'a> {
 LL |     fn get<'b>(&'b self) -> &'a i32 {
    |            -- lifetime `'b` defined here
 LL |         self.x
-   |         ^^^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+   |         ^^^^^^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
    |
    = help: consider adding the following bound: `'b: 'a`
 
diff --git a/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr b/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr
index f05b0cd6538..40429fe756f 100644
--- a/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr
+++ b/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr
@@ -1,5 +1,10 @@
 error[E0311]: the parameter type `Self` may not live long enough
    |
+note: the parameter type `Self` must be valid for the lifetime `'a` as defined here...
+  --> $DIR/object-safety-supertrait-mentions-GAT.rs:9:26
+   |
+LL | trait SuperTrait<T>: for<'a> GatTrait<Gat<'a> = T> {
+   |                          ^^
    = help: consider adding an explicit lifetime bound `Self: 'a`...
    = note: ...so that the type `Self` will meet its required lifetime bounds...
 note: ...that is required by this bound
diff --git a/tests/ui/privacy/privacy1.rs b/tests/ui/privacy/privacy1.rs
index 3c9fa983dfd..fcb2108ab5f 100644
--- a/tests/ui/privacy/privacy1.rs
+++ b/tests/ui/privacy/privacy1.rs
@@ -106,7 +106,7 @@ mod foo {
                                 //~^ ERROR: associated function `bar` is private
         ::bar::baz::A.foo2();   //~ ERROR: module `baz` is private
         ::bar::baz::A.bar2();   //~ ERROR: module `baz` is private
-                                //~^ ERROR: associated function `bar2` is private
+                                //~^ ERROR: method `bar2` is private
 
         let _: isize =
         ::bar::B::foo();        //~ ERROR: trait `B` is private
diff --git a/tests/ui/privacy/privacy1.stderr b/tests/ui/privacy/privacy1.stderr
index 70e6fcb7a07..6ebed8ee062 100644
--- a/tests/ui/privacy/privacy1.stderr
+++ b/tests/ui/privacy/privacy1.stderr
@@ -190,14 +190,14 @@ LL |             fn bar() {}
 LL |         ::bar::baz::A::bar();
    |                        ^^^ private associated function
 
-error[E0624]: associated function `bar2` is private
+error[E0624]: method `bar2` is private
   --> $DIR/privacy1.rs:108:23
    |
 LL |             fn bar2(&self) {}
-   |             -------------- private associated function defined here
+   |             -------------- private method defined here
 ...
 LL |         ::bar::baz::A.bar2();
-   |                       ^^^^ private associated function
+   |                       ^^^^ private method
 
 error: aborting due to 18 previous errors
 
diff --git a/tests/ui/privacy/private-impl-method.rs b/tests/ui/privacy/private-impl-method.rs
index f7be6726c5e..b5587920f1c 100644
--- a/tests/ui/privacy/private-impl-method.rs
+++ b/tests/ui/privacy/private-impl-method.rs
@@ -17,5 +17,5 @@ fn f() {
 fn main() {
     let s = a::Foo { x: 1 };
     s.bar();
-    s.foo();    //~ ERROR associated function `foo` is private
+    s.foo();    //~ ERROR method `foo` is private
 }
diff --git a/tests/ui/privacy/private-impl-method.stderr b/tests/ui/privacy/private-impl-method.stderr
index bb54dce7e7e..18e4531d112 100644
--- a/tests/ui/privacy/private-impl-method.stderr
+++ b/tests/ui/privacy/private-impl-method.stderr
@@ -1,11 +1,11 @@
-error[E0624]: associated function `foo` is private
+error[E0624]: method `foo` is private
   --> $DIR/private-impl-method.rs:20:7
    |
 LL |         fn foo(&self) {}
-   |         ------------- private associated function defined here
+   |         ------------- private method defined here
 ...
 LL |     s.foo();
-   |       ^^^ private associated function
+   |       ^^^ private method
 
 error: aborting due to previous error
 
diff --git a/tests/ui/privacy/private-method-cross-crate.rs b/tests/ui/privacy/private-method-cross-crate.rs
index ab3bbdfe496..4da44e0682b 100644
--- a/tests/ui/privacy/private-method-cross-crate.rs
+++ b/tests/ui/privacy/private-method-cross-crate.rs
@@ -4,5 +4,5 @@ use cci_class_5::kitties::cat;
 
 fn main() {
   let nyan : cat = cat(52, 99);
-  nyan.nap();   //~ ERROR associated function `nap` is private
+  nyan.nap();   //~ ERROR method `nap` is private
 }
diff --git a/tests/ui/privacy/private-method-cross-crate.stderr b/tests/ui/privacy/private-method-cross-crate.stderr
index 93f6a7f2f61..e644440c827 100644
--- a/tests/ui/privacy/private-method-cross-crate.stderr
+++ b/tests/ui/privacy/private-method-cross-crate.stderr
@@ -1,13 +1,13 @@
-error[E0624]: associated function `nap` is private
+error[E0624]: method `nap` is private
   --> $DIR/private-method-cross-crate.rs:7:8
    |
 LL |   nyan.nap();
-   |        ^^^ private associated function
+   |        ^^^ private method
    |
   ::: $DIR/auxiliary/cci_class_5.rs:8:9
    |
 LL |         fn nap(&self) {}
-   |         ------------- private associated function defined here
+   |         ------------- private method defined here
 
 error: aborting due to previous error
 
diff --git a/tests/ui/privacy/private-method-inherited.rs b/tests/ui/privacy/private-method-inherited.rs
index 2f6454288ae..bc27027e886 100644
--- a/tests/ui/privacy/private-method-inherited.rs
+++ b/tests/ui/privacy/private-method-inherited.rs
@@ -10,5 +10,5 @@ mod a {
 
 fn main() {
     let x = a::Foo;
-    x.f();  //~ ERROR associated function `f` is private
+    x.f();  //~ ERROR method `f` is private
 }
diff --git a/tests/ui/privacy/private-method-inherited.stderr b/tests/ui/privacy/private-method-inherited.stderr
index 011a7fee478..0104a1b27e4 100644
--- a/tests/ui/privacy/private-method-inherited.stderr
+++ b/tests/ui/privacy/private-method-inherited.stderr
@@ -1,11 +1,11 @@
-error[E0624]: associated function `f` is private
+error[E0624]: method `f` is private
   --> $DIR/private-method-inherited.rs:13:7
    |
 LL |         fn f(self) {}
-   |         ---------- private associated function defined here
+   |         ---------- private method defined here
 ...
 LL |     x.f();
-   |       ^ private associated function
+   |       ^ private method
 
 error: aborting due to previous error
 
diff --git a/tests/ui/privacy/private-method.rs b/tests/ui/privacy/private-method.rs
index 76a642cde1a..a9bea520e75 100644
--- a/tests/ui/privacy/private-method.rs
+++ b/tests/ui/privacy/private-method.rs
@@ -19,5 +19,5 @@ mod kitties {
 
 fn main() {
   let nyan : kitties::Cat = kitties::cat(52, 99);
-  nyan.nap(); //~ ERROR associated function `nap` is private
+  nyan.nap(); //~ ERROR method `nap` is private
 }
diff --git a/tests/ui/privacy/private-method.stderr b/tests/ui/privacy/private-method.stderr
index 17c7179dc36..42fec762265 100644
--- a/tests/ui/privacy/private-method.stderr
+++ b/tests/ui/privacy/private-method.stderr
@@ -1,11 +1,11 @@
-error[E0624]: associated function `nap` is private
+error[E0624]: method `nap` is private
   --> $DIR/private-method.rs:22:8
    |
 LL |         fn nap(&self) {}
-   |         ------------- private associated function defined here
+   |         ------------- private method defined here
 ...
 LL |   nyan.nap();
-   |        ^^^ private associated function
+   |        ^^^ private method
 
 error: aborting due to previous error
 
diff --git a/tests/ui/privacy/restricted/test.stderr b/tests/ui/privacy/restricted/test.stderr
index 1acd221b42c..76f19525df5 100644
--- a/tests/ui/privacy/restricted/test.stderr
+++ b/tests/ui/privacy/restricted/test.stderr
@@ -54,14 +54,14 @@ error[E0616]: field `x` of struct `S` is private
 LL |     S::default().x;
    |                  ^ private field
 
-error[E0624]: associated function `f` is private
+error[E0624]: method `f` is private
   --> $DIR/test.rs:32:18
    |
 LL |             pub(super) fn f(&self) {}
-   |             ---------------------- private associated function defined here
+   |             ---------------------- private method defined here
 ...
 LL |     S::default().f();
-   |                  ^ private associated function
+   |                  ^ private method
 
 error[E0624]: associated function `g` is private
   --> $DIR/test.rs:33:8
@@ -84,27 +84,27 @@ error[E0616]: field `z` of struct `Universe` is private
 LL |     let _ = u.z;
    |               ^ private field
 
-error[E0624]: associated function `g` is private
+error[E0624]: method `g` is private
   --> $DIR/test.rs:45:7
    |
 LL |     u.g();
-   |       ^ private associated function
+   |       ^ private method
    |
   ::: $DIR/auxiliary/pub_restricted.rs:12:5
    |
 LL |     pub(crate) fn g(&self) {}
-   |     ---------------------- private associated function defined here
+   |     ---------------------- private method defined here
 
-error[E0624]: associated function `h` is private
+error[E0624]: method `h` is private
   --> $DIR/test.rs:46:7
    |
 LL |     u.h();
-   |       ^ private associated function
+   |       ^ private method
    |
   ::: $DIR/auxiliary/pub_restricted.rs:13:5
    |
 LL |     pub(crate) fn h(&self) {}
-   |     ---------------------- private associated function defined here
+   |     ---------------------- private method defined here
 
 error: aborting due to 12 previous errors
 
diff --git a/tests/ui/recursion_limit/issue_21102.rs b/tests/ui/recursion_limit/issue-105700.rs
index e1fee46313d..e1fee46313d 100644
--- a/tests/ui/recursion_limit/issue_21102.rs
+++ b/tests/ui/recursion_limit/issue-105700.rs
diff --git a/tests/ui/recursion_limit/issue_21102.stderr b/tests/ui/recursion_limit/issue-105700.stderr
index 1bd722c492b..9b1114e9ce6 100644
--- a/tests/ui/recursion_limit/issue_21102.stderr
+++ b/tests/ui/recursion_limit/issue-105700.stderr
@@ -1,10 +1,10 @@
 error: recursion limit reached while expanding `#[invalid_attribute]`
-  --> $DIR/issue_21102.rs:6:1
+  --> $DIR/issue-105700.rs:6:1
    |
 LL | #![invalid_attribute]
    | ^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "8"]` attribute to your crate (`issue_21102`)
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "8"]` attribute to your crate (`issue_105700`)
 
 error: aborting due to previous error
 
diff --git a/tests/ui/regions/regions-early-bound-error-method.stderr b/tests/ui/regions/regions-early-bound-error-method.stderr
index 7f10c051f29..a7746d8981e 100644
--- a/tests/ui/regions/regions-early-bound-error-method.stderr
+++ b/tests/ui/regions/regions-early-bound-error-method.stderr
@@ -6,7 +6,7 @@ LL | impl<'a> Box<'a> {
 LL |     fn or<'b,G:GetRef<'b>>(&self, g2: G) -> &'a isize {
    |           -- lifetime `'b` defined here
 LL |         g2.get()
-   |         ^^^^^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+   |         ^^^^^^^^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
    |
    = help: consider adding the following bound: `'b: 'a`
 
diff --git a/tests/ui/regions/regions-free-region-ordering-incorrect.stderr b/tests/ui/regions/regions-free-region-ordering-incorrect.stderr
index f7c75033c04..d0ceaec3b67 100644
--- a/tests/ui/regions/regions-free-region-ordering-incorrect.stderr
+++ b/tests/ui/regions/regions-free-region-ordering-incorrect.stderr
@@ -9,7 +9,7 @@ LL | /         match self.next {
 LL | |             Some(ref next) => next.get(),
 LL | |             None => &self.val
 LL | |         }
-   | |_________^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+   | |_________^ method was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
    |
    = help: consider adding the following bound: `'a: 'b`
 
diff --git a/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs b/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs
index 7c2e1aeeea6..46462c432a8 100644
--- a/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs
+++ b/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs
@@ -8,6 +8,8 @@
 //
 //     'a : 'b
 
+#![warn(unused_lifetimes)]
+
 fn test<'a,'b>(x: &'a i32) -> &'b i32
     where 'a: 'static //~ WARN unnecessary lifetime parameter `'a`
 {
diff --git a/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.stderr b/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.stderr
index 70ed418d5cb..9f03a6553ba 100644
--- a/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.stderr
+++ b/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.stderr
@@ -1,10 +1,15 @@
 warning: unnecessary lifetime parameter `'a`
-  --> $DIR/regions-free-region-outlives-static-outlives-free-region.rs:12:11
+  --> $DIR/regions-free-region-outlives-static-outlives-free-region.rs:14:11
    |
 LL |     where 'a: 'static
    |           ^^
    |
    = help: you can use the `'static` lifetime directly, in place of `'a`
+note: the lint level is defined here
+  --> $DIR/regions-free-region-outlives-static-outlives-free-region.rs:11:9
+   |
+LL | #![warn(unused_lifetimes)]
+   |         ^^^^^^^^^^^^^^^^
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/regions/regions-static-bound-rpass.rs b/tests/ui/regions/regions-static-bound-rpass.rs
index 25232b455b6..e2ebb394d0a 100644
--- a/tests/ui/regions/regions-static-bound-rpass.rs
+++ b/tests/ui/regions/regions-static-bound-rpass.rs
@@ -1,5 +1,7 @@
 // run-pass
 
+#![warn(unused_lifetimes)]
+
 fn invariant_id<'a,'b>(t: &'b mut &'static ()) -> &'b mut &'a ()
     where 'a: 'static { t }
 //~^ WARN unnecessary lifetime parameter `'a`
diff --git a/tests/ui/regions/regions-static-bound-rpass.stderr b/tests/ui/regions/regions-static-bound-rpass.stderr
index 9355a409d50..f0f3a4c5261 100644
--- a/tests/ui/regions/regions-static-bound-rpass.stderr
+++ b/tests/ui/regions/regions-static-bound-rpass.stderr
@@ -1,13 +1,18 @@
 warning: unnecessary lifetime parameter `'a`
-  --> $DIR/regions-static-bound-rpass.rs:4:11
+  --> $DIR/regions-static-bound-rpass.rs:6:11
    |
 LL |     where 'a: 'static { t }
    |           ^^
    |
    = help: you can use the `'static` lifetime directly, in place of `'a`
+note: the lint level is defined here
+  --> $DIR/regions-static-bound-rpass.rs:3:9
+   |
+LL | #![warn(unused_lifetimes)]
+   |         ^^^^^^^^^^^^^^^^
 
 warning: unnecessary lifetime parameter `'a`
-  --> $DIR/regions-static-bound-rpass.rs:8:11
+  --> $DIR/regions-static-bound-rpass.rs:10:11
    |
 LL |     where 'a: 'static { t }
    |           ^^
@@ -15,7 +20,7 @@ LL |     where 'a: 'static { t }
    = help: you can use the `'static` lifetime directly, in place of `'a`
 
 warning: unnecessary lifetime parameter `'b`
-  --> $DIR/regions-static-bound-rpass.rs:12:19
+  --> $DIR/regions-static-bound-rpass.rs:14:19
    |
 LL |     where 'a: 'b, 'b: 'static { t }
    |                   ^^
diff --git a/tests/ui/regions/regions-static-bound.rs b/tests/ui/regions/regions-static-bound.rs
index 4d2455470e2..e7aa8795f01 100644
--- a/tests/ui/regions/regions-static-bound.rs
+++ b/tests/ui/regions/regions-static-bound.rs
@@ -1,6 +1,8 @@
-fn static_id<'a,'b>(t: &'a ()) -> &'static ()
-    where 'a: 'static { t }
-//~^ WARN unnecessary lifetime parameter `'a`
+#![warn(unused_lifetimes)]
+
+fn static_id<'a,'b>(t: &'a ()) -> &'static () where 'a: 'static { t }
+//~^ WARN lifetime parameter `'b` never used
+//~| WARN unnecessary lifetime parameter `'a`
 
 fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static ()
     where 'a: 'b, 'b: 'static { t }
diff --git a/tests/ui/regions/regions-static-bound.stderr b/tests/ui/regions/regions-static-bound.stderr
index 2886ec3ead5..b314e9fe85d 100644
--- a/tests/ui/regions/regions-static-bound.stderr
+++ b/tests/ui/regions/regions-static-bound.stderr
@@ -1,13 +1,27 @@
+warning: lifetime parameter `'b` never used
+  --> $DIR/regions-static-bound.rs:3:17
+   |
+LL | fn static_id<'a,'b>(t: &'a ()) -> &'static () where 'a: 'static { t }
+   |                -^^
+   |                |
+   |                help: elide the unused lifetime
+   |
+note: the lint level is defined here
+  --> $DIR/regions-static-bound.rs:1:9
+   |
+LL | #![warn(unused_lifetimes)]
+   |         ^^^^^^^^^^^^^^^^
+
 warning: unnecessary lifetime parameter `'a`
-  --> $DIR/regions-static-bound.rs:2:11
+  --> $DIR/regions-static-bound.rs:3:53
    |
-LL |     where 'a: 'static { t }
-   |           ^^
+LL | fn static_id<'a,'b>(t: &'a ()) -> &'static () where 'a: 'static { t }
+   |                                                     ^^
    |
    = help: you can use the `'static` lifetime directly, in place of `'a`
 
 warning: unnecessary lifetime parameter `'b`
-  --> $DIR/regions-static-bound.rs:6:19
+  --> $DIR/regions-static-bound.rs:8:19
    |
 LL |     where 'a: 'b, 'b: 'static { t }
    |                   ^^
@@ -15,7 +29,7 @@ LL |     where 'a: 'b, 'b: 'static { t }
    = help: you can use the `'static` lifetime directly, in place of `'b`
 
 error: lifetime may not live long enough
-  --> $DIR/regions-static-bound.rs:10:5
+  --> $DIR/regions-static-bound.rs:12:5
    |
 LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
    |                        -- lifetime `'a` defined here
@@ -23,7 +37,7 @@ LL |     t
    |     ^ returning this value requires that `'a` must outlive `'static`
 
 error[E0521]: borrowed data escapes outside of function
-  --> $DIR/regions-static-bound.rs:15:5
+  --> $DIR/regions-static-bound.rs:17:5
    |
 LL | fn error(u: &(), v: &()) {
    |          -  - let's call the lifetime of this reference `'1`
@@ -36,7 +50,7 @@ LL |     static_id(&u);
    |     argument requires that `'1` must outlive `'static`
 
 error[E0521]: borrowed data escapes outside of function
-  --> $DIR/regions-static-bound.rs:17:5
+  --> $DIR/regions-static-bound.rs:19:5
    |
 LL | fn error(u: &(), v: &()) {
    |                  -  - let's call the lifetime of this reference `'2`
@@ -49,6 +63,6 @@ LL |     static_id_indirect(&v);
    |     `v` escapes the function body here
    |     argument requires that `'2` must outlive `'static`
 
-error: aborting due to 3 previous errors; 2 warnings emitted
+error: aborting due to 3 previous errors; 3 warnings emitted
 
 For more information about this error, try `rustc --explain E0521`.
diff --git a/tests/ui/regions/resolve-re-error-ice.rs b/tests/ui/regions/resolve-re-error-ice.rs
new file mode 100644
index 00000000000..f37b27a82b3
--- /dev/null
+++ b/tests/ui/regions/resolve-re-error-ice.rs
@@ -0,0 +1,22 @@
+// check-pass
+
+// Allow this for now, can remove this UI test when this becomes a hard error.
+#![allow(implied_bounds_entailment)]
+
+use std::collections::hash_map::{Keys, HashMap};
+use std::marker::PhantomData;
+
+trait MapAssertion<'a, K, V, R> {
+    fn key_set(&self) -> Subject<Keys<K, V>, (), R>;
+}
+
+struct Subject<'a, T, V, R>(PhantomData<(&'a T, V, R)>);
+
+impl<'a, K, V, R> MapAssertion<'a, K, V, R> for Subject<'a, HashMap<K, V>, (), R>
+{
+    fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> {
+        todo!()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/regions/resolve-re-error-ice.stderr b/tests/ui/regions/resolve-re-error-ice.stderr
new file mode 100644
index 00000000000..e7003e1c32f
--- /dev/null
+++ b/tests/ui/regions/resolve-re-error-ice.stderr
@@ -0,0 +1,15 @@
+Future incompatibility report: Future breakage diagnostic:
+warning: impl method assumes more implied bounds than the corresponding trait method
+  --> $DIR/resolve-re-error-ice.rs:17:16
+   |
+LL |     fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> {
+   |                ^^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `Subject<'_, std::collections::hash_map::Keys<'_, K, V>, (), R>`
+   |
+   = 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 #105572 <https://github.com/rust-lang/rust/issues/105572>
+note: the lint level is defined here
+  --> $DIR/resolve-re-error-ice.rs:4:10
+   |
+LL | #![allow(implied_bounds_entailment)]
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/tests/ui/rfc-2091-track-caller/error-with-main.stderr b/tests/ui/rfc-2091-track-caller/error-with-main.stderr
index 7e2ec352414..6d6562dae3b 100644
--- a/tests/ui/rfc-2091-track-caller/error-with-main.stderr
+++ b/tests/ui/rfc-2091-track-caller/error-with-main.stderr
@@ -2,7 +2,7 @@ error: `main` function is not allowed to be `#[track_caller]`
   --> $DIR/error-with-main.rs:1:1
    |
 LL | #[track_caller]
-   | ^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^ help: remove this annotation
 LL | fn main() {
    | --------- `main` function is not allowed to be `#[track_caller]`
 
diff --git a/tests/ui/rfc-2457/mod_file_nonascii_forbidden.stderr b/tests/ui/rfc-2457/mod_file_nonascii_forbidden.stderr
index dd0dac95e36..7639ae9f6a4 100644
--- a/tests/ui/rfc-2457/mod_file_nonascii_forbidden.stderr
+++ b/tests/ui/rfc-2457/mod_file_nonascii_forbidden.stderr
@@ -12,7 +12,7 @@ error[E0754]: trying to load file for module `řųśť` with non-ascii identifie
 LL | mod řųśť;
    |     ^^^^
    |
-   = help: consider using `#[path]` attribute to specify filesystem path
+   = help: consider using the `#[path]` attribute to specify filesystem path
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/rfc-2632-const-trait-impl/do-not-const-check-override.rs b/tests/ui/rfc-2632-const-trait-impl/do-not-const-check-override.rs
new file mode 100644
index 00000000000..730e268c091
--- /dev/null
+++ b/tests/ui/rfc-2632-const-trait-impl/do-not-const-check-override.rs
@@ -0,0 +1,19 @@
+// check-pass
+#![feature(const_trait_impl, rustc_attrs)]
+
+#[const_trait]
+trait Foo {
+    #[rustc_do_not_const_check]
+    fn into_iter(&self) { println!("FEAR ME!") }
+}
+
+
+impl const Foo for () {
+    fn into_iter(&self) {
+        // ^_^
+    }
+}
+
+const _: () = Foo::into_iter(&());
+
+fn main() {}
diff --git a/tests/ui/rfc-2632-const-trait-impl/do-not-const-check.rs b/tests/ui/rfc-2632-const-trait-impl/do-not-const-check.rs
new file mode 100644
index 00000000000..3c39c53de5f
--- /dev/null
+++ b/tests/ui/rfc-2632-const-trait-impl/do-not-const-check.rs
@@ -0,0 +1,18 @@
+// check-pass
+#![feature(const_trait_impl, rustc_attrs)]
+
+#[const_trait]
+trait IntoIter {
+    fn into_iter(self);
+}
+
+#[const_trait]
+trait Hmm: Sized {
+    #[rustc_do_not_const_check]
+    fn chain<U>(self, other: U) where U: IntoIter,
+    {
+        other.into_iter()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr b/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
index 6180e1e0f2d..0b4c0a7fece 100644
--- a/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
+++ b/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
@@ -2,7 +2,7 @@ error: lifetime may not live long enough
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:52
    |
 LL |     async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
-   |                          -         -               ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |                          -         -               ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |                          |         |
    |                          |         let's call the lifetime of this reference `'1`
    |                          let's call the lifetime of this reference `'2`
@@ -16,7 +16,7 @@ error: lifetime may not live long enough
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:75
    |
 LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
-   |                          -          -                                     ^^^^^^^^^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |                          -          -                                     ^^^^^^^^^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |                          |          |
    |                          |          let's call the lifetime of this reference `'1`
    |                          let's call the lifetime of this reference `'2`
@@ -30,7 +30,7 @@ error: lifetime may not live long enough
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64
    |
 LL |     async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
-   |                  --              -                             ^^^ associated function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a`
+   |                  --              -                             ^^^ method was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a`
    |                  |               |
    |                  |               let's call the lifetime of this reference `'1`
    |                  lifetime `'a` defined here
diff --git a/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr b/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr
index fccee5d4363..209dae9c1b3 100644
--- a/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr
+++ b/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr
@@ -2,7 +2,7 @@ error: lifetime may not live long enough
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:6:46
    |
 LL |     fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
-   |                    -         -               ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |                    -         -               ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |                    |         |
    |                    |         let's call the lifetime of this reference `'1`
    |                    let's call the lifetime of this reference `'2`
@@ -16,7 +16,7 @@ error: lifetime may not live long enough
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:9:69
    |
 LL |     fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
-   |                    -          -                                     ^^^^^^^^^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |                    -          -                                     ^^^^^^^^^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |                    |          |
    |                    |          let's call the lifetime of this reference `'1`
    |                    let's call the lifetime of this reference `'2`
@@ -30,7 +30,7 @@ error: lifetime may not live long enough
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:15:58
    |
 LL |     fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
-   |            --  ---- has type `Pin<&'1 Foo>`              ^^^ associated function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a`
+   |            --  ---- has type `Pin<&'1 Foo>`              ^^^ method was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a`
    |            |
    |            lifetime `'a` defined here
 
diff --git a/tests/ui/self/elision/lt-ref-self-async.stderr b/tests/ui/self/elision/lt-ref-self-async.stderr
index 787afd4dc9d..29d60ed6635 100644
--- a/tests/ui/self/elision/lt-ref-self-async.stderr
+++ b/tests/ui/self/elision/lt-ref-self-async.stderr
@@ -6,7 +6,7 @@ LL |     async fn ref_self(&self, f: &u32) -> &u32 {
    |                       |
    |                       let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -21,7 +21,7 @@ LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                             |
    |                             let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -36,7 +36,7 @@ LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                                     |
    |                                     let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -51,7 +51,7 @@ LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                                     |
    |                                     let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -66,7 +66,7 @@ LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                             |
    |                                             let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -81,7 +81,7 @@ LL |     async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                         |
    |                                         let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
diff --git a/tests/ui/self/elision/lt-ref-self.stderr b/tests/ui/self/elision/lt-ref-self.stderr
index 49af638e4c6..216737a2c73 100644
--- a/tests/ui/self/elision/lt-ref-self.stderr
+++ b/tests/ui/self/elision/lt-ref-self.stderr
@@ -6,7 +6,7 @@ LL |     fn ref_self(&self, f: &u32) -> &u32 {
    |                 |
    |                 let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -21,7 +21,7 @@ LL |     fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                       |
    |                       let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -36,7 +36,7 @@ LL |     fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                               |
    |                               let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -51,7 +51,7 @@ LL |     fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                               |
    |                               let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -66,7 +66,7 @@ LL |     fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                       |
    |                                       let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -81,7 +81,7 @@ LL |     fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                   |
    |                                   let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
diff --git a/tests/ui/self/elision/ref-mut-self-async.stderr b/tests/ui/self/elision/ref-mut-self-async.stderr
index dff50aee918..62543ba5339 100644
--- a/tests/ui/self/elision/ref-mut-self-async.stderr
+++ b/tests/ui/self/elision/ref-mut-self-async.stderr
@@ -6,7 +6,7 @@ LL |     async fn ref_self(&mut self, f: &u32) -> &u32 {
    |                       |
    |                       let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -21,7 +21,7 @@ LL |     async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
    |                             |
    |                             let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -36,7 +36,7 @@ LL |     async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
    |                                     |
    |                                     let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -51,7 +51,7 @@ LL |     async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
    |                                     |
    |                                     let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -66,7 +66,7 @@ LL |     async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
    |                                             |
    |                                             let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -81,7 +81,7 @@ LL |     async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
    |                                             |
    |                                             let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
diff --git a/tests/ui/self/elision/ref-mut-self.stderr b/tests/ui/self/elision/ref-mut-self.stderr
index ccf1830167c..12b64a3f6dc 100644
--- a/tests/ui/self/elision/ref-mut-self.stderr
+++ b/tests/ui/self/elision/ref-mut-self.stderr
@@ -6,7 +6,7 @@ LL |     fn ref_self(&mut self, f: &u32) -> &u32 {
    |                 |
    |                 let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -21,7 +21,7 @@ LL |     fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
    |                       |
    |                       let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -36,7 +36,7 @@ LL |     fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
    |                               |
    |                               let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -51,7 +51,7 @@ LL |     fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
    |                               |
    |                               let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -66,7 +66,7 @@ LL |     fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
    |                                       |
    |                                       let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -81,7 +81,7 @@ LL |     fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
    |                                       |
    |                                       let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
diff --git a/tests/ui/self/elision/ref-mut-struct-async.stderr b/tests/ui/self/elision/ref-mut-struct-async.stderr
index 5b7ad026f9d..f8fb2e4a138 100644
--- a/tests/ui/self/elision/ref-mut-struct-async.stderr
+++ b/tests/ui/self/elision/ref-mut-struct-async.stderr
@@ -6,7 +6,7 @@ LL |     async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
    |                               |
    |                               let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -21,7 +21,7 @@ LL |     async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
    |                                       |
    |                                       let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -36,7 +36,7 @@ LL |     async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
    |                                       |
    |                                       let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -51,7 +51,7 @@ LL |     async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u
    |                                               |
    |                                               let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -66,7 +66,7 @@ LL |     async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u
    |                                               |
    |                                               let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
diff --git a/tests/ui/self/elision/ref-mut-struct.stderr b/tests/ui/self/elision/ref-mut-struct.stderr
index b9c71e8433c..cde16ce8ba4 100644
--- a/tests/ui/self/elision/ref-mut-struct.stderr
+++ b/tests/ui/self/elision/ref-mut-struct.stderr
@@ -6,7 +6,7 @@ LL |     fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
    |                         |
    |                         let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -21,7 +21,7 @@ LL |     fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
    |                                 |
    |                                 let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -36,7 +36,7 @@ LL |     fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
    |                                 |
    |                                 let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -51,7 +51,7 @@ LL |     fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
    |                                         |
    |                                         let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -66,7 +66,7 @@ LL |     fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
    |                                         |
    |                                         let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
diff --git a/tests/ui/self/elision/ref-self-async.stderr b/tests/ui/self/elision/ref-self-async.stderr
index 26ef9779be2..010d281b002 100644
--- a/tests/ui/self/elision/ref-self-async.stderr
+++ b/tests/ui/self/elision/ref-self-async.stderr
@@ -6,7 +6,7 @@ LL |     async fn ref_self(&self, f: &u32) -> &u32 {
    |                       |
    |                       let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -21,7 +21,7 @@ LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                             |
    |                             let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -36,7 +36,7 @@ LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                                     |
    |                                     let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -51,7 +51,7 @@ LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                                     |
    |                                     let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -66,7 +66,7 @@ LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                             |
    |                                             let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -81,7 +81,7 @@ LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                             |
    |                                             let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -96,7 +96,7 @@ LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
    |                                            |
    |                                            let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
diff --git a/tests/ui/self/elision/ref-self.stderr b/tests/ui/self/elision/ref-self.stderr
index 32448f3a677..35693257c99 100644
--- a/tests/ui/self/elision/ref-self.stderr
+++ b/tests/ui/self/elision/ref-self.stderr
@@ -6,7 +6,7 @@ LL |     fn ref_self(&self, f: &u32) -> &u32 {
    |                 |
    |                 let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -21,7 +21,7 @@ LL |     fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                       |
    |                       let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -36,7 +36,7 @@ LL |     fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                               |
    |                               let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -51,7 +51,7 @@ LL |     fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                               |
    |                               let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -66,7 +66,7 @@ LL |     fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                       |
    |                                       let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -81,7 +81,7 @@ LL |     fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                       |
    |                                       let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -96,7 +96,7 @@ LL |     fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
    |                                      |
    |                                      let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
diff --git a/tests/ui/self/elision/ref-struct-async.stderr b/tests/ui/self/elision/ref-struct-async.stderr
index edb5c54ab00..c9376d58f90 100644
--- a/tests/ui/self/elision/ref-struct-async.stderr
+++ b/tests/ui/self/elision/ref-struct-async.stderr
@@ -6,7 +6,7 @@ LL |     async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |                               |
    |                               let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -21,7 +21,7 @@ LL |     async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
    |                                       |
    |                                       let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -36,7 +36,7 @@ LL |     async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
    |                                       |
    |                                       let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -51,7 +51,7 @@ LL |     async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
    |                                               |
    |                                               let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -66,7 +66,7 @@ LL |     async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
    |                                           |
    |                                           let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
diff --git a/tests/ui/self/elision/ref-struct.stderr b/tests/ui/self/elision/ref-struct.stderr
index 4492ed4aafc..a3d3cebeba9 100644
--- a/tests/ui/self/elision/ref-struct.stderr
+++ b/tests/ui/self/elision/ref-struct.stderr
@@ -6,7 +6,7 @@ LL |     fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |                         |
    |                         let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -21,7 +21,7 @@ LL |     fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
    |                                 |
    |                                 let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -36,7 +36,7 @@ LL |     fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
    |                                 |
    |                                 let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -51,7 +51,7 @@ LL |     fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
    |                                         |
    |                                         let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
@@ -66,7 +66,7 @@ LL |     fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
    |                                     |
    |                                     let's call the lifetime of this reference `'2`
 LL |         f
-   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |         ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
    |
 help: consider introducing a named lifetime parameter and update trait if needed
    |
diff --git a/tests/ui/seq-args.rs b/tests/ui/seq-args.rs
index a5ebeecd311..627dfcc3198 100644
--- a/tests/ui/seq-args.rs
+++ b/tests/ui/seq-args.rs
@@ -2,12 +2,12 @@ fn main() {
     trait Seq { }
 
     impl<T> Seq<T> for Vec<T> {
-        //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+        //~^ ERROR trait takes 0 generic arguments but 1 generic argument
         /* ... */
     }
 
     impl Seq<bool> for u32 {
-        //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+        //~^ ERROR trait takes 0 generic arguments but 1 generic argument
         /* Treat the integer as a sequence of bits */
     }
 }
diff --git a/tests/ui/seq-args.stderr b/tests/ui/seq-args.stderr
index c404d95748b..a5b0f8e98dc 100644
--- a/tests/ui/seq-args.stderr
+++ b/tests/ui/seq-args.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/seq-args.rs:4:13
    |
 LL |     impl<T> Seq<T> for Vec<T> {
@@ -12,7 +12,7 @@ note: trait defined here, with 0 generic parameters
 LL |     trait Seq { }
    |           ^^^
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/seq-args.rs:9:10
    |
 LL |     impl Seq<bool> for u32 {
diff --git a/tests/ui/span/issue-37767.stderr b/tests/ui/span/issue-37767.stderr
index f7732847a28..b612fdf16fc 100644
--- a/tests/ui/span/issue-37767.stderr
+++ b/tests/ui/span/issue-37767.stderr
@@ -14,11 +14,11 @@ note: candidate #2 is defined in the trait `B`
    |
 LL |     fn foo(&mut self) {}
    |     ^^^^^^^^^^^^^^^^^
-help: disambiguate the associated function for candidate #1
+help: disambiguate the method for candidate #1
    |
 LL |     A::foo(&a)
    |     ~~~~~~~~~~
-help: disambiguate the associated function for candidate #2
+help: disambiguate the method for candidate #2
    |
 LL |     B::foo(&a)
    |     ~~~~~~~~~~
@@ -39,11 +39,11 @@ note: candidate #2 is defined in the trait `D`
    |
 LL |     fn foo(&self) {}
    |     ^^^^^^^^^^^^^
-help: disambiguate the associated function for candidate #1
+help: disambiguate the method for candidate #1
    |
 LL |     C::foo(&a)
    |     ~~~~~~~~~~
-help: disambiguate the associated function for candidate #2
+help: disambiguate the method for candidate #2
    |
 LL |     D::foo(&a)
    |     ~~~~~~~~~~
@@ -64,11 +64,11 @@ note: candidate #2 is defined in the trait `F`
    |
 LL |     fn foo(self) {}
    |     ^^^^^^^^^^^^
-help: disambiguate the associated function for candidate #1
+help: disambiguate the method for candidate #1
    |
 LL |     E::foo(a)
    |     ~~~~~~~~~
-help: disambiguate the associated function for candidate #2
+help: disambiguate the method for candidate #2
    |
 LL |     F::foo(a)
    |     ~~~~~~~~~
diff --git a/tests/ui/span/issue-42234-unknown-receiver-type.full.stderr b/tests/ui/span/issue-42234-unknown-receiver-type.full.stderr
index 2b178990850..e01e1edab5a 100644
--- a/tests/ui/span/issue-42234-unknown-receiver-type.full.stderr
+++ b/tests/ui/span/issue-42234-unknown-receiver-type.full.stderr
@@ -15,7 +15,7 @@ error[E0282]: type annotations needed
   --> $DIR/issue-42234-unknown-receiver-type.rs:15:10
    |
 LL |         .sum::<_>()
-   |          ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum`
+   |          ^^^ cannot infer type of the type parameter `S` declared on the method `sum`
    |
 help: consider specifying the generic argument
    |
diff --git a/tests/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr b/tests/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr
index d93d54e878b..a4b65256574 100644
--- a/tests/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr
+++ b/tests/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr
@@ -15,7 +15,7 @@ error[E0282]: type annotations needed
   --> $DIR/issue-42234-unknown-receiver-type.rs:15:10
    |
 LL |         .sum::<_>()
-   |          ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum`
+   |          ^^^ cannot infer type of the type parameter `S` declared on the method `sum`
    |
 help: consider specifying the generic argument
    |
diff --git a/tests/ui/span/missing-unit-argument.stderr b/tests/ui/span/missing-unit-argument.stderr
index ef4d732b51d..ff89f775334 100644
--- a/tests/ui/span/missing-unit-argument.stderr
+++ b/tests/ui/span/missing-unit-argument.stderr
@@ -65,7 +65,7 @@ error[E0061]: this method takes 1 argument but 0 arguments were supplied
 LL |     S.baz();
    |       ^^^-- an argument of type `()` is missing
    |
-note: associated function defined here
+note: method defined here
   --> $DIR/missing-unit-argument.rs:6:8
    |
 LL |     fn baz(self, (): ()) { }
@@ -81,7 +81,7 @@ error[E0061]: this method takes 1 argument but 0 arguments were supplied
 LL |     S.generic::<()>();
    |       ^^^^^^^^^^^^^-- an argument of type `()` is missing
    |
-note: associated function defined here
+note: method defined here
   --> $DIR/missing-unit-argument.rs:7:8
    |
 LL |     fn generic<T>(self, _: T) { }
diff --git a/tests/ui/span/type-annotations-needed-expr.stderr b/tests/ui/span/type-annotations-needed-expr.stderr
index 9dff6c64db4..65a90318a3c 100644
--- a/tests/ui/span/type-annotations-needed-expr.stderr
+++ b/tests/ui/span/type-annotations-needed-expr.stderr
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/type-annotations-needed-expr.rs:2:39
    |
 LL |     let _ = (vec![1,2,3]).into_iter().sum() as f64;
-   |                                       ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum`
+   |                                       ^^^ cannot infer type of the type parameter `S` declared on the method `sum`
    |
 help: consider specifying the generic argument
    |
diff --git a/tests/ui/stability-attribute/unresolved_stability_lint.rs b/tests/ui/stability-attribute/unresolved_stability_lint.rs
new file mode 100644
index 00000000000..818d228bc91
--- /dev/null
+++ b/tests/ui/stability-attribute/unresolved_stability_lint.rs
@@ -0,0 +1,8 @@
+#![feature(staged_api)]
+#![stable(feature = "uwu", since = "1.0.0")]
+
+#[unstable(feature = "foo", issue = "none")]
+impl Foo for () {}
+//~^ ERROR cannot find trait `Foo` in this scope
+
+fn main() {}
diff --git a/tests/ui/stability-attribute/unresolved_stability_lint.stderr b/tests/ui/stability-attribute/unresolved_stability_lint.stderr
new file mode 100644
index 00000000000..11d6abcaf36
--- /dev/null
+++ b/tests/ui/stability-attribute/unresolved_stability_lint.stderr
@@ -0,0 +1,9 @@
+error[E0405]: cannot find trait `Foo` in this scope
+  --> $DIR/unresolved_stability_lint.rs:5:6
+   |
+LL | impl Foo for () {}
+   |      ^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0405`.
diff --git a/tests/ui/static/static-lifetime-bound.rs b/tests/ui/static/static-lifetime-bound.rs
index b5da91ec3b6..847fe87b2ea 100644
--- a/tests/ui/static/static-lifetime-bound.rs
+++ b/tests/ui/static/static-lifetime-bound.rs
@@ -1,4 +1,4 @@
-fn f<'a: 'static>(_: &'a i32) {} //~WARN unnecessary lifetime parameter `'a`
+fn f<'a: 'static>(_: &'a i32) {}
 
 fn main() {
     let x = 0;
diff --git a/tests/ui/static/static-lifetime-bound.stderr b/tests/ui/static/static-lifetime-bound.stderr
index e22411b13b7..19e55a6582e 100644
--- a/tests/ui/static/static-lifetime-bound.stderr
+++ b/tests/ui/static/static-lifetime-bound.stderr
@@ -1,11 +1,3 @@
-warning: unnecessary lifetime parameter `'a`
-  --> $DIR/static-lifetime-bound.rs:1:6
-   |
-LL | fn f<'a: 'static>(_: &'a i32) {}
-   |      ^^
-   |
-   = help: you can use the `'static` lifetime directly, in place of `'a`
-
 error[E0597]: `x` does not live long enough
   --> $DIR/static-lifetime-bound.rs:5:7
    |
@@ -19,6 +11,6 @@ LL |     f(&x);
 LL | }
    | - `x` dropped here while still borrowed
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/statics/uninhabited-static.stderr b/tests/ui/statics/uninhabited-static.stderr
index ef794bb36ac..437053a4476 100644
--- a/tests/ui/statics/uninhabited-static.stderr
+++ b/tests/ui/statics/uninhabited-static.stderr
@@ -53,10 +53,7 @@ warning: the type `Void` does not permit zero-initialization
   --> $DIR/uninhabited-static.rs:12:31
    |
 LL | static VOID2: Void = unsafe { std::mem::transmute(()) };
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^
-   |                               |
-   |                               this code causes undefined behavior when executed
-   |                               help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
    |
 note: enums with no inhabited variants have no valid value
   --> $DIR/uninhabited-static.rs:4:1
@@ -75,10 +72,7 @@ warning: the type `Void` does not permit zero-initialization
   --> $DIR/uninhabited-static.rs:16:32
    |
 LL | static NEVER2: Void = unsafe { std::mem::transmute(()) };
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^
-   |                                |
-   |                                this code causes undefined behavior when executed
-   |                                help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
    |
 note: enums with no inhabited variants have no valid value
   --> $DIR/uninhabited-static.rs:4:1
diff --git a/tests/ui/stats/hir-stats.stderr b/tests/ui/stats/hir-stats.stderr
index 7d9ff2dfb4d..ee62d8f2d25 100644
--- a/tests/ui/stats/hir-stats.stderr
+++ b/tests/ui/stats/hir-stats.stderr
@@ -1,119 +1,119 @@
 ast-stats-1 PRE EXPANSION AST STATS
 ast-stats-1 Name                Accumulated Size         Count     Item Size
 ast-stats-1 ----------------------------------------------------------------
-ast-stats-1 ExprField                 48 ( 0.6%)             1            48
-ast-stats-1 GenericArgs               56 ( 0.8%)             1            56
-ast-stats-1 - AngleBracketed            56 ( 0.8%)             1
-ast-stats-1 Crate                     56 ( 0.8%)             1            56
-ast-stats-1 Attribute                 64 ( 0.9%)             2            32
-ast-stats-1 - Normal                    32 ( 0.4%)             1
-ast-stats-1 - DocComment                32 ( 0.4%)             1
-ast-stats-1 Local                     72 ( 1.0%)             1            72
-ast-stats-1 WherePredicate            72 ( 1.0%)             1            72
-ast-stats-1 - BoundPredicate            72 ( 1.0%)             1
-ast-stats-1 Arm                       96 ( 1.3%)             2            48
-ast-stats-1 ForeignItem               96 ( 1.3%)             1            96
-ast-stats-1 - Fn                        96 ( 1.3%)             1
-ast-stats-1 FieldDef                 160 ( 2.2%)             2            80
-ast-stats-1 Stmt                     160 ( 2.2%)             5            32
-ast-stats-1 - Local                     32 ( 0.4%)             1
-ast-stats-1 - MacCall                   32 ( 0.4%)             1
-ast-stats-1 - Expr                      96 ( 1.3%)             3
-ast-stats-1 Param                    160 ( 2.2%)             4            40
-ast-stats-1 FnDecl                   200 ( 2.7%)             5            40
-ast-stats-1 Variant                  240 ( 3.2%)             2           120
-ast-stats-1 GenericBound             288 ( 3.9%)             4            72
-ast-stats-1 - Trait                    288 ( 3.9%)             4
-ast-stats-1 Block                    288 ( 3.9%)             6            48
-ast-stats-1 AssocItem                416 ( 5.6%)             4           104
-ast-stats-1 - Type                     208 ( 2.8%)             2
-ast-stats-1 - Fn                       208 ( 2.8%)             2
-ast-stats-1 GenericParam             480 ( 6.5%)             5            96
-ast-stats-1 Expr                     576 ( 7.8%)             8            72
-ast-stats-1 - Path                      72 ( 1.0%)             1
-ast-stats-1 - Match                     72 ( 1.0%)             1
-ast-stats-1 - Struct                    72 ( 1.0%)             1
-ast-stats-1 - Lit                      144 ( 1.9%)             2
-ast-stats-1 - Block                    216 ( 2.9%)             3
-ast-stats-1 Pat                      616 ( 8.3%)             7            88
-ast-stats-1 - Struct                    88 ( 1.2%)             1
-ast-stats-1 - Wild                      88 ( 1.2%)             1
-ast-stats-1 - Ident                    440 ( 5.9%)             5
-ast-stats-1 PathSegment              720 ( 9.7%)            30            24
-ast-stats-1 Ty                       896 (12.1%)            14            64
-ast-stats-1 - Ptr                       64 ( 0.9%)             1
-ast-stats-1 - Ref                       64 ( 0.9%)             1
-ast-stats-1 - ImplicitSelf             128 ( 1.7%)             2
-ast-stats-1 - Path                     640 ( 8.6%)            10
-ast-stats-1 Item                   1_656 (22.3%)             9           184
-ast-stats-1 - Trait                    184 ( 2.5%)             1
-ast-stats-1 - Enum                     184 ( 2.5%)             1
-ast-stats-1 - ForeignMod               184 ( 2.5%)             1
-ast-stats-1 - Impl                     184 ( 2.5%)             1
-ast-stats-1 - Fn                       368 ( 5.0%)             2
-ast-stats-1 - Use                      552 ( 7.4%)             3
+ast-stats-1 GenericArgs               40 ( 0.6%)             1            40
+ast-stats-1 - AngleBracketed            40 ( 0.6%)             1
+ast-stats-1 Crate                     40 ( 0.6%)             1            40
+ast-stats-1 ExprField                 48 ( 0.7%)             1            48
+ast-stats-1 WherePredicate            56 ( 0.9%)             1            56
+ast-stats-1 - BoundPredicate            56 ( 0.9%)             1
+ast-stats-1 Attribute                 64 ( 1.0%)             2            32
+ast-stats-1 - Normal                    32 ( 0.5%)             1
+ast-stats-1 - DocComment                32 ( 0.5%)             1
+ast-stats-1 Local                     72 ( 1.1%)             1            72
+ast-stats-1 Arm                       96 ( 1.5%)             2            48
+ast-stats-1 ForeignItem               96 ( 1.5%)             1            96
+ast-stats-1 - Fn                        96 ( 1.5%)             1
+ast-stats-1 FnDecl                   120 ( 1.8%)             5            24
+ast-stats-1 FieldDef                 160 ( 2.4%)             2            80
+ast-stats-1 Stmt                     160 ( 2.4%)             5            32
+ast-stats-1 - Local                     32 ( 0.5%)             1
+ast-stats-1 - MacCall                   32 ( 0.5%)             1
+ast-stats-1 - Expr                      96 ( 1.5%)             3
+ast-stats-1 Param                    160 ( 2.4%)             4            40
+ast-stats-1 Block                    192 ( 2.9%)             6            32
+ast-stats-1 Variant                  208 ( 3.2%)             2           104
+ast-stats-1 GenericBound             224 ( 3.4%)             4            56
+ast-stats-1 - Trait                    224 ( 3.4%)             4
+ast-stats-1 AssocItem                416 ( 6.3%)             4           104
+ast-stats-1 - Type                     208 ( 3.2%)             2
+ast-stats-1 - Fn                       208 ( 3.2%)             2
+ast-stats-1 GenericParam             480 ( 7.3%)             5            96
+ast-stats-1 Pat                      504 ( 7.7%)             7            72
+ast-stats-1 - Struct                    72 ( 1.1%)             1
+ast-stats-1 - Wild                      72 ( 1.1%)             1
+ast-stats-1 - Ident                    360 ( 5.5%)             5
+ast-stats-1 Expr                     576 ( 8.8%)             8            72
+ast-stats-1 - Path                      72 ( 1.1%)             1
+ast-stats-1 - Match                     72 ( 1.1%)             1
+ast-stats-1 - Struct                    72 ( 1.1%)             1
+ast-stats-1 - Lit                      144 ( 2.2%)             2
+ast-stats-1 - Block                    216 ( 3.3%)             3
+ast-stats-1 PathSegment              720 (11.0%)            30            24
+ast-stats-1 Ty                       896 (13.7%)            14            64
+ast-stats-1 - Ptr                       64 ( 1.0%)             1
+ast-stats-1 - Ref                       64 ( 1.0%)             1
+ast-stats-1 - ImplicitSelf             128 ( 2.0%)             2
+ast-stats-1 - Path                     640 ( 9.8%)            10
+ast-stats-1 Item                   1_224 (18.7%)             9           136
+ast-stats-1 - Trait                    136 ( 2.1%)             1
+ast-stats-1 - Enum                     136 ( 2.1%)             1
+ast-stats-1 - ForeignMod               136 ( 2.1%)             1
+ast-stats-1 - Impl                     136 ( 2.1%)             1
+ast-stats-1 - Fn                       272 ( 4.2%)             2
+ast-stats-1 - Use                      408 ( 6.2%)             3
 ast-stats-1 ----------------------------------------------------------------
-ast-stats-1 Total                  7_416
+ast-stats-1 Total                  6_552
 ast-stats-1
 ast-stats-2 POST EXPANSION AST STATS
 ast-stats-2 Name                Accumulated Size         Count     Item Size
 ast-stats-2 ----------------------------------------------------------------
-ast-stats-2 ExprField                 48 ( 0.6%)             1            48
-ast-stats-2 GenericArgs               56 ( 0.7%)             1            56
-ast-stats-2 - AngleBracketed            56 ( 0.7%)             1
-ast-stats-2 Crate                     56 ( 0.7%)             1            56
-ast-stats-2 Local                     72 ( 0.9%)             1            72
-ast-stats-2 WherePredicate            72 ( 0.9%)             1            72
-ast-stats-2 - BoundPredicate            72 ( 0.9%)             1
-ast-stats-2 Arm                       96 ( 1.2%)             2            48
-ast-stats-2 ForeignItem               96 ( 1.2%)             1            96
-ast-stats-2 - Fn                        96 ( 1.2%)             1
-ast-stats-2 InlineAsm                120 ( 1.5%)             1           120
-ast-stats-2 Attribute                128 ( 1.6%)             4            32
+ast-stats-2 GenericArgs               40 ( 0.6%)             1            40
+ast-stats-2 - AngleBracketed            40 ( 0.6%)             1
+ast-stats-2 Crate                     40 ( 0.6%)             1            40
+ast-stats-2 ExprField                 48 ( 0.7%)             1            48
+ast-stats-2 WherePredicate            56 ( 0.8%)             1            56
+ast-stats-2 - BoundPredicate            56 ( 0.8%)             1
+ast-stats-2 Local                     72 ( 1.0%)             1            72
+ast-stats-2 Arm                       96 ( 1.3%)             2            48
+ast-stats-2 ForeignItem               96 ( 1.3%)             1            96
+ast-stats-2 - Fn                        96 ( 1.3%)             1
+ast-stats-2 InlineAsm                120 ( 1.7%)             1           120
+ast-stats-2 FnDecl                   120 ( 1.7%)             5            24
+ast-stats-2 Attribute                128 ( 1.8%)             4            32
 ast-stats-2 - DocComment                32 ( 0.4%)             1
-ast-stats-2 - Normal                    96 ( 1.2%)             3
-ast-stats-2 FieldDef                 160 ( 2.0%)             2            80
-ast-stats-2 Stmt                     160 ( 2.0%)             5            32
+ast-stats-2 - Normal                    96 ( 1.3%)             3
+ast-stats-2 FieldDef                 160 ( 2.2%)             2            80
+ast-stats-2 Stmt                     160 ( 2.2%)             5            32
 ast-stats-2 - Local                     32 ( 0.4%)             1
 ast-stats-2 - Semi                      32 ( 0.4%)             1
-ast-stats-2 - Expr                      96 ( 1.2%)             3
-ast-stats-2 Param                    160 ( 2.0%)             4            40
-ast-stats-2 FnDecl                   200 ( 2.5%)             5            40
-ast-stats-2 Variant                  240 ( 3.0%)             2           120
-ast-stats-2 GenericBound             288 ( 3.6%)             4            72
-ast-stats-2 - Trait                    288 ( 3.6%)             4
-ast-stats-2 Block                    288 ( 3.6%)             6            48
-ast-stats-2 AssocItem                416 ( 5.1%)             4           104
-ast-stats-2 - Type                     208 ( 2.6%)             2
-ast-stats-2 - Fn                       208 ( 2.6%)             2
-ast-stats-2 GenericParam             480 ( 5.9%)             5            96
-ast-stats-2 Pat                      616 ( 7.6%)             7            88
-ast-stats-2 - Struct                    88 ( 1.1%)             1
-ast-stats-2 - Wild                      88 ( 1.1%)             1
-ast-stats-2 - Ident                    440 ( 5.4%)             5
-ast-stats-2 Expr                     648 ( 8.0%)             9            72
-ast-stats-2 - Path                      72 ( 0.9%)             1
-ast-stats-2 - Match                     72 ( 0.9%)             1
-ast-stats-2 - Struct                    72 ( 0.9%)             1
-ast-stats-2 - InlineAsm                 72 ( 0.9%)             1
-ast-stats-2 - Lit                      144 ( 1.8%)             2
-ast-stats-2 - Block                    216 ( 2.7%)             3
-ast-stats-2 PathSegment              792 ( 9.8%)            33            24
-ast-stats-2 Ty                       896 (11.0%)            14            64
-ast-stats-2 - Ptr                       64 ( 0.8%)             1
-ast-stats-2 - Ref                       64 ( 0.8%)             1
-ast-stats-2 - ImplicitSelf             128 ( 1.6%)             2
-ast-stats-2 - Path                     640 ( 7.9%)            10
-ast-stats-2 Item                   2_024 (25.0%)            11           184
-ast-stats-2 - Trait                    184 ( 2.3%)             1
-ast-stats-2 - Enum                     184 ( 2.3%)             1
-ast-stats-2 - ExternCrate              184 ( 2.3%)             1
-ast-stats-2 - ForeignMod               184 ( 2.3%)             1
-ast-stats-2 - Impl                     184 ( 2.3%)             1
-ast-stats-2 - Fn                       368 ( 4.5%)             2
-ast-stats-2 - Use                      736 ( 9.1%)             4
+ast-stats-2 - Expr                      96 ( 1.3%)             3
+ast-stats-2 Param                    160 ( 2.2%)             4            40
+ast-stats-2 Block                    192 ( 2.7%)             6            32
+ast-stats-2 Variant                  208 ( 2.9%)             2           104
+ast-stats-2 GenericBound             224 ( 3.1%)             4            56
+ast-stats-2 - Trait                    224 ( 3.1%)             4
+ast-stats-2 AssocItem                416 ( 5.8%)             4           104
+ast-stats-2 - Type                     208 ( 2.9%)             2
+ast-stats-2 - Fn                       208 ( 2.9%)             2
+ast-stats-2 GenericParam             480 ( 6.7%)             5            96
+ast-stats-2 Pat                      504 ( 7.0%)             7            72
+ast-stats-2 - Struct                    72 ( 1.0%)             1
+ast-stats-2 - Wild                      72 ( 1.0%)             1
+ast-stats-2 - Ident                    360 ( 5.0%)             5
+ast-stats-2 Expr                     648 ( 9.1%)             9            72
+ast-stats-2 - Path                      72 ( 1.0%)             1
+ast-stats-2 - Match                     72 ( 1.0%)             1
+ast-stats-2 - Struct                    72 ( 1.0%)             1
+ast-stats-2 - InlineAsm                 72 ( 1.0%)             1
+ast-stats-2 - Lit                      144 ( 2.0%)             2
+ast-stats-2 - Block                    216 ( 3.0%)             3
+ast-stats-2 PathSegment              792 (11.1%)            33            24
+ast-stats-2 Ty                       896 (12.5%)            14            64
+ast-stats-2 - Ptr                       64 ( 0.9%)             1
+ast-stats-2 - Ref                       64 ( 0.9%)             1
+ast-stats-2 - ImplicitSelf             128 ( 1.8%)             2
+ast-stats-2 - Path                     640 ( 8.9%)            10
+ast-stats-2 Item                   1_496 (20.9%)            11           136
+ast-stats-2 - Trait                    136 ( 1.9%)             1
+ast-stats-2 - Enum                     136 ( 1.9%)             1
+ast-stats-2 - ExternCrate              136 ( 1.9%)             1
+ast-stats-2 - ForeignMod               136 ( 1.9%)             1
+ast-stats-2 - Impl                     136 ( 1.9%)             1
+ast-stats-2 - Fn                       272 ( 3.8%)             2
+ast-stats-2 - Use                      544 ( 7.6%)             4
 ast-stats-2 ----------------------------------------------------------------
-ast-stats-2 Total                  8_112
+ast-stats-2 Total                  7_152
 ast-stats-2
 hir-stats HIR STATS
 hir-stats Name                Accumulated Size         Count     Item Size
diff --git a/tests/ui/structs/struct-path-associated-type.rs b/tests/ui/structs/struct-path-associated-type.rs
index 2dd7174a9be..74d9705d4b8 100644
--- a/tests/ui/structs/struct-path-associated-type.rs
+++ b/tests/ui/structs/struct-path-associated-type.rs
@@ -13,7 +13,7 @@ fn f<T: Tr>() {
     //~^ ERROR expected struct, variant or union type, found associated type
     let z = T::A::<u8> {};
     //~^ ERROR expected struct, variant or union type, found associated type
-    //~| ERROR this associated type takes 0 generic arguments but 1 generic argument was supplied
+    //~| ERROR associated type takes 0 generic arguments but 1 generic argument was supplied
     match S {
         T::A {} => {}
         //~^ ERROR expected struct, variant or union type, found associated type
@@ -22,7 +22,7 @@ fn f<T: Tr>() {
 
 fn g<T: Tr<A = S>>() {
     let s = T::A {}; // OK
-    let z = T::A::<u8> {}; //~ ERROR this associated type takes 0 generic arguments but 1 generic argument was supplied
+    let z = T::A::<u8> {}; //~ ERROR associated type takes 0 generic arguments but 1 generic argument was supplied
     match S {
         T::A {} => {} // OK
     }
diff --git a/tests/ui/structs/struct-path-associated-type.stderr b/tests/ui/structs/struct-path-associated-type.stderr
index ca5f0b7e21e..acfddaf3760 100644
--- a/tests/ui/structs/struct-path-associated-type.stderr
+++ b/tests/ui/structs/struct-path-associated-type.stderr
@@ -4,7 +4,7 @@ error[E0071]: expected struct, variant or union type, found associated type
 LL |     let s = T::A {};
    |             ^^^^ not a struct
 
-error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/struct-path-associated-type.rs:14:16
    |
 LL |     let z = T::A::<u8> {};
@@ -30,7 +30,7 @@ error[E0071]: expected struct, variant or union type, found associated type
 LL |         T::A {} => {}
    |         ^^^^ not a struct
 
-error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/struct-path-associated-type.rs:25:16
    |
 LL |     let z = T::A::<u8> {};
diff --git a/tests/ui/structs/structure-constructor-type-mismatch.rs b/tests/ui/structs/structure-constructor-type-mismatch.rs
index a03ef590cb3..21cd9d08b21 100644
--- a/tests/ui/structs/structure-constructor-type-mismatch.rs
+++ b/tests/ui/structs/structure-constructor-type-mismatch.rs
@@ -45,13 +45,13 @@ fn main() {
         y: 8,
     };
 
-    let pt3 = PointF::<i32> { //~ ERROR this type alias takes 0 generic arguments but 1 generic argument
+    let pt3 = PointF::<i32> { //~ ERROR type alias takes 0 generic arguments but 1 generic argument
         x: 9,  //~ ERROR mismatched types
         y: 10, //~ ERROR mismatched types
     };
 
     match (Point { x: 1, y: 2 }) {
-        PointF::<u32> { .. } => {} //~ ERROR this type alias takes 0 generic arguments but 1 generic argument
+        PointF::<u32> { .. } => {} //~ ERROR type alias takes 0 generic arguments but 1 generic argument
         //~^ ERROR mismatched types
     }
 
diff --git a/tests/ui/structs/structure-constructor-type-mismatch.stderr b/tests/ui/structs/structure-constructor-type-mismatch.stderr
index 3e3f9ea06ef..63dda459396 100644
--- a/tests/ui/structs/structure-constructor-type-mismatch.stderr
+++ b/tests/ui/structs/structure-constructor-type-mismatch.stderr
@@ -52,7 +52,7 @@ LL |         x: 7,
    |            expected `f32`, found integer
    |            help: use a float literal: `7.0`
 
-error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/structure-constructor-type-mismatch.rs:48:15
    |
 LL |     let pt3 = PointF::<i32> {
@@ -84,7 +84,7 @@ LL |         y: 10,
    |            expected `f32`, found integer
    |            help: use a float literal: `10.0`
 
-error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/structure-constructor-type-mismatch.rs:54:9
    |
 LL |         PointF::<u32> { .. } => {}
diff --git a/tests/ui/suggestions/assoc-ct-for-assoc-method.stderr b/tests/ui/suggestions/assoc-ct-for-assoc-method.stderr
index afef38f1296..211cb1584ad 100644
--- a/tests/ui/suggestions/assoc-ct-for-assoc-method.stderr
+++ b/tests/ui/suggestions/assoc-ct-for-assoc-method.stderr
@@ -36,7 +36,7 @@ LL |     let y: i32 = i32::max - 42;
    |                  |
    |                  fn(i32, i32) -> i32 {<i32 as Ord>::max}
    |
-help: use parentheses to call this associated function
+help: use parentheses to call this method
    |
 LL |     let y: i32 = i32::max(/* i32 */, /* i32 */) - 42;
    |                          ++++++++++++++++++++++
diff --git a/tests/ui/suggestions/fn-or-tuple-struct-without-args.stderr b/tests/ui/suggestions/fn-or-tuple-struct-without-args.stderr
index 4f981a16374..a137db8cdee 100644
--- a/tests/ui/suggestions/fn-or-tuple-struct-without-args.stderr
+++ b/tests/ui/suggestions/fn-or-tuple-struct-without-args.stderr
@@ -206,7 +206,7 @@ error[E0308]: mismatched types
   --> $DIR/fn-or-tuple-struct-without-args.rs:41:20
    |
 LL |     fn ban(&self) -> usize { 42 }
-   |     ---------------------- associated function `ban` defined here
+   |     ---------------------- method `ban` defined here
 ...
 LL |     let _: usize = X::ban;
    |            -----   ^^^^^^ expected `usize`, found fn item
@@ -215,7 +215,7 @@ LL |     let _: usize = X::ban;
    |
    = note: expected type `usize`
            found fn item `for<'a> fn(&'a X) -> usize {<X as T>::ban}`
-help: use parentheses to call this associated function
+help: use parentheses to call this method
    |
 LL |     let _: usize = X::ban(/* &X */);
    |                          ++++++++++
@@ -224,7 +224,7 @@ error[E0308]: mismatched types
   --> $DIR/fn-or-tuple-struct-without-args.rs:42:20
    |
 LL |     fn bal(&self) -> usize;
-   |     ----------------------- associated function `bal` defined here
+   |     ----------------------- method `bal` defined here
 ...
 LL |     let _: usize = X::bal;
    |            -----   ^^^^^^ expected `usize`, found fn item
@@ -233,7 +233,7 @@ LL |     let _: usize = X::bal;
    |
    = note: expected type `usize`
            found fn item `for<'a> fn(&'a X) -> usize {<X as T>::bal}`
-help: use parentheses to call this associated function
+help: use parentheses to call this method
    |
 LL |     let _: usize = X::bal(/* &X */);
    |                          ++++++++++
diff --git a/tests/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr b/tests/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr
index 864ab053520..fc5a521746a 100644
--- a/tests/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr
+++ b/tests/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr
@@ -12,7 +12,7 @@ note: required by a bound in `foo`
   --> $DIR/imm-ref-trait-object-literal-bound-regions.rs:11:20
    |
 LL | fn foo<X>(_: X)
-   |    --- required by a bound in this
+   |    --- required by a bound in this function
 LL | where
 LL |     for<'b> &'b X: Trait,
    |                    ^^^^^ required by this bound in `foo`
diff --git a/tests/ui/suggestions/issue-101421.rs b/tests/ui/suggestions/issue-101421.rs
index b615997d1a9..1407ebd277c 100644
--- a/tests/ui/suggestions/issue-101421.rs
+++ b/tests/ui/suggestions/issue-101421.rs
@@ -8,5 +8,5 @@ impl Ice for () {
 
 fn main() {
     ().f::<()>(());
-    //~^ ERROR this associated function takes 0 generic arguments but 1 generic argument was supplied
+    //~^ ERROR method takes 0 generic arguments but 1 generic argument was supplied
 }
diff --git a/tests/ui/suggestions/issue-101421.stderr b/tests/ui/suggestions/issue-101421.stderr
index f8e1efb8820..2656ab3db0b 100644
--- a/tests/ui/suggestions/issue-101421.stderr
+++ b/tests/ui/suggestions/issue-101421.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-101421.rs:10:8
    |
 LL |     ().f::<()>(());
@@ -6,7 +6,7 @@ LL |     ().f::<()>(());
    |        |
    |        expected 0 generic arguments
    |
-note: associated function defined here, with 0 generic parameters
+note: method defined here, with 0 generic parameters
   --> $DIR/issue-101421.rs:2:8
    |
 LL |     fn f(&self, _: ());
diff --git a/tests/ui/suggestions/issue-104287.rs b/tests/ui/suggestions/issue-104287.rs
index e3fa22a8f66..37b3339fa92 100644
--- a/tests/ui/suggestions/issue-104287.rs
+++ b/tests/ui/suggestions/issue-104287.rs
@@ -8,6 +8,6 @@ impl S {
 fn main() {
     let x = S;
     foo::<()>(x);
-    //~^ ERROR this associated function takes 0 generic arguments but 1 generic argument was supplied
+    //~^ ERROR method takes 0 generic arguments but 1 generic argument was supplied
     //~| ERROR cannot find function `foo` in this scope
 }
diff --git a/tests/ui/suggestions/issue-104287.stderr b/tests/ui/suggestions/issue-104287.stderr
index 602a01828b2..ed59b2e7a2d 100644
--- a/tests/ui/suggestions/issue-104287.stderr
+++ b/tests/ui/suggestions/issue-104287.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-104287.rs:10:5
    |
 LL |     foo::<()>(x);
@@ -6,7 +6,7 @@ LL |     foo::<()>(x);
    |     |
    |     expected 0 generic arguments
    |
-note: associated function defined here, with 0 generic parameters
+note: method defined here, with 0 generic parameters
   --> $DIR/issue-104287.rs:6:8
    |
 LL |     fn foo(&self) {}
diff --git a/tests/ui/suggestions/issue-84973.stderr b/tests/ui/suggestions/issue-84973.stderr
index ae2bf5aac40..55c89884a5f 100644
--- a/tests/ui/suggestions/issue-84973.stderr
+++ b/tests/ui/suggestions/issue-84973.stderr
@@ -13,7 +13,7 @@ LL |     G: SomeTrait,
    |        ^^^^^^^^^ required by this bound in `Other::<'a, G>::new`
 LL | {
 LL |     pub fn new(g: G) -> Self {
-   |            --- required by a bound in this
+   |            --- required by a bound in this associated function
 help: consider borrowing here
    |
 LL |     let o = Other::new(&f);
diff --git a/tests/ui/suggestions/issue-85347.rs b/tests/ui/suggestions/issue-85347.rs
index 02b5fb61894..04d4c47d8e5 100644
--- a/tests/ui/suggestions/issue-85347.rs
+++ b/tests/ui/suggestions/issue-85347.rs
@@ -1,7 +1,7 @@
 use std::ops::Deref;
 trait Foo {
     type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
-    //~^ ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+    //~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
     //~| ERROR associated type bindings are not allowed here
     //~| HELP add missing
 }
diff --git a/tests/ui/suggestions/issue-85347.stderr b/tests/ui/suggestions/issue-85347.stderr
index 17c1b7dc4cc..f330b3c1fad 100644
--- a/tests/ui/suggestions/issue-85347.stderr
+++ b/tests/ui/suggestions/issue-85347.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
   --> $DIR/issue-85347.rs:3:42
    |
 LL |     type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
diff --git a/tests/ui/suggestions/issue-89064.stderr b/tests/ui/suggestions/issue-89064.stderr
index 93d8da226c8..be09dd89512 100644
--- a/tests/ui/suggestions/issue-89064.stderr
+++ b/tests/ui/suggestions/issue-89064.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: associated function takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-89064.rs:17:16
    |
 LL |     let _ = A::foo::<S>();
@@ -20,7 +20,7 @@ LL -     let _ = A::foo::<S>();
 LL +     let _ = A::foo();
    |
 
-error[E0107]: this associated function takes 0 generic arguments but 2 generic arguments were supplied
+error[E0107]: associated function takes 0 generic arguments but 2 generic arguments were supplied
   --> $DIR/issue-89064.rs:22:16
    |
 LL |     let _ = B::bar::<S, S>();
@@ -42,7 +42,7 @@ LL -     let _ = B::bar::<S, S>();
 LL +     let _ = B::bar();
    |
 
-error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: associated function takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-89064.rs:27:21
    |
 LL |     let _ = A::<S>::foo::<S>();
@@ -56,7 +56,7 @@ note: associated function defined here, with 0 generic parameters
 LL |     fn foo() {}
    |        ^^^
 
-error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-89064.rs:31:16
    |
 LL |     let _ = 42.into::<Option<_>>();
diff --git a/tests/ui/suggestions/missing-lifetime-specifier.rs b/tests/ui/suggestions/missing-lifetime-specifier.rs
index 24f5f782f35..cb734e8ba85 100644
--- a/tests/ui/suggestions/missing-lifetime-specifier.rs
+++ b/tests/ui/suggestions/missing-lifetime-specifier.rs
@@ -37,19 +37,19 @@ thread_local! {
 
 thread_local! {
     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
-    //~^ ERROR this union takes 2 lifetime arguments but 1 lifetime argument
-    //~| ERROR this union takes 2 lifetime arguments but 1 lifetime argument was supplied
-    //~| ERROR this union takes 2 lifetime arguments but 1 lifetime argument was supplied
-    //~| ERROR this union takes 2 lifetime arguments but 1 lifetime argument was supplied
-    //~| ERROR this union takes 2 lifetime arguments but 1 lifetime argument was supplied
+    //~^ ERROR union takes 2 lifetime arguments but 1 lifetime argument
+    //~| ERROR union takes 2 lifetime arguments but 1 lifetime argument was supplied
+    //~| ERROR union takes 2 lifetime arguments but 1 lifetime argument was supplied
+    //~| ERROR union takes 2 lifetime arguments but 1 lifetime argument was supplied
+    //~| ERROR union takes 2 lifetime arguments but 1 lifetime argument was supplied
 }
 thread_local! {
     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
-    //~^ ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
-    //~| ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
-    //~| ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
-    //~| ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
-    //~| ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+    //~^ ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+    //~| ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+    //~| ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+    //~| ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+    //~| ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied
     //~| ERROR missing lifetime
     //~| ERROR missing lifetime
 }
diff --git a/tests/ui/suggestions/missing-lifetime-specifier.stderr b/tests/ui/suggestions/missing-lifetime-specifier.stderr
index 997bbb5e9b5..21d2378382c 100644
--- a/tests/ui/suggestions/missing-lifetime-specifier.stderr
+++ b/tests/ui/suggestions/missing-lifetime-specifier.stderr
@@ -133,7 +133,7 @@ LL | | }
    |
    = help: this function's return type contains a borrowed value, but the signature does not say which one of `init`'s 3 lifetimes it is borrowed from
 
-error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: union takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:39:44
    |
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
@@ -151,7 +151,7 @@ help: add missing lifetime argument
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                                       +++++++++
 
-error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: union takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:39:44
    |
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
@@ -169,7 +169,7 @@ help: add missing lifetime argument
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                                       +++++++++
 
-error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: union takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:39:44
    |
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
@@ -187,7 +187,7 @@ help: add missing lifetime argument
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                                       +++++++++
 
-error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: union takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:39:44
    |
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
@@ -205,7 +205,7 @@ help: add missing lifetime argument
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                                       +++++++++
 
-error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: union takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:39:44
    |
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
@@ -223,7 +223,7 @@ help: add missing lifetime argument
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                                       +++++++++
 
-error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:47:45
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
@@ -241,7 +241,7 @@ help: add missing lifetime argument
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                                        +++++++++
 
-error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:47:45
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
@@ -259,7 +259,7 @@ help: add missing lifetime argument
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                                        +++++++++
 
-error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:47:45
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
@@ -277,7 +277,7 @@ help: add missing lifetime argument
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                                        +++++++++
 
-error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:47:45
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
@@ -295,7 +295,7 @@ help: add missing lifetime argument
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                                        +++++++++
 
-error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:47:45
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
diff --git a/tests/ui/suggestions/missing-type-param-used-in-param.stderr b/tests/ui/suggestions/missing-type-param-used-in-param.stderr
index 4f7058a6492..3116c5a0a1c 100644
--- a/tests/ui/suggestions/missing-type-param-used-in-param.stderr
+++ b/tests/ui/suggestions/missing-type-param-used-in-param.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: function takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/missing-type-param-used-in-param.rs:6:5
    |
 LL |     two_type_params::<String>(100);
diff --git a/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.rs b/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.rs
index 2f540060a34..4066cd3b11a 100644
--- a/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.rs
+++ b/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.rs
@@ -12,7 +12,7 @@ impl Foo<i32> for i32 {
 
 fn main() {
     1.bar::<i32>(0);
-    //~^ ERROR this associated function takes 0 generic arguments but 1 generic argument was supplied
+    //~^ ERROR method takes 0 generic arguments but 1 generic argument was supplied
     //~| HELP consider moving this generic argument to the `Foo` trait, which takes up to 1 argument
     //~| HELP remove these generics
 }
diff --git a/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr b/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr
index 9557220f6bb..bfdb35947ef 100644
--- a/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr
+++ b/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr
@@ -1,10 +1,10 @@
-error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/move-generic-to-trait-in-method-with-params.rs:14:7
    |
 LL |     1.bar::<i32>(0);
    |       ^^^ expected 0 generic arguments
    |
-note: associated function defined here, with 0 generic parameters
+note: method defined here, with 0 generic parameters
   --> $DIR/move-generic-to-trait-in-method-with-params.rs:4:8
    |
 LL |     fn bar(&self, _: T);
diff --git a/tests/ui/suggestions/sugg-else-for-closure.stderr b/tests/ui/suggestions/sugg-else-for-closure.stderr
index 7f05832bcd7..09553b93c45 100644
--- a/tests/ui/suggestions/sugg-else-for-closure.stderr
+++ b/tests/ui/suggestions/sugg-else-for-closure.stderr
@@ -15,7 +15,7 @@ LL |     let _s = y.unwrap_or(|| x.split('.').nth(1).unwrap());
    |              ^^^^^^^^^^^^-------------------------------^
    |                          |
    |                          this argument influences the return type of `unwrap_or`
-note: associated function defined here
+note: method defined here
   --> $SRC_DIR/core/src/option.rs:LL:COL
 help: try calling `unwrap_or_else` instead
    |
diff --git a/tests/ui/suggestions/trait-with-missing-associated-type-restriction.stderr b/tests/ui/suggestions/trait-with-missing-associated-type-restriction.stderr
index f520d88c6ba..7deb9a4342d 100644
--- a/tests/ui/suggestions/trait-with-missing-associated-type-restriction.stderr
+++ b/tests/ui/suggestions/trait-with-missing-associated-type-restriction.stderr
@@ -90,7 +90,7 @@ LL |     fn func(&self) -> Self::A;
 LL |     fn funk(&self, _: Self::A);
 LL |     fn funq(&self) -> Self::A {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ consider calling `Trait::funq`
-note: associated function defined here
+note: method defined here
   --> $DIR/trait-with-missing-associated-type-restriction.rs:9:8
    |
 LL |     fn funk(&self, _: Self::A);
diff --git a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr
index fcff02e09db..4e3180e84d2 100644
--- a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr
+++ b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr
@@ -18,7 +18,7 @@ LL |     let _: Vec<A:B> = A::B;
    = note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
    = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
 
-error[E0107]: this struct takes at least 1 generic argument but 0 generic arguments were supplied
+error[E0107]: struct takes at least 1 generic argument but 0 generic arguments were supplied
   --> $DIR/type-ascription-instead-of-path-in-type.rs:6:12
    |
 LL |     let _: Vec<A:B> = A::B;
diff --git a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs
index 8b6e8cfd720..ed262fd39a5 100644
--- a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs
+++ b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs
@@ -6,7 +6,7 @@ pub trait T<X, Y> {
 pub struct Foo {
     i: Box<dyn T<usize, usize, usize, usize, B=usize>>,
     //~^ ERROR must be specified
-    //~| ERROR this trait takes 2 generic arguments but 4 generic arguments were supplied
+    //~| ERROR trait takes 2 generic arguments but 4 generic arguments were supplied
 }
 
 
diff --git a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr
index 75b91923284..175a5fbba61 100644
--- a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr
+++ b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this trait takes 2 generic arguments but 4 generic arguments were supplied
+error[E0107]: trait takes 2 generic arguments but 4 generic arguments were supplied
   --> $DIR/use-type-argument-instead-of-assoc-type.rs:7:16
    |
 LL |     i: Box<dyn T<usize, usize, usize, usize, B=usize>>,
diff --git a/tests/ui/tool-attributes/auxiliary/p1.rs b/tests/ui/tool-attributes/auxiliary/p1.rs
new file mode 100644
index 00000000000..47195c7e9d6
--- /dev/null
+++ b/tests/ui/tool-attributes/auxiliary/p1.rs
@@ -0,0 +1,3 @@
+#![feature(rustc_attrs)]
+#[rustc_diagnostic_item = "Foo"]
+pub struct Foo {}
diff --git a/tests/ui/tool-attributes/auxiliary/p2.rs b/tests/ui/tool-attributes/auxiliary/p2.rs
new file mode 100644
index 00000000000..47195c7e9d6
--- /dev/null
+++ b/tests/ui/tool-attributes/auxiliary/p2.rs
@@ -0,0 +1,3 @@
+#![feature(rustc_attrs)]
+#[rustc_diagnostic_item = "Foo"]
+pub struct Foo {}
diff --git a/tests/ui/tool-attributes/duplicate-diagnostic.rs b/tests/ui/tool-attributes/duplicate-diagnostic.rs
new file mode 100644
index 00000000000..39c2ca1cb86
--- /dev/null
+++ b/tests/ui/tool-attributes/duplicate-diagnostic.rs
@@ -0,0 +1,13 @@
+// aux-build: p1.rs
+// aux-build: p2.rs
+
+// error-pattern: duplicate diagnostic item in crate `p2`
+// error-pattern: note: the diagnostic item is first defined in crate `p1`
+
+#![feature(rustc_attrs)]
+extern crate p1;
+extern crate p2;
+
+#[rustc_diagnostic_item = "Foo"]
+pub struct Foo {} //~ ERROR duplicate diagnostic item found
+fn main() {}
diff --git a/tests/ui/tool-attributes/duplicate-diagnostic.stderr b/tests/ui/tool-attributes/duplicate-diagnostic.stderr
new file mode 100644
index 00000000000..e315fdc7d84
--- /dev/null
+++ b/tests/ui/tool-attributes/duplicate-diagnostic.stderr
@@ -0,0 +1,12 @@
+error: duplicate diagnostic item in crate `p2`: `Foo`.
+   |
+   = note: the diagnostic item is first defined in crate `p1`.
+
+error: duplicate diagnostic item found: `Foo`.
+  --> $DIR/duplicate-diagnostic.rs:12:1
+   |
+LL | pub struct Foo {}
+   | ^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/traits/alias/ambiguous.stderr b/tests/ui/traits/alias/ambiguous.stderr
index 0fe1a79678d..203bdc526f6 100644
--- a/tests/ui/traits/alias/ambiguous.stderr
+++ b/tests/ui/traits/alias/ambiguous.stderr
@@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `B` for the type `u8`
    |
 LL |         fn foo(&self) {}
    |         ^^^^^^^^^^^^^
-help: disambiguate the associated function for candidate #1
+help: disambiguate the method for candidate #1
    |
 LL |     A::foo(&t);
    |     ~~~~~~~~~~
-help: disambiguate the associated function for candidate #2
+help: disambiguate the method for candidate #2
    |
 LL |     B::foo(&t);
    |     ~~~~~~~~~~
diff --git a/tests/ui/traits/inductive-overflow/supertrait-auto-trait.stderr b/tests/ui/traits/inductive-overflow/supertrait-auto-trait.stderr
index 3ec288d1382..dc967d51298 100644
--- a/tests/ui/traits/inductive-overflow/supertrait-auto-trait.stderr
+++ b/tests/ui/traits/inductive-overflow/supertrait-auto-trait.stderr
@@ -4,7 +4,7 @@ error[E0568]: auto traits cannot have super traits or lifetime bounds
 LL | auto trait Magic: Copy {}
    |            -----^^^^^^ help: remove the super traits or lifetime bounds
    |            |
-   |            auto trait cannot have super traits or lifetime bounds
+   |            auto traits cannot have super traits or lifetime bounds
 
 error[E0277]: the trait bound `NoClone: Copy` is not satisfied
   --> $DIR/supertrait-auto-trait.rs:16:23
diff --git a/tests/ui/traits/issue-52893.stderr b/tests/ui/traits/issue-52893.stderr
index 006cb3a7b72..db807a38830 100644
--- a/tests/ui/traits/issue-52893.stderr
+++ b/tests/ui/traits/issue-52893.stderr
@@ -18,7 +18,7 @@ LL |         builder.push(output);
    |         ^^^^^^^^^^^^^------^
    |                      |
    |                      this argument influences the return type of `push`
-note: associated function defined here
+note: method defined here
   --> $DIR/issue-52893.rs:11:8
    |
 LL |     fn push(self, other: T) -> Self::PushRes;
diff --git a/tests/ui/traits/issue-77982.stderr b/tests/ui/traits/issue-77982.stderr
index 0b57a8212bd..a397b0accc8 100644
--- a/tests/ui/traits/issue-77982.stderr
+++ b/tests/ui/traits/issue-77982.stderr
@@ -4,7 +4,7 @@ error[E0283]: type annotations needed
 LL |     opts.get(opt.as_ref());
    |          ^^^ ------------ type must be known at this point
    |          |
-   |          cannot infer type of the type parameter `Q` declared on the associated function `get`
+   |          cannot infer type of the type parameter `Q` declared on the method `get`
    |
    = note: multiple `impl`s satisfying `String: Borrow<_>` found in the following crates: `alloc`, `core`:
            - impl Borrow<str> for String;
@@ -23,7 +23,7 @@ error[E0283]: type annotations needed
 LL |     opts.get(opt.as_ref());
    |          ^^^     ------ type must be known at this point
    |          |
-   |          cannot infer type of the type parameter `Q` declared on the associated function `get`
+   |          cannot infer type of the type parameter `Q` declared on the method `get`
    |
    = note: multiple `impl`s satisfying `String: AsRef<_>` found in the following crates: `alloc`, `std`:
            - impl AsRef<OsStr> for String;
diff --git a/tests/ui/traits/item-privacy.rs b/tests/ui/traits/item-privacy.rs
index 38d06b967bc..a3e1a22e7a8 100644
--- a/tests/ui/traits/item-privacy.rs
+++ b/tests/ui/traits/item-privacy.rs
@@ -69,7 +69,7 @@ fn check_method() {
     S.c(); // OK
     // a, b, c are resolved as inherent items, their traits don't need to be in scope
     let c = &S as &dyn C;
-    c.a(); //~ ERROR associated function `a` is private
+    c.a(); //~ ERROR method `a` is private
     c.b(); // OK
     c.c(); // OK
 
@@ -81,7 +81,7 @@ fn check_method() {
     //~^ ERROR no function or associated item named `b` found
     S::c(&S); // OK
     // a, b, c are resolved as inherent items, their traits don't need to be in scope
-    <dyn C>::a(&S); //~ ERROR associated function `a` is private
+    <dyn C>::a(&S); //~ ERROR method `a` is private
     <dyn C>::b(&S); // OK
     C::c(&S); // OK
 }
diff --git a/tests/ui/traits/item-privacy.stderr b/tests/ui/traits/item-privacy.stderr
index 293cfbda86c..04995b3a17b 100644
--- a/tests/ui/traits/item-privacy.stderr
+++ b/tests/ui/traits/item-privacy.stderr
@@ -32,14 +32,14 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f
 LL | use method::B;
    |
 
-error[E0624]: associated function `a` is private
+error[E0624]: method `a` is private
   --> $DIR/item-privacy.rs:72:7
    |
 LL |         fn a(&self) { }
-   |         ----------- private associated function defined here
+   |         ----------- private method defined here
 ...
 LL |     c.a();
-   |       ^ private associated function
+   |       ^ private method
 
 error[E0599]: no function or associated item named `a` found for struct `S` in the current scope
   --> $DIR/item-privacy.rs:78:8
@@ -72,14 +72,14 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f
 LL | use method::B;
    |
 
-error[E0624]: associated function `a` is private
+error[E0624]: method `a` is private
   --> $DIR/item-privacy.rs:84:14
    |
 LL |         fn a(&self) { }
-   |         ----------- private associated function defined here
+   |         ----------- private method defined here
 ...
 LL |     <dyn C>::a(&S);
-   |              ^ private associated function
+   |              ^ private method
 
 error[E0599]: no associated item named `A` found for struct `S` in the current scope
   --> $DIR/item-privacy.rs:97:8
diff --git a/tests/ui/traits/method-private.stderr b/tests/ui/traits/method-private.stderr
index 8e991ec018c..55656f21e00 100644
--- a/tests/ui/traits/method-private.stderr
+++ b/tests/ui/traits/method-private.stderr
@@ -1,11 +1,11 @@
-error[E0624]: associated function `method` is private
+error[E0624]: method `method` is private
   --> $DIR/method-private.rs:19:9
    |
 LL |         fn method(&self) {}
-   |         ---------------- private associated function defined here
+   |         ---------------- private method defined here
 ...
 LL |     foo.method();
-   |         ^^^^^^ private associated function
+   |         ^^^^^^ private method
    |
    = help: items from traits can only be used if the trait is in scope
 help: the following trait is implemented but not in scope; perhaps add a `use` for it:
diff --git a/tests/ui/traits/multidispatch-convert-ambig-dest.stderr b/tests/ui/traits/multidispatch-convert-ambig-dest.stderr
index 6e6172eea47..e927f26e96d 100644
--- a/tests/ui/traits/multidispatch-convert-ambig-dest.stderr
+++ b/tests/ui/traits/multidispatch-convert-ambig-dest.stderr
@@ -29,7 +29,7 @@ note: required by a bound in `test`
   --> $DIR/multidispatch-convert-ambig-dest.rs:21:11
    |
 LL | fn test<T,U>(_: T, _: U)
-   |    ---- required by a bound in this
+   |    ---- required by a bound in this function
 LL | where T : Convert<U>
    |           ^^^^^^^^^^ required by this bound in `test`
 help: consider specifying the generic arguments
diff --git a/tests/ui/traits/new-solver/higher-ranked-dyn-bounds.rs b/tests/ui/traits/new-solver/higher-ranked-dyn-bounds.rs
new file mode 100644
index 00000000000..c886aeeda3e
--- /dev/null
+++ b/tests/ui/traits/new-solver/higher-ranked-dyn-bounds.rs
@@ -0,0 +1,17 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+trait Trait<'a> {
+    type Item: for<'b> Trait2<'b>;
+}
+
+trait Trait2<'a> {}
+impl Trait2<'_> for () {}
+
+fn needs_trait(_: Box<impl for<'a> Trait<'a> + ?Sized>) {}
+
+fn foo(x: Box<dyn for<'a> Trait<'a, Item = ()>>) {
+    needs_trait(x);
+}
+
+fn main() {}
diff --git a/tests/ui/traits/new-solver/more-object-bound.rs b/tests/ui/traits/new-solver/more-object-bound.rs
new file mode 100644
index 00000000000..712759ef0e6
--- /dev/null
+++ b/tests/ui/traits/new-solver/more-object-bound.rs
@@ -0,0 +1,27 @@
+// compile-flags: -Ztrait-solver=next
+// From #80800
+
+trait SuperTrait {
+    type A;
+    type B;
+}
+
+trait Trait: SuperTrait<A = <Self as SuperTrait>::B> {}
+
+fn transmute<A, B>(x: A) -> B {
+    foo::<A, B, dyn Trait<A = A, B = B>>(x)
+    //~^ ERROR type annotations needed: cannot satisfy `dyn Trait<A = A, B = B>: Trait`
+}
+
+fn foo<A, B, T: ?Sized>(x: T::A) -> B
+where
+    T: Trait<B = B>,
+{
+    x
+}
+
+static X: u8 = 0;
+fn main() {
+    let x = transmute::<&u8, &[u8; 1_000_000]>(&X);
+    println!("{:?}", x[100_000]);
+}
diff --git a/tests/ui/traits/new-solver/more-object-bound.stderr b/tests/ui/traits/new-solver/more-object-bound.stderr
new file mode 100644
index 00000000000..208fdecb08f
--- /dev/null
+++ b/tests/ui/traits/new-solver/more-object-bound.stderr
@@ -0,0 +1,19 @@
+error[E0283]: type annotations needed: cannot satisfy `dyn Trait<A = A, B = B>: Trait`
+  --> $DIR/more-object-bound.rs:12:5
+   |
+LL |     foo::<A, B, dyn Trait<A = A, B = B>>(x)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: cannot satisfy `dyn Trait<A = A, B = B>: Trait`
+note: required by a bound in `foo`
+  --> $DIR/more-object-bound.rs:18:8
+   |
+LL | fn foo<A, B, T: ?Sized>(x: T::A) -> B
+   |    --- required by a bound in this function
+LL | where
+LL |     T: Trait<B = B>,
+   |        ^^^^^^^^^^^^ required by this bound in `foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/traits/new-solver/object-unsafety.rs b/tests/ui/traits/new-solver/object-unsafety.rs
new file mode 100644
index 00000000000..7bdd863a762
--- /dev/null
+++ b/tests/ui/traits/new-solver/object-unsafety.rs
@@ -0,0 +1,20 @@
+// compile-flags: -Ztrait-solver=next
+
+trait Setup {
+    type From: Copy;
+}
+
+fn copy<U: Setup + ?Sized>(from: &U::From) -> U::From {
+    *from
+}
+
+pub fn copy_any<T>(t: &T) -> T {
+    copy::<dyn Setup<From=T>>(t)
+    //~^ ERROR the trait bound `dyn Setup<From = T>: Setup` is not satisfied
+}
+
+fn main() {
+    let x = String::from("Hello, world");
+    let y = copy_any(&x);
+    println!("{y}");
+}
diff --git a/tests/ui/traits/new-solver/object-unsafety.stderr b/tests/ui/traits/new-solver/object-unsafety.stderr
new file mode 100644
index 00000000000..198ac623df8
--- /dev/null
+++ b/tests/ui/traits/new-solver/object-unsafety.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `dyn Setup<From = T>: Setup` is not satisfied
+  --> $DIR/object-unsafety.rs:12:12
+   |
+LL |     copy::<dyn Setup<From=T>>(t)
+   |            ^^^^^^^^^^^^^^^^^ the trait `Setup` is not implemented for `dyn Setup<From = T>`
+   |
+note: required by a bound in `copy`
+  --> $DIR/object-unsafety.rs:7:12
+   |
+LL | fn copy<U: Setup + ?Sized>(from: &U::From) -> U::From {
+   |            ^^^^^ required by this bound in `copy`
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+   |
+LL | pub fn copy_any<T>(t: &T) -> T where dyn Setup<From = T>: Setup {
+   |                                ++++++++++++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr
index 6480e490e8b..ed9b57cb1bd 100644
--- a/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr
+++ b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr
@@ -18,7 +18,7 @@ note: required by a bound in `foo`
   --> $DIR/bad-sized-cond.rs:6:15
    |
 LL | pub fn foo()
-   |        --- required by a bound in this
+   |        --- required by a bound in this function
 LL | where
 LL |     for<V> V: Sized,
    |               ^^^^^ required by this bound in `foo`
@@ -35,7 +35,7 @@ note: required by a bound in `bar`
   --> $DIR/bad-sized-cond.rs:12:15
    |
 LL | pub fn bar()
-   |        --- required by a bound in this
+   |        --- required by a bound in this function
 LL | where
 LL |     for<V> V: IntoIterator,
    |               ^^^^^^^^^^^^ required by this bound in `bar`
@@ -52,7 +52,7 @@ note: required by a bound in `bar`
   --> $DIR/bad-sized-cond.rs:12:15
    |
 LL | pub fn bar()
-   |        --- required by a bound in this
+   |        --- required by a bound in this function
 LL | where
 LL |     for<V> V: IntoIterator,
    |               ^^^^^^^^^^^^ required by this bound in `bar`
diff --git a/tests/ui/traits/non_lifetime_binders/fail.stderr b/tests/ui/traits/non_lifetime_binders/fail.stderr
index c3f4fd6a88e..7bd02550fb3 100644
--- a/tests/ui/traits/non_lifetime_binders/fail.stderr
+++ b/tests/ui/traits/non_lifetime_binders/fail.stderr
@@ -17,7 +17,7 @@ note: required by a bound in `fail`
   --> $DIR/fail.rs:10:15
    |
 LL | fn fail()
-   |    ---- required by a bound in this
+   |    ---- required by a bound in this function
 LL | where
 LL |     for<T> T: Trait,
    |               ^^^^^ required by this bound in `fail`
@@ -33,7 +33,7 @@ note: required by a bound in `auto_trait`
   --> $DIR/fail.rs:15:15
    |
 LL | fn auto_trait()
-   |    ---------- required by a bound in this
+   |    ---------- required by a bound in this function
 LL | where
 LL |     for<T> T: Send,
    |               ^^^^ required by this bound in `auto_trait`
diff --git a/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.rs b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.rs
new file mode 100644
index 00000000000..5ff7089b993
--- /dev/null
+++ b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.rs
@@ -0,0 +1,14 @@
+// edition:2021
+// check-pass
+
+// Checks that test_type_match code doesn't ICE when predicates have late-bound types
+
+#![feature(non_lifetime_binders)]
+//~^ WARN is incomplete and may not be safe to use
+
+async fn walk2<'a, T: 'a>(_: T)
+where
+    for<F> F: 'a,
+{}
+
+fn main() {}
diff --git a/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr
new file mode 100644
index 00000000000..3609bed28df
--- /dev/null
+++ b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr
@@ -0,0 +1,11 @@
+warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/type-match-with-late-bound.rs:6:12
+   |
+LL | #![feature(non_lifetime_binders)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/traits/object/enforce-supertrait-projection.stderr b/tests/ui/traits/object/enforce-supertrait-projection.stderr
index cbf09386654..848b4e69a4b 100644
--- a/tests/ui/traits/object/enforce-supertrait-projection.stderr
+++ b/tests/ui/traits/object/enforce-supertrait-projection.stderr
@@ -16,7 +16,7 @@ note: required by a bound in `foo`
   --> $DIR/enforce-supertrait-projection.rs:15:8
    |
 LL | fn foo<A, B, T: ?Sized>(x: T::A) -> B
-   |    --- required by a bound in this
+   |    --- required by a bound in this function
 LL | where
 LL |     T: Trait<B = B>,
    |        ^^^^^^^^^^^^ required by this bound in `foo`
diff --git a/tests/ui/traits/object/vs-lifetime.rs b/tests/ui/traits/object/vs-lifetime.rs
index 14ae67cffd7..d3e6c0b217c 100644
--- a/tests/ui/traits/object/vs-lifetime.rs
+++ b/tests/ui/traits/object/vs-lifetime.rs
@@ -9,8 +9,8 @@ fn main() {
     let _: S<'static, dyn 'static +>;
     //~^ at least one trait is required for an object type
     let _: S<'static, 'static>;
-    //~^ ERROR this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
-    //~| ERROR this struct takes 1 generic argument but 0 generic arguments were supplied
+    //~^ ERROR struct takes 1 lifetime argument but 2 lifetime arguments were supplied
+    //~| ERROR struct takes 1 generic argument but 0 generic arguments were supplied
     let _: S<dyn 'static +, 'static>;
     //~^ ERROR type provided when a lifetime was expected
     //~| ERROR at least one trait is required for an object type
diff --git a/tests/ui/traits/object/vs-lifetime.stderr b/tests/ui/traits/object/vs-lifetime.stderr
index 22446522852..a69cd140807 100644
--- a/tests/ui/traits/object/vs-lifetime.stderr
+++ b/tests/ui/traits/object/vs-lifetime.stderr
@@ -4,7 +4,7 @@ error[E0224]: at least one trait is required for an object type
 LL |     let _: S<'static, dyn 'static +>;
    |                       ^^^^^^^^^^^^^
 
-error[E0107]: this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/vs-lifetime.rs:11:12
    |
 LL |     let _: S<'static, 'static>;
@@ -18,7 +18,7 @@ note: struct defined here, with 1 lifetime parameter: `'a`
 LL | struct S<'a, T>(&'a u8, T);
    |        ^ --
 
-error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/vs-lifetime.rs:11:12
    |
 LL |     let _: S<'static, 'static>;
diff --git a/tests/ui/traits/test-2.rs b/tests/ui/traits/test-2.rs
index 342928e882a..ffb778a0141 100644
--- a/tests/ui/traits/test-2.rs
+++ b/tests/ui/traits/test-2.rs
@@ -7,9 +7,9 @@ impl bar for u32 { fn dup(&self) -> u32 { *self } fn blah<X>(&self) {} }
 
 fn main() {
     10.dup::<i32>();
-    //~^ ERROR this associated function takes 0 generic arguments but 1
+    //~^ ERROR method takes 0 generic arguments but 1
     10.blah::<i32, i32>();
-    //~^ ERROR this associated function takes 1 generic argument but 2
+    //~^ ERROR method takes 1 generic argument but 2
     (Box::new(10) as Box<dyn bar>).dup();
     //~^ ERROR E0038
     //~| ERROR E0038
diff --git a/tests/ui/traits/test-2.stderr b/tests/ui/traits/test-2.stderr
index eaa20b0b4f4..6c0e8b8af4b 100644
--- a/tests/ui/traits/test-2.stderr
+++ b/tests/ui/traits/test-2.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/test-2.rs:9:8
    |
 LL |     10.dup::<i32>();
@@ -6,13 +6,13 @@ LL |     10.dup::<i32>();
    |        |
    |        expected 0 generic arguments
    |
-note: associated function defined here, with 0 generic parameters
+note: method defined here, with 0 generic parameters
   --> $DIR/test-2.rs:4:16
    |
 LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
    |                ^^^
 
-error[E0107]: this associated function takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: method takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/test-2.rs:11:8
    |
 LL |     10.blah::<i32, i32>();
@@ -20,7 +20,7 @@ LL |     10.blah::<i32, i32>();
    |        |
    |        expected 1 generic argument
    |
-note: associated function defined here, with 1 generic parameter: `X`
+note: method defined here, with 1 generic parameter: `X`
   --> $DIR/test-2.rs:4:39
    |
 LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
diff --git a/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr b/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr
index 96a2fdc54db..164e88ede20 100644
--- a/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr
+++ b/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -31,7 +31,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -53,7 +53,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -75,7 +75,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -97,7 +97,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -119,7 +119,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
diff --git a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr
index 4da5fcea337..0f0f77f1683 100644
--- a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr
+++ b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -32,7 +32,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -55,7 +55,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -78,7 +78,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -101,7 +101,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -124,7 +124,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -147,7 +147,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -170,7 +170,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -193,7 +193,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -216,7 +216,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -239,7 +239,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -262,7 +262,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -285,7 +285,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -308,7 +308,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -331,7 +331,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -354,7 +354,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -377,7 +377,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -400,7 +400,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -423,7 +423,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -446,7 +446,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
diff --git a/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr
index 510b8c56e5a..d456a746f5e 100644
--- a/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr
+++ b/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:14:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -32,7 +32,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:14:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -55,7 +55,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:14:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -78,7 +78,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:14:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -101,7 +101,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:14:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -124,7 +124,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:14:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
diff --git a/tests/ui/transmutability/enums/should_pad_variants.stderr b/tests/ui/transmutability/enums/should_pad_variants.stderr
index a823503d594..f4988239df9 100644
--- a/tests/ui/transmutability/enums/should_pad_variants.stderr
+++ b/tests/ui/transmutability/enums/should_pad_variants.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/should_pad_variants.rs:13:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
diff --git a/tests/ui/transmutability/enums/should_respect_endianness.stderr b/tests/ui/transmutability/enums/should_respect_endianness.stderr
index 0845a5edf32..350583b0b85 100644
--- a/tests/ui/transmutability/enums/should_respect_endianness.stderr
+++ b/tests/ui/transmutability/enums/should_respect_endianness.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/should_respect_endianness.rs:14:14
    |
 LL |       pub fn is_transmutable<Src, Dst>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
diff --git a/tests/ui/transmutability/issue-101739-2.rs b/tests/ui/transmutability/issue-101739-2.rs
index 964a7e49ee6..e5a56ccc9e0 100644
--- a/tests/ui/transmutability/issue-101739-2.rs
+++ b/tests/ui/transmutability/issue-101739-2.rs
@@ -15,7 +15,7 @@ mod assert {
         const ASSUME_VISIBILITY: bool,
     >()
     where
-        Dst: BikeshedIntrinsicFrom< //~ ERROR this trait takes at most 3 generic arguments but 6 generic arguments were supplied
+        Dst: BikeshedIntrinsicFrom< //~ ERROR trait takes at most 3 generic arguments but 6 generic arguments were supplied
             Src,
             Context,
             ASSUME_ALIGNMENT,
diff --git a/tests/ui/transmutability/issue-101739-2.stderr b/tests/ui/transmutability/issue-101739-2.stderr
index 1b3d202590d..420a9f33008 100644
--- a/tests/ui/transmutability/issue-101739-2.stderr
+++ b/tests/ui/transmutability/issue-101739-2.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this trait takes at most 3 generic arguments but 6 generic arguments were supplied
+error[E0107]: trait takes at most 3 generic arguments but 6 generic arguments were supplied
   --> $DIR/issue-101739-2.rs:18:14
    |
 LL |           Dst: BikeshedIntrinsicFrom<
diff --git a/tests/ui/transmutability/primitives/bool.stderr b/tests/ui/transmutability/primitives/bool.stderr
index 214b5e150ed..22decf15e54 100644
--- a/tests/ui/transmutability/primitives/bool.stderr
+++ b/tests/ui/transmutability/primitives/bool.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/bool.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
diff --git a/tests/ui/transmutability/primitives/numbers.stderr b/tests/ui/transmutability/primitives/numbers.stderr
index 7cb7ca8e6db..c04a0e82aa2 100644
--- a/tests/ui/transmutability/primitives/numbers.stderr
+++ b/tests/ui/transmutability/primitives/numbers.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -25,7 +25,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -41,7 +41,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -57,7 +57,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -73,7 +73,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -89,7 +89,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -105,7 +105,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -121,7 +121,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -137,7 +137,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -153,7 +153,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -169,7 +169,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -185,7 +185,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -201,7 +201,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -217,7 +217,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -233,7 +233,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -249,7 +249,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -265,7 +265,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -281,7 +281,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -297,7 +297,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -313,7 +313,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -329,7 +329,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -345,7 +345,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -361,7 +361,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -377,7 +377,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -393,7 +393,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -409,7 +409,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -425,7 +425,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -441,7 +441,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -457,7 +457,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -473,7 +473,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -489,7 +489,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -505,7 +505,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -521,7 +521,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -537,7 +537,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -553,7 +553,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -569,7 +569,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -585,7 +585,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -601,7 +601,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -617,7 +617,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -633,7 +633,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -649,7 +649,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -665,7 +665,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -681,7 +681,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -697,7 +697,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -713,7 +713,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -729,7 +729,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -745,7 +745,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -761,7 +761,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -777,7 +777,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -793,7 +793,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -809,7 +809,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -825,7 +825,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -841,7 +841,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -857,7 +857,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -873,7 +873,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -889,7 +889,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -905,7 +905,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/numbers.rs:12:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
diff --git a/tests/ui/transmutability/primitives/unit.stderr b/tests/ui/transmutability/primitives/unit.stderr
index 8cabe44a053..988cd33b3bf 100644
--- a/tests/ui/transmutability/primitives/unit.stderr
+++ b/tests/ui/transmutability/primitives/unit.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/unit.rs:12:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
diff --git a/tests/ui/transmutability/references.stderr b/tests/ui/transmutability/references.stderr
index e9c7b144a82..eb3bd03fd31 100644
--- a/tests/ui/transmutability/references.stderr
+++ b/tests/ui/transmutability/references.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/references.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
diff --git a/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr
index 621dbee849f..d9aebac6417 100644
--- a/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr
+++ b/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -32,7 +32,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -55,7 +55,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -78,7 +78,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -101,7 +101,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -124,7 +124,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -147,7 +147,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -170,7 +170,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -193,7 +193,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -216,7 +216,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -239,7 +239,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -262,7 +262,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
diff --git a/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr
index 523bde85adf..aa0cbc51b1b 100644
--- a/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr
+++ b/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
@@ -32,7 +32,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:13:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
diff --git a/tests/ui/transmutability/unions/should_pad_variants.stderr b/tests/ui/transmutability/unions/should_pad_variants.stderr
index a823503d594..f4988239df9 100644
--- a/tests/ui/transmutability/unions/should_pad_variants.stderr
+++ b/tests/ui/transmutability/unions/should_pad_variants.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/should_pad_variants.rs:13:14
    |
 LL |       pub fn is_transmutable<Src, Dst, Context>()
-   |              --------------- required by a bound in this
+   |              --------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
diff --git a/tests/ui/transmutability/unions/should_reject_contraction.stderr b/tests/ui/transmutability/unions/should_reject_contraction.stderr
index 41f0cedc3a3..fa7dcc3d22a 100644
--- a/tests/ui/transmutability/unions/should_reject_contraction.stderr
+++ b/tests/ui/transmutability/unions/should_reject_contraction.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/should_reject_contraction.rs:13:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
diff --git a/tests/ui/transmutability/unions/should_reject_disjoint.stderr b/tests/ui/transmutability/unions/should_reject_disjoint.stderr
index 4323f974066..880e4cd8940 100644
--- a/tests/ui/transmutability/unions/should_reject_disjoint.stderr
+++ b/tests/ui/transmutability/unions/should_reject_disjoint.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_reject_disjoint.rs:13:14
    |
 LL |     pub fn is_maybe_transmutable<Src, Dst>()
-   |            --------------------- required by a bound in this
+   |            --------------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY.and(Assume::VALIDITY) }>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
@@ -25,7 +25,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_reject_disjoint.rs:13:14
    |
 LL |     pub fn is_maybe_transmutable<Src, Dst>()
-   |            --------------------- required by a bound in this
+   |            --------------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY.and(Assume::VALIDITY) }>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
diff --git a/tests/ui/transmutability/unions/should_reject_intersecting.stderr b/tests/ui/transmutability/unions/should_reject_intersecting.stderr
index e009888ae8d..501760b0809 100644
--- a/tests/ui/transmutability/unions/should_reject_intersecting.stderr
+++ b/tests/ui/transmutability/unions/should_reject_intersecting.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/should_reject_intersecting.rs:14:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
@@ -25,7 +25,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/should_reject_intersecting.rs:14:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }>
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
diff --git a/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr b/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr
index d5d6d431b6f..afbba653b83 100644
--- a/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr
+++ b/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/should_reject_if_dst_has_private_field.rs:13:14
    |
 LL |     pub fn is_transmutable<Src, Dst, Context>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
diff --git a/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr b/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr
index a1ca2ced53f..f14b5d8b2cb 100644
--- a/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr
+++ b/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/should_reject_if_dst_has_private_variant.rs:13:14
    |
 LL |     pub fn is_transmutable<Src, Dst, Context>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
diff --git a/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr b/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr
index 4e648664d5a..01ae8bea256 100644
--- a/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr
+++ b/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/should_reject_if_dst_has_unreachable_field.rs:15:14
    |
 LL |     pub fn is_transmutable<Src, Dst, Context>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
diff --git a/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr b/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr
index bd72d64ccd7..20a680a7484 100644
--- a/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr
+++ b/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr
@@ -21,7 +21,7 @@ note: required by a bound in `is_transmutable`
   --> $DIR/should_reject_if_dst_has_unreachable_ty.rs:15:14
    |
 LL |     pub fn is_transmutable<Src, Dst, Context>()
-   |            --------------- required by a bound in this
+   |            --------------- required by a bound in this function
 LL |     where
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
diff --git a/tests/ui/transmute/transmute-padding-ice.stderr b/tests/ui/transmute/transmute-padding-ice.stderr
index c9233890f7a..87fd4fb6630 100644
--- a/tests/ui/transmute/transmute-padding-ice.stderr
+++ b/tests/ui/transmute/transmute-padding-ice.stderr
@@ -9,7 +9,7 @@ note: required by a bound in `is_maybe_transmutable`
   --> $DIR/transmute-padding-ice.rs:11:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this
+   |              --------------------- required by a bound in this function
 LL |       where
 LL |           Dst: BikeshedIntrinsicFrom<
    |  ______________^
diff --git a/tests/ui/tuple/wrong_argument_ice-3.stderr b/tests/ui/tuple/wrong_argument_ice-3.stderr
index 7143c959478..8b9dac6e291 100644
--- a/tests/ui/tuple/wrong_argument_ice-3.stderr
+++ b/tests/ui/tuple/wrong_argument_ice-3.stderr
@@ -11,7 +11,7 @@ LL |         groups.push(new_group, vec![process]);
    |                     ^^^^^^^^^
    = note: expected tuple `(Vec<String>, Vec<Process>)`
              found struct `Vec<String>`
-note: associated function defined here
+note: method defined here
   --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
 help: remove the extra argument
    |
diff --git a/tests/ui/tuple/wrong_argument_ice.stderr b/tests/ui/tuple/wrong_argument_ice.stderr
index f1b00ae0b92..213ca8f885c 100644
--- a/tests/ui/tuple/wrong_argument_ice.stderr
+++ b/tests/ui/tuple/wrong_argument_ice.stderr
@@ -4,7 +4,7 @@ error[E0061]: method takes 1 argument but 2 arguments were supplied
 LL |         self.acc.push_back(self.current_provides, self.current_requires);
    |                  ^^^^^^^^^
    |
-note: associated function defined here
+note: method defined here
   --> $SRC_DIR/alloc/src/collections/vec_deque/mod.rs:LL:COL
 help: wrap these arguments in parentheses to construct a tuple
    |
diff --git a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs
index 0031a4665c8..759a7fd7e05 100644
--- a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs
+++ b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs
@@ -62,10 +62,10 @@ fn main() {
     AliasFixed::TSVariant::<()>(());
     //~^ ERROR type arguments are not allowed on this type [E0109]
     AliasFixed::<()>::TSVariant(());
-    //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
+    //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
     AliasFixed::<()>::TSVariant::<()>(());
     //~^ ERROR type arguments are not allowed on this type [E0109]
-    //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
+    //~| ERROR type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
 
     // Struct variant
 
@@ -80,10 +80,10 @@ fn main() {
     AliasFixed::SVariant::<()> { v: () };
     //~^ ERROR type arguments are not allowed on this type [E0109]
     AliasFixed::<()>::SVariant { v: () };
-    //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
+    //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
     AliasFixed::<()>::SVariant::<()> { v: () };
     //~^ ERROR type arguments are not allowed on this type [E0109]
-    //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
+    //~| ERROR type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
 
     // Unit variant
 
@@ -98,8 +98,8 @@ fn main() {
     AliasFixed::UVariant::<()>;
     //~^ ERROR type arguments are not allowed on this type [E0109]
     AliasFixed::<()>::UVariant;
-    //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
+    //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
     AliasFixed::<()>::UVariant::<()>;
     //~^ ERROR type arguments are not allowed on this type [E0109]
-    //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
+    //~| ERROR type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
 }
diff --git a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
index a922d7a5e41..758ff31ff70 100644
--- a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
+++ b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
@@ -304,7 +304,7 @@ LL |     AliasFixed::TSVariant::<()>(());
    |                 |
    |                 not allowed on this type
 
-error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/enum-variant-generic-args.rs:64:5
    |
 LL |     AliasFixed::<()>::TSVariant(());
@@ -318,7 +318,7 @@ note: type alias defined here, with 0 generic parameters
 LL | type AliasFixed = Enum<()>;
    |      ^^^^^^^^^^
 
-error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/enum-variant-generic-args.rs:66:5
    |
 LL |     AliasFixed::<()>::TSVariant::<()>(());
@@ -395,7 +395,7 @@ LL -     AliasFixed::SVariant::<()> { v: () };
 LL +     AliasFixed::<()>::SVariant { v: () };
    |
 
-error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/enum-variant-generic-args.rs:82:5
    |
 LL |     AliasFixed::<()>::SVariant { v: () };
@@ -409,7 +409,7 @@ note: type alias defined here, with 0 generic parameters
 LL | type AliasFixed = Enum<()>;
    |      ^^^^^^^^^^
 
-error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/enum-variant-generic-args.rs:84:5
    |
 LL |     AliasFixed::<()>::SVariant::<()> { v: () };
@@ -470,7 +470,7 @@ LL |     AliasFixed::UVariant::<()>;
    |                 |
    |                 not allowed on this type
 
-error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/enum-variant-generic-args.rs:100:5
    |
 LL |     AliasFixed::<()>::UVariant;
@@ -484,7 +484,7 @@ note: type alias defined here, with 0 generic parameters
 LL | type AliasFixed = Enum<()>;
    |      ^^^^^^^^^^
 
-error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/enum-variant-generic-args.rs:102:5
    |
 LL |     AliasFixed::<()>::UVariant::<()>;
diff --git a/tests/ui/type-alias-impl-trait/bounds-are-checked.rs b/tests/ui/type-alias-impl-trait/bounds-are-checked.rs
index eeb5dca07f0..7c3a3a84406 100644
--- a/tests/ui/type-alias-impl-trait/bounds-are-checked.rs
+++ b/tests/ui/type-alias-impl-trait/bounds-are-checked.rs
@@ -6,7 +6,6 @@
 type X<'a> = impl Into<&'static str> + From<&'a str>;
 
 fn f<'a: 'static>(t: &'a str) -> X<'a> {
-    //~^ WARNING unnecessary lifetime parameter
     t
     //~^ ERROR expected generic lifetime parameter, found `'static`
 }
diff --git a/tests/ui/type-alias-impl-trait/bounds-are-checked.stderr b/tests/ui/type-alias-impl-trait/bounds-are-checked.stderr
index 94882597a62..962dedde09a 100644
--- a/tests/ui/type-alias-impl-trait/bounds-are-checked.stderr
+++ b/tests/ui/type-alias-impl-trait/bounds-are-checked.stderr
@@ -1,13 +1,5 @@
-warning: unnecessary lifetime parameter `'a`
-  --> $DIR/bounds-are-checked.rs:8:6
-   |
-LL | fn f<'a: 'static>(t: &'a str) -> X<'a> {
-   |      ^^
-   |
-   = help: you can use the `'static` lifetime directly, in place of `'a`
-
 error[E0792]: expected generic lifetime parameter, found `'static`
-  --> $DIR/bounds-are-checked.rs:10:5
+  --> $DIR/bounds-are-checked.rs:9:5
    |
 LL | type X<'a> = impl Into<&'static str> + From<&'a str>;
    |        -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
@@ -15,6 +7,6 @@ LL | type X<'a> = impl Into<&'static str> + From<&'a str>;
 LL |     t
    |     ^
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs
index 07f825aea50..6f9434255a8 100644
--- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs
+++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs
@@ -4,7 +4,6 @@ mod test_lifetime_param {
     type Ty<'a> = impl Sized + 'a;
     fn defining(a: &str) -> Ty<'_> { a }
     fn assert_static<'a: 'static>() {}
-    //~^ WARN: unnecessary lifetime parameter `'a`
     fn test<'a>() where Ty<'a>: 'static { assert_static::<'a>() }
     //~^ ERROR: lifetime may not live long enough
 }
@@ -13,14 +12,12 @@ mod test_higher_kinded_lifetime_param {
     type Ty<'a> = impl Sized + 'a;
     fn defining(a: &str) -> Ty<'_> { a }
     fn assert_static<'a: 'static>() {}
-    //~^ WARN: unnecessary lifetime parameter `'a`
     fn test<'a>() where for<'b> Ty<'b>: 'a { assert_static::<'a>() }
     //~^ ERROR: lifetime may not live long enough
 }
 
 mod test_higher_kinded_lifetime_param2 {
     fn assert_static<'a: 'static>() {}
-    //~^ WARN: unnecessary lifetime parameter `'a`
     fn test<'a>() { assert_static::<'a>() }
     //~^ ERROR: lifetime may not live long enough
 }
diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr
index 887620a4d50..399775641f8 100644
--- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr
+++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr
@@ -1,41 +1,17 @@
-warning: unnecessary lifetime parameter `'a`
-  --> $DIR/implied_lifetime_wf_check3.rs:6:22
-   |
-LL |     fn assert_static<'a: 'static>() {}
-   |                      ^^
-   |
-   = help: you can use the `'static` lifetime directly, in place of `'a`
-
-warning: unnecessary lifetime parameter `'a`
-  --> $DIR/implied_lifetime_wf_check3.rs:15:22
-   |
-LL |     fn assert_static<'a: 'static>() {}
-   |                      ^^
-   |
-   = help: you can use the `'static` lifetime directly, in place of `'a`
-
-warning: unnecessary lifetime parameter `'a`
-  --> $DIR/implied_lifetime_wf_check3.rs:22:22
-   |
-LL |     fn assert_static<'a: 'static>() {}
-   |                      ^^
-   |
-   = help: you can use the `'static` lifetime directly, in place of `'a`
-
 error: lifetime may not live long enough
-  --> $DIR/implied_lifetime_wf_check3.rs:8:43
+  --> $DIR/implied_lifetime_wf_check3.rs:7:43
    |
 LL |     fn test<'a>() where Ty<'a>: 'static { assert_static::<'a>() }
    |             -- lifetime `'a` defined here ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/implied_lifetime_wf_check3.rs:17:46
+  --> $DIR/implied_lifetime_wf_check3.rs:15:46
    |
 LL |     fn test<'a>() where for<'b> Ty<'b>: 'a { assert_static::<'a>() }
    |             -- lifetime `'a` defined here    ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/implied_lifetime_wf_check3.rs:24:21
+  --> $DIR/implied_lifetime_wf_check3.rs:21:21
    |
 LL |     fn test<'a>() { assert_static::<'a>() }
    |             --      ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
@@ -43,7 +19,7 @@ LL |     fn test<'a>() { assert_static::<'a>() }
    |             lifetime `'a` defined here
 
 error[E0310]: the parameter type `A` may not live long enough
-  --> $DIR/implied_lifetime_wf_check3.rs:32:41
+  --> $DIR/implied_lifetime_wf_check3.rs:29:41
    |
 LL |     fn test<A>() where Ty<A>: 'static { assert_static::<A>() }
    |                                         ^^^^^^^^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds
@@ -53,6 +29,6 @@ help: consider adding an explicit lifetime bound...
 LL |     fn test<A: 'static>() where Ty<A>: 'static { assert_static::<A>() }
    |              +++++++++
 
-error: aborting due to 4 previous errors; 3 warnings emitted
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0310`.
diff --git a/tests/ui/type-alias-impl-trait/match-unification.rs b/tests/ui/type-alias-impl-trait/match-unification.rs
new file mode 100644
index 00000000000..f5c2abc0efa
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/match-unification.rs
@@ -0,0 +1,14 @@
+use std::fmt::Debug;
+
+// check-pass
+
+fn bar() -> impl Debug {}
+
+fn baz(b: bool) -> Option<impl Debug> {
+    match b {
+        true => baz(false),
+        false => Some(bar()),
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr
index a31cf1a51cc..ff375b2ff86 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr
@@ -1,4 +1,4 @@
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types
   --> $DIR/type-alias-impl-trait-fn-type.rs:6:20
    |
 LL | type Foo = fn() -> impl Send;
diff --git a/tests/ui/type-inference/sort_by_key.stderr b/tests/ui/type-inference/sort_by_key.stderr
index 0a48d5756eb..de7b4b24899 100644
--- a/tests/ui/type-inference/sort_by_key.stderr
+++ b/tests/ui/type-inference/sort_by_key.stderr
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/sort_by_key.rs:3:40
    |
 LL |     lst.sort_by_key(|&(v, _)| v.iter().sum());
-   |                                        ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum`
+   |                                        ^^^ cannot infer type of the type parameter `S` declared on the method `sum`
    |
 help: consider specifying the generic argument
    |
diff --git a/tests/ui/type/type-check/point-at-inference-3.fixed b/tests/ui/type/type-check/point-at-inference-3.fixed
index 1a960133ceb..edd4adf8bd2 100644
--- a/tests/ui/type/type-check/point-at-inference-3.fixed
+++ b/tests/ui/type/type-check/point-at-inference-3.fixed
@@ -7,6 +7,6 @@ fn main() {
     v.push(1i32); //~ ERROR mismatched types
     //~^ NOTE expected `i32`, found `u32`
     //~| NOTE arguments to this method are incorrect
-    //~| NOTE associated function defined here
+    //~| NOTE method defined here
     //~| HELP change the type of the numeric literal from `u32` to `i32`
 }
diff --git a/tests/ui/type/type-check/point-at-inference-3.rs b/tests/ui/type/type-check/point-at-inference-3.rs
index 92910ae1a31..49d7b50075b 100644
--- a/tests/ui/type/type-check/point-at-inference-3.rs
+++ b/tests/ui/type/type-check/point-at-inference-3.rs
@@ -7,6 +7,6 @@ fn main() {
     v.push(1u32); //~ ERROR mismatched types
     //~^ NOTE expected `i32`, found `u32`
     //~| NOTE arguments to this method are incorrect
-    //~| NOTE associated function defined here
+    //~| NOTE method defined here
     //~| HELP change the type of the numeric literal from `u32` to `i32`
 }
diff --git a/tests/ui/type/type-check/point-at-inference-3.stderr b/tests/ui/type/type-check/point-at-inference-3.stderr
index 999c3148362..2c4907ed263 100644
--- a/tests/ui/type/type-check/point-at-inference-3.stderr
+++ b/tests/ui/type/type-check/point-at-inference-3.stderr
@@ -9,7 +9,7 @@ LL |     v.push(1u32);
    |       |
    |       arguments to this method are incorrect
    |
-note: associated function defined here
+note: method defined here
   --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
 help: change the type of the numeric literal from `u32` to `i32`
    |
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 7903e9e83cf..aea9b2c6c14 100644
--- a/tests/ui/type/type-check/point-at-inference-4.rs
+++ b/tests/ui/type/type-check/point-at-inference-4.rs
@@ -2,7 +2,7 @@ struct S<A, B>(Option<(A, B)>);
 
 impl<A, B> S<A, B> {
     fn infer(&self, a: A, b: B) {}
-    //~^ NOTE associated function defined here
+    //~^ NOTE method defined here
     //~| NOTE
     //~| NOTE
 }
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 fac9701e4a1..28833d2ed1c 100644
--- a/tests/ui/type/type-check/point-at-inference-4.stderr
+++ b/tests/ui/type/type-check/point-at-inference-4.stderr
@@ -4,7 +4,7 @@ error[E0061]: this method takes 2 arguments but 1 argument was supplied
 LL |     s.infer(0i32);
    |       ^^^^^------ an argument is missing
    |
-note: associated function defined here
+note: method defined here
   --> $DIR/point-at-inference-4.rs:4:8
    |
 LL |     fn infer(&self, a: A, b: B) {}
diff --git a/tests/ui/type/wrong-call-return-type-due-to-generic-arg.stderr b/tests/ui/type/wrong-call-return-type-due-to-generic-arg.stderr
index 4d012cb156b..fbe6bfeebb1 100644
--- a/tests/ui/type/wrong-call-return-type-due-to-generic-arg.stderr
+++ b/tests/ui/type/wrong-call-return-type-due-to-generic-arg.stderr
@@ -95,7 +95,7 @@ LL |     let x: u16 = (S {}).method(0u32);
    |                  ^^^^^^^^^^^^^^----^
    |                                |
    |                                this argument influences the return type of `method`
-note: associated function defined here
+note: method defined here
   --> $DIR/wrong-call-return-type-due-to-generic-arg.rs:7:8
    |
 LL |     fn method<T>(&self, x: T) -> T {
diff --git a/tests/ui/typeck/bad-type-in-vec-push.stderr b/tests/ui/typeck/bad-type-in-vec-push.stderr
index 882854acb1d..ae46050c91b 100644
--- a/tests/ui/typeck/bad-type-in-vec-push.stderr
+++ b/tests/ui/typeck/bad-type-in-vec-push.stderr
@@ -10,7 +10,7 @@ LL |     result.push(vector);
    |
    = note: expected type `{integer}`
             found struct `Vec<_>`
-note: associated function defined here
+note: method defined here
   --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
 
 error[E0308]: mismatched types
@@ -21,7 +21,7 @@ LL |     x.push("");
    |       |
    |       arguments to this method are incorrect
    |
-note: associated function defined here
+note: method defined here
   --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/typeck/issue-104513-ice.stderr b/tests/ui/typeck/issue-104513-ice.stderr
index 42cfe38aed8..09187d7863a 100644
--- a/tests/ui/typeck/issue-104513-ice.stderr
+++ b/tests/ui/typeck/issue-104513-ice.stderr
@@ -4,7 +4,7 @@ error[E0405]: cannot find trait `Oops` in this scope
 LL |     let _: S<impl Oops> = S;
    |                   ^^^^ not found in this scope
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings
   --> $DIR/issue-104513-ice.rs:3:14
    |
 LL |     let _: S<impl Oops> = S;
diff --git a/tests/ui/typeck/issue-75883.rs b/tests/ui/typeck/issue-75883.rs
index 885acc48231..c50ea0a086b 100644
--- a/tests/ui/typeck/issue-75883.rs
+++ b/tests/ui/typeck/issue-75883.rs
@@ -4,7 +4,7 @@ pub struct UI {}
 
 impl UI {
     pub fn run() -> Result<_> {
-        //~^ ERROR: this enum takes 2 generic arguments but 1 generic argument was supplied
+        //~^ ERROR: enum takes 2 generic arguments but 1 generic argument was supplied
         //~| ERROR: the placeholder `_` is not allowed within types on item signatures for return types
         let mut ui = UI {};
         ui.interact();
@@ -13,7 +13,7 @@ impl UI {
     }
 
     pub fn interact(&mut self) -> Result<_> {
-        //~^ ERROR: this enum takes 2 generic arguments but 1 generic argument was supplied
+        //~^ ERROR: enum takes 2 generic arguments but 1 generic argument was supplied
         //~| ERROR: the placeholder `_` is not allowed within types on item signatures for return types
         unimplemented!();
     }
diff --git a/tests/ui/typeck/issue-75883.stderr b/tests/ui/typeck/issue-75883.stderr
index f5adcabe3e9..a1ed0840675 100644
--- a/tests/ui/typeck/issue-75883.stderr
+++ b/tests/ui/typeck/issue-75883.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: enum takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-75883.rs:6:21
    |
 LL |     pub fn run() -> Result<_> {
@@ -11,7 +11,7 @@ help: add missing generic argument
 LL |     pub fn run() -> Result<_, E> {
    |                             +++
 
-error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: enum takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-75883.rs:15:35
    |
 LL |     pub fn interact(&mut self) -> Result<_> {
diff --git a/tests/ui/typeck/issue-84768.stderr b/tests/ui/typeck/issue-84768.stderr
index 63936f9979f..3d2d53f5c76 100644
--- a/tests/ui/typeck/issue-84768.stderr
+++ b/tests/ui/typeck/issue-84768.stderr
@@ -21,7 +21,7 @@ LL |     <F as FnOnce(&mut u8)>::call_once(f, 1)
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^
    |                                          |
    |                                          this argument influences the return type of `FnOnce`
-note: associated function defined here
+note: method defined here
   --> $SRC_DIR/core/src/ops/function.rs:LL:COL
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.rs b/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.rs
new file mode 100644
index 00000000000..5ff567cd07c
--- /dev/null
+++ b/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.rs
@@ -0,0 +1,6 @@
+// compile-flags: -Ztrait-solver=next
+// known-bug: unknown
+
+fn main() {
+    (0u8 + 0u8) as char;
+}
diff --git a/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.stderr b/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.stderr
new file mode 100644
index 00000000000..6b09ccd5214
--- /dev/null
+++ b/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.stderr
@@ -0,0 +1,9 @@
+error[E0271]: type mismatch resolving `char == <u8 as Add>::Output`
+  --> $DIR/cast-checks-handling-projections.rs:5:5
+   |
+LL |     (0u8 + 0u8) as char;
+   |     ^^^^^^^^^^^ types differ
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs b/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs
index c463a8ad0c7..7ff9199f63c 100644
--- a/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs
+++ b/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs
@@ -1,17 +1,17 @@
 fn foo1<T:Copy<U>, U>(x: T) {}
-//~^ ERROR this trait takes 0 generic arguments but 1 generic argument was supplied
+//~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied
 
 trait Trait: Copy<dyn Send> {}
-//~^ ERROR this trait takes 0 generic arguments but 1 generic argument was supplied
+//~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied
 
 struct MyStruct1<T: Copy<T>>;
-//~^ ERROR this trait takes 0 generic arguments but 1 generic argument was supplied
+//~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied
 
 struct MyStruct2<'a, T: Copy<'a>>;
-//~^ ERROR this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
+//~^ ERROR trait takes 0 lifetime arguments but 1 lifetime argument was supplied
 
 fn foo2<'a, T:Copy<'a, U>, U>(x: T) {}
-//~^ ERROR this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
-//~| ERROR this trait takes 0 generic arguments but 1 generic argument was supplied
+//~^ ERROR trait takes 0 lifetime arguments but 1 lifetime argument was supplied
+//~| ERROR trait takes 0 generic arguments but 1 generic argument was supplied
 
 fn main() { }
diff --git a/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr b/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr
index 331540d1e42..a71fd953658 100644
--- a/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr
+++ b/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/typeck-builtin-bound-type-parameters.rs:1:11
    |
 LL | fn foo1<T:Copy<U>, U>(x: T) {}
@@ -6,7 +6,7 @@ LL | fn foo1<T:Copy<U>, U>(x: T) {}
    |           |
    |           expected 0 generic arguments
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/typeck-builtin-bound-type-parameters.rs:4:14
    |
 LL | trait Trait: Copy<dyn Send> {}
@@ -14,7 +14,7 @@ LL | trait Trait: Copy<dyn Send> {}
    |              |
    |              expected 0 generic arguments
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/typeck-builtin-bound-type-parameters.rs:7:21
    |
 LL | struct MyStruct1<T: Copy<T>>;
@@ -22,7 +22,7 @@ LL | struct MyStruct1<T: Copy<T>>;
    |                     |
    |                     expected 0 generic arguments
 
-error[E0107]: this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/typeck-builtin-bound-type-parameters.rs:10:25
    |
 LL | struct MyStruct2<'a, T: Copy<'a>>;
@@ -30,7 +30,7 @@ LL | struct MyStruct2<'a, T: Copy<'a>>;
    |                         |
    |                         expected 0 lifetime arguments
 
-error[E0107]: this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/typeck-builtin-bound-type-parameters.rs:13:15
    |
 LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {}
@@ -38,7 +38,7 @@ LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {}
    |               |
    |               expected 0 lifetime arguments
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/typeck-builtin-bound-type-parameters.rs:13:15
    |
 LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {}
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs
index b96c5271339..a450dbb82d1 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.rs
+++ b/tests/ui/typeck/typeck_type_placeholder_item.rs
@@ -227,4 +227,6 @@ fn evens_squared(n: usize) -> _ {
 }
 
 const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
-//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
+//~^ ERROR the trait bound
+//~| ERROR the trait bound
+//~| ERROR the placeholder
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr
index bc02547c65e..bc6c9fd0779 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr
@@ -437,17 +437,37 @@ LL | fn evens_squared(n: usize) -> _ {
    |                               not allowed in type signatures
    |                               help: replace with an appropriate return type: `impl Iterator<Item = usize>`
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
-  --> $DIR/typeck_type_placeholder_item.rs:229:10
+error[E0277]: the trait bound `std::ops::Range<{integer}>: Iterator` is not satisfied
+  --> $DIR/typeck_type_placeholder_item.rs:229:22
    |
 LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
-   |          ^ not allowed in type signatures
+   |                      ^^^^^^ `std::ops::Range<{integer}>` is not an iterator
+   |
+   = help: the trait `~const Iterator` is not implemented for `std::ops::Range<{integer}>`
+note: the trait `Iterator` is implemented for `std::ops::Range<{integer}>`, but that implementation is not `const`
+  --> $DIR/typeck_type_placeholder_item.rs:229:14
+   |
+LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
+   |              ^^^^^^^
+
+error[E0277]: the trait bound `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>: Iterator` is not satisfied
+  --> $DIR/typeck_type_placeholder_item.rs:229:45
    |
-note: however, the inferred type `Map<Filter<Range<i32>, [closure@typeck_type_placeholder_item.rs:229:29]>, [closure@typeck_type_placeholder_item.rs:229:49]>` cannot be named
+LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
+   |                                             ^^^ `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>` is not an iterator
+   |
+   = help: the trait `~const Iterator` is not implemented for `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>`
+note: the trait `Iterator` is implemented for `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>`, but that implementation is not `const`
   --> $DIR/typeck_type_placeholder_item.rs:229:14
    |
 LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
+  --> $DIR/typeck_type_placeholder_item.rs:229:10
+   |
+LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
+   |          ^ not allowed in type signatures
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
   --> $DIR/typeck_type_placeholder_item.rs:140:31
@@ -657,7 +677,7 @@ LL |     const D: _ = 42;
    |              not allowed in type signatures
    |              help: replace with the correct type: `i32`
 
-error: aborting due to 71 previous errors
+error: aborting due to 73 previous errors
 
-Some errors have detailed explanations: E0121, E0282, E0403.
+Some errors have detailed explanations: E0121, E0277, E0282, E0403.
 For more information about an error, try `rustc --explain E0121`.
diff --git a/tests/ui/typeck/typeck_type_placeholder_lifetime_1.rs b/tests/ui/typeck/typeck_type_placeholder_lifetime_1.rs
index 43e46c5b6c3..90b12ffdf77 100644
--- a/tests/ui/typeck/typeck_type_placeholder_lifetime_1.rs
+++ b/tests/ui/typeck/typeck_type_placeholder_lifetime_1.rs
@@ -7,5 +7,5 @@ struct Foo<'a, T:'a> {
 
 pub fn main() {
     let c: Foo<_, _> = Foo { r: &5 };
-    //~^ ERROR this struct takes 1 generic argument but 2 generic arguments were supplied
+    //~^ ERROR struct takes 1 generic argument but 2 generic arguments were supplied
 }
diff --git a/tests/ui/typeck/typeck_type_placeholder_lifetime_1.stderr b/tests/ui/typeck/typeck_type_placeholder_lifetime_1.stderr
index a89c6b85c78..c4e4aed2067 100644
--- a/tests/ui/typeck/typeck_type_placeholder_lifetime_1.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_lifetime_1.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/typeck_type_placeholder_lifetime_1.rs:9:12
    |
 LL |     let c: Foo<_, _> = Foo { r: &5 };
diff --git a/tests/ui/typeck/typeck_type_placeholder_lifetime_2.rs b/tests/ui/typeck/typeck_type_placeholder_lifetime_2.rs
index 178b8b1229a..e361312ddba 100644
--- a/tests/ui/typeck/typeck_type_placeholder_lifetime_2.rs
+++ b/tests/ui/typeck/typeck_type_placeholder_lifetime_2.rs
@@ -7,5 +7,5 @@ struct Foo<'a, T:'a> {
 
 pub fn main() {
     let c: Foo<_, usize> = Foo { r: &5 };
-    //~^ ERROR this struct takes 1 generic argument but 2 generic arguments were supplied
+    //~^ ERROR struct takes 1 generic argument but 2 generic arguments were supplied
 }
diff --git a/tests/ui/typeck/typeck_type_placeholder_lifetime_2.stderr b/tests/ui/typeck/typeck_type_placeholder_lifetime_2.stderr
index f30766bdf01..302231777bd 100644
--- a/tests/ui/typeck/typeck_type_placeholder_lifetime_2.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_lifetime_2.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/typeck_type_placeholder_lifetime_2.rs:9:12
    |
 LL |     let c: Foo<_, usize> = Foo { r: &5 };
diff --git a/tests/ui/ufcs/ufcs-qpath-missing-params.rs b/tests/ui/ufcs/ufcs-qpath-missing-params.rs
index 766351634bb..6ab6580c0e6 100644
--- a/tests/ui/ufcs/ufcs-qpath-missing-params.rs
+++ b/tests/ui/ufcs/ufcs-qpath-missing-params.rs
@@ -15,6 +15,6 @@ fn main() {
       //~^ ERROR missing generics for
 
     <String as IntoCow>::into_cow::<str>("foo".to_string());
-    //~^ ERROR this associated function takes 0 generic arguments but 1
+    //~^ ERROR method takes 0 generic arguments but 1
     //~| ERROR missing generics for
 }
diff --git a/tests/ui/ufcs/ufcs-qpath-missing-params.stderr b/tests/ui/ufcs/ufcs-qpath-missing-params.stderr
index d0ec47d6132..2338871218b 100644
--- a/tests/ui/ufcs/ufcs-qpath-missing-params.stderr
+++ b/tests/ui/ufcs/ufcs-qpath-missing-params.stderr
@@ -30,7 +30,7 @@ help: add missing generic argument
 LL |     <String as IntoCow<B>>::into_cow::<str>("foo".to_string());
    |                       +++
 
-error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/ufcs-qpath-missing-params.rs:17:26
    |
 LL |     <String as IntoCow>::into_cow::<str>("foo".to_string());
@@ -38,7 +38,7 @@ LL |     <String as IntoCow>::into_cow::<str>("foo".to_string());
    |                          |
    |                          expected 0 generic arguments
    |
-note: associated function defined here, with 0 generic parameters
+note: method defined here, with 0 generic parameters
   --> $DIR/ufcs-qpath-missing-params.rs:4:8
    |
 LL |     fn into_cow(self) -> Cow<'a, B>;
diff --git a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr
index e85144a31ca..96ac4321689 100644
--- a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr
+++ b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr
@@ -28,7 +28,7 @@ LL |     <i32 as Add<i32>>::add(1u32, 2);
    |     ^^^^^^^^^^^^^^^^^^^^^^^----^^^^
    |                            |
    |                            this argument influences the return type of `Add`
-note: associated function defined here
+note: method defined here
   --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
 help: change the type of the numeric literal from `u32` to `i32`
    |
@@ -50,7 +50,7 @@ LL |     <i32 as Add<i32>>::add(1, 2u32);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^----^
    |                               |
    |                               this argument influences the return type of `Add`
-note: associated function defined here
+note: method defined here
   --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
 help: change the type of the numeric literal from `u32` to `i32`
    |
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs
index 65f40075bd8..c575f507704 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs
@@ -28,7 +28,7 @@ fn test<'a,'b>() {
 }
 
 fn test2(x: &dyn Foo<(isize,),Output=()>, y: &dyn Foo(isize)) {
-    //~^ ERROR this trait takes 1 lifetime argument but 0 lifetime arguments were supplied
+    //~^ ERROR trait takes 1 lifetime argument but 0 lifetime arguments were supplied
     // Here, the omitted lifetimes are expanded to distinct things.
     same_type(x, y)
 }
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr
index 016fc4dfb24..8814617814c 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this trait takes 1 lifetime argument but 0 lifetime arguments were supplied
+error[E0107]: trait takes 1 lifetime argument but 0 lifetime arguments were supplied
   --> $DIR/unboxed-closure-sugar-region.rs:30:51
    |
 LL | fn test2(x: &dyn Foo<(isize,),Output=()>, y: &dyn Foo(isize)) {
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs
index 462f6fb7b87..14d5646b508 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs
@@ -7,7 +7,7 @@ struct Bar<A> {
 fn bar() {
     let x: Box<Bar()> = panic!();
     //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
-    //~| ERROR this struct takes 1 generic argument but 0 generic arguments
+    //~| ERROR struct takes 1 generic argument but 0 generic arguments
 }
 
 fn main() { }
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr
index 29ea5735cad..27b22c2127b 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr
@@ -4,7 +4,7 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
 LL |     let x: Box<Bar()> = panic!();
    |                ^^^^^ only `Fn` traits may use parentheses
 
-error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/unboxed-closure-sugar-used-on-struct-1.rs:8:16
    |
 LL |     let x: Box<Bar()> = panic!();
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs
index bd61cbd8022..657b29204cd 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs
@@ -6,7 +6,7 @@ struct Bar<A> {
 
 fn foo(b: Box<Bar()>) {
     //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
-    //~| ERROR this struct takes 1 generic argument but 0 generic arguments
+    //~| ERROR struct takes 1 generic argument but 0 generic arguments
 }
 
 fn main() { }
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr
index 427ba3414f8..94e42a66c9e 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr
@@ -4,7 +4,7 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
 LL | fn foo(b: Box<Bar()>) {
    |               ^^^^^ only `Fn` traits may use parentheses
 
-error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/unboxed-closure-sugar-used-on-struct.rs:7:15
    |
 LL | fn foo(b: Box<Bar()>) {
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs
index f26ad8e93a1..dd47ae73a38 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs
@@ -3,7 +3,7 @@
 trait Three<A,B,C> { fn dummy(&self) -> (A,B,C); }
 
 fn foo(_: &dyn Three())
-//~^ ERROR this trait takes 3 generic arguments but 1 generic argument
+//~^ ERROR trait takes 3 generic arguments but 1 generic argument
 //~| ERROR associated type `Output` not found
 {}
 
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr
index ebaacf0a698..5d7fe3fa533 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this trait takes 3 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 3 generic arguments but 1 generic argument was supplied
   --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs:5:16
    |
 LL | fn foo(_: &dyn Three())
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.rs
index 4465b43a757..2c7e12f3257 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.rs
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.rs
@@ -3,25 +3,25 @@
 trait Zero { fn dummy(&self); }
 
 fn foo1(_: dyn Zero()) {
-    //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+    //~^ ERROR trait takes 0 generic arguments but 1 generic argument
     //~| ERROR associated type `Output` not found for `Zero`
 }
 
 fn foo2(_: dyn Zero<usize>) {
-    //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+    //~^ ERROR trait takes 0 generic arguments but 1 generic argument
 }
 
 fn foo3(_: dyn Zero <   usize   >) {
-    //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+    //~^ ERROR trait takes 0 generic arguments but 1 generic argument
 }
 
 fn foo4(_: dyn Zero(usize)) {
-    //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+    //~^ ERROR trait takes 0 generic arguments but 1 generic argument
     //~| ERROR associated type `Output` not found for `Zero`
 }
 
 fn foo5(_: dyn Zero (   usize   )) {
-    //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+    //~^ ERROR trait takes 0 generic arguments but 1 generic argument
     //~| ERROR associated type `Output` not found for `Zero`
 }
 
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.stderr
index 9601e64c189..50b90553aa7 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:5:16
    |
 LL | fn foo1(_: dyn Zero()) {
@@ -18,7 +18,7 @@ error[E0220]: associated type `Output` not found for `Zero`
 LL | fn foo1(_: dyn Zero()) {
    |                ^^^^^^ associated type `Output` not found
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:10:16
    |
 LL | fn foo2(_: dyn Zero<usize>) {
@@ -32,7 +32,7 @@ note: trait defined here, with 0 generic parameters
 LL | trait Zero { fn dummy(&self); }
    |       ^^^^
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:14:16
    |
 LL | fn foo3(_: dyn Zero <   usize   >) {
@@ -46,7 +46,7 @@ note: trait defined here, with 0 generic parameters
 LL | trait Zero { fn dummy(&self); }
    |       ^^^^
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:18:16
    |
 LL | fn foo4(_: dyn Zero(usize)) {
@@ -66,7 +66,7 @@ error[E0220]: associated type `Output` not found for `Zero`
 LL | fn foo4(_: dyn Zero(usize)) {
    |                ^^^^^^^^^^^ associated type `Output` not found
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:23:16
    |
 LL | fn foo5(_: dyn Zero (   usize   )) {
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.rs
index 4bcf90552f9..ad60b0a0c77 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.rs
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.rs
@@ -3,7 +3,7 @@
 trait Trait {}
 
 fn f<F:Trait(isize) -> isize>(x: F) {}
-//~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+//~^ ERROR trait takes 0 generic arguments but 1 generic argument
 //~| ERROR associated type `Output` not found for `Trait`
 
 fn main() {}
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.stderr
index 3ff05fb2331..130b193d69c 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/unboxed-closure-sugar-wrong-trait.rs:5:8
    |
 LL | fn f<F:Trait(isize) -> isize>(x: F) {}
diff --git a/tests/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr b/tests/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr
index 635ebbb71d0..846a44ce4d7 100644
--- a/tests/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr
@@ -14,7 +14,7 @@ note: required by a bound in `foo`
   --> $DIR/unboxed-closures-infer-fn-once-move-from-projection.rs:4:14
    |
 LL | fn foo<F>(f: F)
-   |    --- required by a bound in this
+   |    --- required by a bound in this function
 LL |     where F: Fn()
    |              ^^^^ required by this bound in `foo`
 
diff --git a/tests/ui/unsized/issue-71659.stderr b/tests/ui/unsized/issue-71659.stderr
index d7b95f55769..b57b3015e47 100644
--- a/tests/ui/unsized/issue-71659.stderr
+++ b/tests/ui/unsized/issue-71659.stderr
@@ -8,7 +8,7 @@ note: required by a bound in `Cast::cast`
   --> $DIR/issue-71659.rs:19:15
    |
 LL |     fn cast<T: ?Sized>(&self) -> &T
-   |        ---- required by a bound in this
+   |        ---- required by a bound in this associated function
 LL |     where
 LL |         Self: CastTo<T>,
    |               ^^^^^^^^^ required by this bound in `Cast::cast`
diff --git a/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr b/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr
index 30248a7a397..191a8ca8ebc 100644
--- a/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr
+++ b/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr
@@ -8,7 +8,7 @@ note: required by a bound in `called`
   --> $DIR/higher-ranked-fn-type.rs:12:25
    |
 LL | fn called()
-   |    ------ required by a bound in this
+   |    ------ required by a bound in this function
 LL | where
 LL |     for<'b> fn(&'b ()): Foo,
    |                         ^^^ required by this bound in `called`
diff --git a/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr b/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr
index 268cef6e275..f4c7acd5c58 100644
--- a/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr
+++ b/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr
@@ -8,7 +8,7 @@ note: required by a bound in `called`
   --> $DIR/higher-ranked-fn-type.rs:12:25
    |
 LL | fn called()
-   |    ------ required by a bound in this
+   |    ------ required by a bound in this function
 LL | where
 LL |     for<'b> fn(&'b ()): Foo,
    |                         ^^^ required by this bound in `called`
diff --git a/tests/ui/xc-private-method2.rs b/tests/ui/xc-private-method2.rs
index 92946923f6e..f11b251082b 100644
--- a/tests/ui/xc-private-method2.rs
+++ b/tests/ui/xc-private-method2.rs
@@ -4,8 +4,8 @@ extern crate xc_private_method_lib;
 
 fn main() {
     let _ = xc_private_method_lib::Struct{ x: 10 }.meth_struct();
-    //~^ ERROR associated function `meth_struct` is private
+    //~^ ERROR method `meth_struct` is private
 
     let _ = xc_private_method_lib::Enum::Variant1(20).meth_enum();
-    //~^ ERROR associated function `meth_enum` is private
+    //~^ ERROR method `meth_enum` is private
 }
diff --git a/tests/ui/xc-private-method2.stderr b/tests/ui/xc-private-method2.stderr
index b569882f8c1..af0c3cfcb2c 100644
--- a/tests/ui/xc-private-method2.stderr
+++ b/tests/ui/xc-private-method2.stderr
@@ -1,24 +1,24 @@
-error[E0624]: associated function `meth_struct` is private
+error[E0624]: method `meth_struct` is private
   --> $DIR/xc-private-method2.rs:6:52
    |
 LL |     let _ = xc_private_method_lib::Struct{ x: 10 }.meth_struct();
-   |                                                    ^^^^^^^^^^^ private associated function
+   |                                                    ^^^^^^^^^^^ private method
    |
   ::: $DIR/auxiliary/xc-private-method-lib.rs:12:5
    |
 LL |     fn meth_struct(&self) -> isize {
-   |     ------------------------------ private associated function defined here
+   |     ------------------------------ private method defined here
 
-error[E0624]: associated function `meth_enum` is private
+error[E0624]: method `meth_enum` is private
   --> $DIR/xc-private-method2.rs:9:55
    |
 LL |     let _ = xc_private_method_lib::Enum::Variant1(20).meth_enum();
-   |                                                       ^^^^^^^^^ private associated function
+   |                                                       ^^^^^^^^^ private method
    |
   ::: $DIR/auxiliary/xc-private-method-lib.rs:27:5
    |
 LL |     fn meth_enum(&self) -> isize {
-   |     ---------------------------- private associated function defined here
+   |     ---------------------------- private method defined here
 
 error: aborting due to 2 previous errors