about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--RELEASES.md103
-rw-r--r--compiler/rustc_ast_lowering/src/index.rs16
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs26
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs6
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs16
-rw-r--r--compiler/rustc_borrowck/src/constraints/mod.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs10
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs12
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs24
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs10
-rw-r--r--compiler/rustc_borrowck/src/type_check/canonical.rs10
-rw-r--r--compiler/rustc_borrowck/src/type_check/constraint_conversion.rs8
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs21
-rw-r--r--compiler/rustc_borrowck/src/type_check/relate_tys.rs8
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs6
-rw-r--r--compiler/rustc_codegen_cranelift/src/constant.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs13
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs13
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs30
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/type_.rs7
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs16
-rw-r--r--compiler/rustc_const_eval/src/const_eval/valtrees.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/intern.rs12
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs11
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs3
-rw-r--r--compiler/rustc_const_eval/src/lib.rs1
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs3
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/resolver.rs6
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs3
-rw-r--r--compiler/rustc_const_eval/src/util/call_kind.rs20
-rw-r--r--compiler/rustc_data_structures/src/lib.rs2
-rw-r--r--compiler/rustc_data_structures/src/unord.rs382
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0382.md2
-rw-r--r--compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl6
-rw-r--r--compiler/rustc_error_messages/locales/en-US/middle.ftl4
-rw-r--r--compiler/rustc_error_messages/locales/en-US/monomorphize.ftl3
-rw-r--r--compiler/rustc_feature/src/active.rs5
-rw-r--r--compiler/rustc_hir/src/hir.rs72
-rw-r--r--compiler/rustc_hir/src/intravisit.rs20
-rw-r--r--compiler/rustc_hir/src/lang_items.rs207
-rw-r--r--compiler/rustc_hir/src/lib.rs2
-rw-r--r--compiler/rustc_hir/src/stable_hash_impls.rs8
-rw-r--r--compiler/rustc_hir/src/weak_lang_items.rs60
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs60
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_method.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs58
-rw-r--r--compiler/rustc_hir_analysis/src/check_unused.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/orphan.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/unsafety.rs32
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs31
-rw-r--r--compiler/rustc_hir_analysis/src/collect/lifetimes.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs48
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs48
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/test.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/variance/test.rs7
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs13
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs41
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs15
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs13
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs24
-rw-r--r--compiler/rustc_incremental/src/persist/dirty_clean.rs8
-rw-r--r--compiler/rustc_infer/src/infer/canonical/query_response.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs2
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs8
-rw-r--r--compiler/rustc_interface/src/passes.rs2
-rw-r--r--compiler/rustc_interface/src/proc_macro_decls.rs2
-rw-r--r--compiler/rustc_lint/src/builtin.rs77
-rw-r--r--compiler/rustc_lint/src/context.rs4
-rw-r--r--compiler/rustc_lint/src/late.rs8
-rw-r--r--compiler/rustc_lint/src/lib.rs2
-rw-r--r--compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs2
-rw-r--r--compiler/rustc_lint/src/traits.rs2
-rw-r--r--compiler/rustc_lint/src/types.rs8
-rw-r--r--compiler/rustc_metadata/src/foreign_modules.rs6
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs16
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs5
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs57
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs6
-rw-r--r--compiler/rustc_middle/src/arena.rs4
-rw-r--r--compiler/rustc_middle/src/error.rs9
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs16
-rw-r--r--compiler/rustc_middle/src/hir/mod.rs8
-rw-r--r--compiler/rustc_middle/src/infer/canonical.rs6
-rw-r--r--compiler/rustc_middle/src/middle/lang_items.rs4
-rw-r--r--compiler/rustc_middle/src/middle/privacy.rs179
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs7
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs6
-rw-r--r--compiler/rustc_middle/src/mir/query.rs16
-rw-r--r--compiler/rustc_middle/src/query/mod.rs10
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs2
-rw-r--r--compiler/rustc_middle/src/traits/specialization_graph.rs17
-rw-r--r--compiler/rustc_middle/src/ty/context.rs5
-rw-r--r--compiler/rustc_middle/src/ty/error.rs6
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs4
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs8
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs38
-rw-r--r--compiler/rustc_middle/src/ty/query.rs3
-rw-r--r--compiler/rustc_middle/src/ty/util.rs21
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_operand.rs5
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs6
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs28
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs4
-rw-r--r--compiler/rustc_mir_transform/src/check_unsafety.rs2
-rw-r--r--compiler/rustc_mir_transform/src/const_prop.rs2
-rw-r--r--compiler/rustc_mir_transform/src/const_prop_lint.rs2
-rw-r--r--compiler/rustc_mir_transform/src/deduce_param_attrs.rs3
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs2
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs4
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs45
-rw-r--r--compiler/rustc_monomorphize/src/errors.rs6
-rw-r--r--compiler/rustc_monomorphize/src/partitioning/default.rs6
-rw-r--r--compiler/rustc_passes/src/check_attr.rs2
-rw-r--r--compiler/rustc_passes/src/dead.rs54
-rw-r--r--compiler/rustc_passes/src/diagnostic_items.rs8
-rw-r--r--compiler/rustc_passes/src/entry.rs20
-rw-r--r--compiler/rustc_passes/src/hir_id_validator.rs8
-rw-r--r--compiler/rustc_passes/src/lang_items.rs36
-rw-r--r--compiler/rustc_passes/src/layout_test.rs6
-rw-r--r--compiler/rustc_passes/src/reachable.rs40
-rw-r--r--compiler/rustc_passes/src/stability.rs39
-rw-r--r--compiler/rustc_passes/src/weak_lang_items.rs14
-rw-r--r--compiler/rustc_privacy/src/lib.rs233
-rw-r--r--compiler/rustc_query_impl/src/on_disk_cache.rs5
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs45
-rw-r--r--compiler/rustc_resolve/src/effective_visibilities.rs (renamed from compiler/rustc_resolve/src/access_levels.rs)61
-rw-r--r--compiler/rustc_resolve/src/late.rs103
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs41
-rw-r--r--compiler/rustc_resolve/src/lib.rs21
-rw-r--r--compiler/rustc_save_analysis/src/dump_visitor.rs78
-rw-r--r--compiler/rustc_save_analysis/src/lib.rs22
-rw-r--r--compiler/rustc_save_analysis/src/sig.rs10
-rw-r--r--compiler/rustc_span/src/lib.rs8
-rw-r--r--compiler/rustc_span/src/symbol.rs9
-rw-r--r--compiler/rustc_symbol_mangling/src/test.rs8
-rw-r--r--compiler/rustc_target/src/spec/abi.rs22
-rw-r--r--compiler/rustc_target/src/spec/mipsel_sony_psx.rs37
-rw-r--r--compiler/rustc_target/src/spec/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/infer.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs12
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs8
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs16
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs4
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs5
-rw-r--r--compiler/rustc_ty_utils/src/needs_drop.rs2
-rw-r--r--config.toml.example4
-rw-r--r--library/core/src/async_iter/async_iter.rs2
-rw-r--r--library/core/src/error.rs2
-rw-r--r--library/core/src/ffi/c_str.rs48
-rw-r--r--library/core/src/future/poll_fn.rs11
-rw-r--r--library/core/src/iter/traits/iterator.rs2
-rw-r--r--library/core/src/mem/mod.rs2
-rw-r--r--library/panic_unwind/src/emcc.rs40
-rw-r--r--library/panic_unwind/src/gcc.rs30
-rw-r--r--library/panic_unwind/src/seh.rs20
-rw-r--r--library/std/src/collections/hash/map.rs2
-rw-r--r--library/std/src/collections/hash/set.rs2
-rw-r--r--library/test/src/console.rs6
-rw-r--r--library/test/src/event.rs2
-rw-r--r--library/test/src/lib.rs90
-rw-r--r--src/bootstrap/bin/rustdoc.rs8
-rw-r--r--src/bootstrap/builder.rs1
-rw-r--r--src/bootstrap/check.rs7
-rw-r--r--src/bootstrap/compile.rs15
-rw-r--r--src/bootstrap/config.rs4
-rw-r--r--src/bootstrap/dist.rs32
-rw-r--r--src/bootstrap/doc.rs35
-rw-r--r--src/bootstrap/lib.rs4
-rw-r--r--src/bootstrap/test.rs19
-rw-r--r--src/bootstrap/tool.rs30
-rw-r--r--src/bootstrap/util.rs14
-rw-r--r--src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile2
-rw-r--r--src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile2
-rw-r--r--src/ci/docker/host-x86_64/dist-various-2/Dockerfile2
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile2
-rwxr-xr-xsrc/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh5
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile1
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile1
-rwxr-xr-xsrc/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh6
-rwxr-xr-xsrc/ci/run.sh5
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/codegen-options/index.md6
-rw-r--r--src/doc/rustc/src/platform-support.md1
-rw-r--r--src/doc/rustc/src/platform-support/mipsel-sony-psx.md49
-rw-r--r--src/doc/rustdoc/book.toml4
-rw-r--r--src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md10
-rw-r--r--src/librustdoc/clean/auto_trait.rs2
-rw-r--r--src/librustdoc/clean/blanket_impl.rs2
-rw-r--r--src/librustdoc/clean/inline.rs62
-rw-r--r--src/librustdoc/clean/mod.rs28
-rw-r--r--src/librustdoc/clean/types.rs12
-rw-r--r--src/librustdoc/clean/utils.rs3
-rw-r--r--src/librustdoc/core.rs7
-rw-r--r--src/librustdoc/formats/cache.rs15
-rw-r--r--src/librustdoc/html/format.rs2
-rw-r--r--src/librustdoc/html/highlight.rs4
-rw-r--r--src/librustdoc/html/render/mod.rs6
-rw-r--r--src/librustdoc/html/sources.rs9
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css95
-rw-r--r--src/librustdoc/html/static/css/themes/ayu.css12
-rw-r--r--src/librustdoc/html/static/css/themes/dark.css14
-rw-r--r--src/librustdoc/html/static/css/themes/light.css14
-rw-r--r--src/librustdoc/html/static/js/main.js2
-rw-r--r--src/librustdoc/html/templates/page.html34
-rw-r--r--src/librustdoc/html/templates/print_item.html6
-rw-r--r--src/librustdoc/passes/check_doc_test_visibility.rs4
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs6
-rw-r--r--src/librustdoc/passes/strip_hidden.rs1
-rw-r--r--src/librustdoc/passes/strip_private.rs4
-rw-r--r--src/librustdoc/passes/stripper.rs62
-rw-r--r--src/librustdoc/visit_ast.rs34
-rw-r--r--src/librustdoc/visit_lib.rs110
m---------src/llvm-project0
-rw-r--r--src/rustdoc-json-types/lib.rs5
-rw-r--r--src/test/codegen/issue-103285-ptr-addr-overflow-check.rs16
-rw-r--r--src/test/codegen/match-optimized.rs60
-rw-r--r--src/test/codegen/match-unoptimized.rs23
-rw-r--r--src/test/codegen/match.rs29
-rw-r--r--src/test/codegen/mir-inlined-line-numbers.rs25
-rw-r--r--src/test/mir-opt/building/enum_cast.bar.built.after.mir (renamed from src/test/mir-opt/enum_cast.bar.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/building/enum_cast.boo.built.after.mir (renamed from src/test/mir-opt/enum_cast.boo.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/building/enum_cast.droppy.built.after.mir (renamed from src/test/mir-opt/enum_cast.droppy.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/building/enum_cast.foo.built.after.mir (renamed from src/test/mir-opt/enum_cast.foo.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/building/enum_cast.rs (renamed from src/test/mir-opt/enum_cast.rs)8
-rw-r--r--src/test/mir-opt/building/issue-101867.rs (renamed from src/test/mir-opt/issue-101867.rs)2
-rw-r--r--src/test/mir-opt/building/issue-49232.rs (renamed from src/test/mir-opt/issue-49232.rs)2
-rw-r--r--src/test/mir-opt/building/issue_101867.main.built.after.mir (renamed from src/test/mir-opt/issue_101867.main.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/building/issue_49232.main.built.after.mir (renamed from src/test/mir-opt/issue_49232.main.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/building/match_false_edges.full_tested_match.built.after.mir (renamed from src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir)29
-rw-r--r--src/test/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir (renamed from src/test/mir-opt/match_false_edges.full_tested_match2.PromoteTemps.before.mir)22
-rw-r--r--src/test/mir-opt/building/match_false_edges.main.built.after.mir (renamed from src/test/mir-opt/match_false_edges.main.PromoteTemps.before.mir)73
-rw-r--r--src/test/mir-opt/building/match_false_edges.rs (renamed from src/test/mir-opt/match_false_edges.rs)6
-rw-r--r--src/test/mir-opt/building/receiver-ptr-mutability.rs (renamed from src/test/mir-opt/receiver-ptr-mutability.rs)2
-rw-r--r--src/test/mir-opt/building/receiver_ptr_mutability.main.built.after.mir (renamed from src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/building/simple-match.rs (renamed from src/test/mir-opt/simple-match.rs)2
-rw-r--r--src/test/mir-opt/building/simple_match.match_bool.built.after.mir (renamed from src/test/mir-opt/simple_match.match_bool.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir (renamed from src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/building/storage_live_dead_in_statics.rs (renamed from src/test/mir-opt/storage_live_dead_in_statics.rs)2
-rw-r--r--src/test/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir (renamed from src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir (renamed from src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/building/uniform_array_move_out.rs (renamed from src/test/mir-opt/uniform_array_move_out.rs)4
-rw-r--r--src/test/mir-opt/const-promotion-extern-static.rs2
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.BOP.built.after.mir (renamed from src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/graphviz.main.built.after.dot (renamed from src/test/mir-opt/graphviz.main.mir_map.0.dot)0
-rw-r--r--src/test/mir-opt/graphviz.rs2
-rw-r--r--src/test/mir-opt/issue-72181-1.rs4
-rw-r--r--src/test/mir-opt/issue-72181.rs6
-rw-r--r--src/test/mir-opt/issue-91633.rs8
-rw-r--r--src/test/mir-opt/issue-99325.rs2
-rw-r--r--src/test/mir-opt/issue_72181.bar.built.after.mir (renamed from src/test/mir-opt/issue_72181.bar.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/issue_72181.foo.built.after.mir (renamed from src/test/mir-opt/issue_72181.foo.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/issue_72181.main.built.after.mir (renamed from src/test/mir-opt/issue_72181.main.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/issue_72181_1.f.built.after.mir (renamed from src/test/mir-opt/issue_72181_1.f.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/issue_72181_1.main.built.after.mir (renamed from src/test/mir-opt/issue_72181_1.main.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/issue_91633.bar.built.after.mir (renamed from src/test/mir-opt/issue_91633.bar.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/issue_91633.foo.built.after.mir (renamed from src/test/mir-opt/issue_91633.foo.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/issue_91633.fun.built.after.mir (renamed from src/test/mir-opt/issue_91633.fun.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/issue_91633.hey.built.after.mir (renamed from src/test/mir-opt/issue_91633.hey.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/issue_99325.main.built.after.mir (renamed from src/test/mir-opt/issue_99325.main.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/spanview-block.rs2
-rw-r--r--src/test/mir-opt/spanview-statement.rs2
-rw-r--r--src/test/mir-opt/spanview-terminator.rs2
-rw-r--r--src/test/mir-opt/spanview_block.main.built.after.html (renamed from src/test/mir-opt/spanview_block.main.mir_map.0.html)2
-rw-r--r--src/test/mir-opt/spanview_statement.main.built.after.html (renamed from src/test/mir-opt/spanview_statement.main.mir_map.0.html)2
-rw-r--r--src/test/mir-opt/spanview_terminator.main.built.after.html (renamed from src/test/mir-opt/spanview_terminator.main.mir_map.0.html)2
-rw-r--r--src/test/mir-opt/unusual-item-types.rs6
-rw-r--r--src/test/mir-opt/unusual_item_types.E-V-{constant#0}.built.after.mir (renamed from src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.built.after.mir (renamed from src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir (renamed from src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.mir)2
-rw-r--r--src/test/run-make-fulldeps/foreign-rust-exceptions/Makefile11
-rw-r--r--src/test/run-make-fulldeps/foreign-rust-exceptions/bar.rs7
-rw-r--r--src/test/run-make-fulldeps/foreign-rust-exceptions/foo.rs13
-rw-r--r--src/test/run-make-fulldeps/obtain-borrowck/driver.rs12
-rw-r--r--src/test/run-make/test-benches/Makefile11
-rw-r--r--src/test/run-make/test-benches/smokebench.rs14
-rw-r--r--src/test/rustdoc-gui/source-code-page.goml44
-rw-r--r--src/test/rustdoc-js/reexport.js17
-rw-r--r--src/test/rustdoc-js/reexport.rs11
-rw-r--r--src/test/rustdoc-json/reexport/reexport_method_from_private_module.rs28
-rw-r--r--src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr12
-rw-r--r--src/test/rustdoc/auxiliary/incoherent-impl-types.rs7
-rw-r--r--src/test/rustdoc/auxiliary/masked.rs4
-rw-r--r--src/test/rustdoc/auxiliary/reexport-doc-aux.rs5
-rw-r--r--src/test/rustdoc/masked.rs1
-rw-r--r--src/test/rustdoc/reexport-doc.rs8
-rw-r--r--src/test/rustdoc/rustc-incoherent-impls.rs28
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr10
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-invariant.rs2
-rw-r--r--src/test/ui/async-await/in-trait/async-associated-types.rs24
-rw-r--r--src/test/ui/async-await/in-trait/async-associated-types.stderr57
-rw-r--r--src/test/ui/async-await/in-trait/async-associated-types2.rs30
-rw-r--r--src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs21
-rw-r--r--src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr17
-rw-r--r--src/test/ui/async-await/in-trait/async-example-desugared-boxed.rs24
-rw-r--r--src/test/ui/async-await/in-trait/async-example-desugared-in-trait.rs21
-rw-r--r--src/test/ui/async-await/in-trait/async-example-desugared.rs23
-rw-r--r--src/test/ui/async-await/in-trait/async-example.rs32
-rw-r--r--src/test/ui/async-await/in-trait/async-generics-and-bounds.rs21
-rw-r--r--src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr37
-rw-r--r--src/test/ui/async-await/in-trait/async-generics.rs18
-rw-r--r--src/test/ui/async-await/in-trait/async-generics.stderr37
-rw-r--r--src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs20
-rw-r--r--src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr23
-rw-r--r--src/test/ui/async-await/in-trait/async-lifetimes.rs18
-rw-r--r--src/test/ui/async-await/in-trait/async-lifetimes.stderr23
-rw-r--r--src/test/ui/async-await/in-trait/async-recursive-generic.rs21
-rw-r--r--src/test/ui/async-await/in-trait/async-recursive-generic.stderr12
-rw-r--r--src/test/ui/async-await/in-trait/async-recursive.rs21
-rw-r--r--src/test/ui/async-await/in-trait/async-recursive.stderr12
-rw-r--r--src/test/ui/async-await/in-trait/fn-not-async-err.rs17
-rw-r--r--src/test/ui/async-await/in-trait/fn-not-async-err.stderr17
-rw-r--r--src/test/ui/async-await/in-trait/fn-not-async-err2.rs21
-rw-r--r--src/test/ui/async-await/in-trait/fn-not-async-err2.stderr12
-rw-r--r--src/test/ui/async-await/issue-98634.rs50
-rw-r--r--src/test/ui/async-await/issue-98634.stderr60
-rw-r--r--src/test/ui/async-await/issues/issue-72312.stderr13
-rw-r--r--src/test/ui/borrowck/issue-103624.rs31
-rw-r--r--src/test/ui/borrowck/issue-103624.stderr35
-rw-r--r--src/test/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs19
-rw-r--r--src/test/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr49
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-1.rs4
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-1.stderr28
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-2.rs15
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-2.stderr6
-rw-r--r--src/test/ui/coercion/coerce-block-tail-26978.rs11
-rw-r--r--src/test/ui/coercion/coerce-block-tail-26978.stderr16
-rw-r--r--src/test/ui/coercion/coerce-block-tail-57749.rs35
-rw-r--r--src/test/ui/coercion/coerce-block-tail-57749.stderr14
-rw-r--r--src/test/ui/coercion/coerce-block-tail-83783.rs13
-rw-r--r--src/test/ui/coercion/coerce-block-tail-83783.stderr12
-rw-r--r--src/test/ui/coercion/coerce-block-tail-83850.rs7
-rw-r--r--src/test/ui/coercion/coerce-block-tail-83850.stderr19
-rw-r--r--src/test/ui/coercion/coerce-block-tail.rs6
-rw-r--r--src/test/ui/coercion/coerce-block-tail.stderr16
-rw-r--r--src/test/ui/coercion/issue-36007.rs20
-rw-r--r--src/test/ui/coherence/coherence-default-trait-impl.stderr12
-rw-r--r--src/test/ui/coherence/strict-coherence-needs-negative-coherence.rs7
-rw-r--r--src/test/ui/coherence/strict-coherence-needs-negative-coherence.stderr10
-rw-r--r--src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr12
-rw-r--r--src/test/ui/dyn-star/no-explicit-dyn-star-cast.rs13
-rw-r--r--src/test/ui/dyn-star/no-explicit-dyn-star-cast.stderr28
-rw-r--r--src/test/ui/dyn-star/no-explicit-dyn-star.rs8
-rw-r--r--src/test/ui/dyn-star/no-explicit-dyn-star.stderr9
-rw-r--r--src/test/ui/error-codes/E0045.stderr4
-rw-r--r--src/test/ui/error-codes/E0199.stderr6
-rw-r--r--src/test/ui/error-codes/E0200.stderr6
-rw-r--r--src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.rs6
-rw-r--r--src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr15
-rw-r--r--src/test/ui/generic-associated-types/issue-87258_a.stderr2
-rw-r--r--src/test/ui/impl-trait/impl-fn-hrtb-bounds-2.rs8
-rw-r--r--src/test/ui/impl-trait/impl-fn-hrtb-bounds-2.stderr11
-rw-r--r--src/test/ui/impl-trait/impl-fn-hrtb-bounds.rs24
-rw-r--r--src/test/ui/impl-trait/impl-fn-hrtb-bounds.stderr51
-rw-r--r--src/test/ui/impl-trait/impl-fn-parsing-ambiguities.rs15
-rw-r--r--src/test/ui/impl-trait/impl-fn-parsing-ambiguities.stderr26
-rw-r--r--src/test/ui/impl-trait/impl-fn-predefined-lifetimes.rs15
-rw-r--r--src/test/ui/impl-trait/impl-fn-predefined-lifetimes.stderr24
-rw-r--r--src/test/ui/impl-trait/impl_fn_associativity.rs26
-rw-r--r--src/test/ui/impl-trait/in-trait/early.rs23
-rw-r--r--src/test/ui/impl-trait/nested_impl_trait.rs4
-rw-r--r--src/test/ui/impl-trait/nested_impl_trait.stderr22
-rw-r--r--src/test/ui/impl-trait/where-allowed.rs7
-rw-r--r--src/test/ui/impl-trait/where-allowed.stderr98
-rw-r--r--src/test/ui/let-else/let-else-irrefutable.rs8
-rw-r--r--src/test/ui/let-else/let-else-irrefutable.stderr15
-rw-r--r--src/test/ui/lexical-scopes.stderr2
-rw-r--r--src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs6
-rw-r--r--src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr14
-rw-r--r--src/test/ui/lint/inline-trait-and-foreign-items.stderr2
-rw-r--r--src/test/ui/lint/issue-103317.fixed14
-rw-r--r--src/test/ui/lint/issue-103317.rs14
-rw-r--r--src/test/ui/lint/issue-103317.stderr17
-rw-r--r--src/test/ui/lint/no-coverage.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr15
-rw-r--r--src/test/ui/nll/user-annotations/adt-nullary-enums.stderr16
-rw-r--r--src/test/ui/privacy/access_levels.rs75
-rw-r--r--src/test/ui/privacy/access_levels.stderr134
-rw-r--r--src/test/ui/privacy/effective_visibilities.rs75
-rw-r--r--src/test/ui/privacy/effective_visibilities.stderr134
-rw-r--r--src/test/ui/resolve/issue-23305.rs2
-rw-r--r--src/test/ui/resolve/issue-23305.stderr16
-rw-r--r--src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr16
-rw-r--r--src/test/ui/resolve/resolve-self-in-impl.rs9
-rw-r--r--src/test/ui/resolve/resolve-self-in-impl.stderr74
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/issue-103677.rs5
-rw-r--r--src/test/ui/save-analysis/issue-68621.stderr2
-rw-r--r--src/test/ui/span/issue-35987.stderr3
-rw-r--r--src/test/ui/suggestions/issue-102354.rs10
-rw-r--r--src/test/ui/suggestions/issue-102354.stderr24
-rw-r--r--src/test/ui/traits/safety-trait-impl-cc.stderr6
-rw-r--r--src/test/ui/traits/safety-trait-impl.stderr12
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-101750.rs37
-rw-r--r--src/test/ui/type/issue-94187-verbose-type-name.rs16
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/copy_iterator.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/default_union_representation.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs26
-rw-r--r--src/tools/clippy/clippy_lints/src/derivable_impls.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/derive.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/doc.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/empty_enum.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/enum_variants.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/escape.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/exhaustive_items.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/fallible_impl_from.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/format_args.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/from_over_into.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/must_use.rs24
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/result.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_hasher.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/inherent_to_string.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/large_enum_variant.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/let_if_seq.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_all.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_pedantic.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_style.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_retain.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_doc.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_inline.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/mut_key.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/new_without_default.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/op_ref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/question_mark.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/same_name_method.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/self_named_constructors.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/trailing_empty_array.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs165
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/utils.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/types/mod.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs18
-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.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_peekable.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_self.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/unwrap_in_result.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/use_self.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/useless_conversion.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/wildcard_imports.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs10
-rw-r--r--src/tools/compiletest/src/common.rs8
-rw-r--r--src/tools/compiletest/src/main.rs8
-rw-r--r--src/tools/compiletest/src/runtest.rs35
-rw-r--r--src/tools/miri/.github/workflows/ci.yml12
-rwxr-xr-xsrc/tools/miri/ci.sh1
-rw-r--r--src/tools/miri/src/lib.rs6
-rw-r--r--src/tools/miri/src/machine.rs30
-rw-r--r--src/tools/miri/src/shims/intrinsics/mod.rs13
-rw-r--r--src/tools/miri/src/shims/unix/linux/sync.rs40
-rw-r--r--src/tools/miri/src/shims/unix/macos/foreign_items.rs5
-rw-r--r--src/tools/miri/src/shims/unix/sync.rs3
-rw-r--r--src/tools/miri/src/shims/windows/dlsym.rs15
-rw-r--r--src/tools/miri/src/shims/windows/sync.rs106
-rw-r--r--src/tools/miri/src/stacked_borrows/mod.rs7
-rw-r--r--src/tools/miri/tests/fail/data_race/stack_pop_race.rs1
-rw-r--r--src/tools/miri/tests/fail/panic/no_std.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond_isolated.rs82
-rw-r--r--src/tools/miri/tests/pass-dep/shims/libc-misc.rs22
-rw-r--r--src/tools/miri/tests/pass-dep/shims/pthreads.rs20
-rw-r--r--src/tools/miri/tests/pass/concurrency/channels.rs1
-rw-r--r--src/tools/miri/tests/pass/concurrency/spin_loops_nopreempt.rs1
-rw-r--r--src/tools/miri/tests/pass/concurrency/sync.rs21
-rw-r--r--src/tools/miri/tests/pass/concurrency/sync_nopreempt.rs2
-rw-r--r--src/tools/miri/tests/pass/concurrency/thread_park_isolated.rs12
-rw-r--r--src/tools/miri/tests/pass/no_std.rs2
-rw-r--r--src/tools/miri/tests/pass/shims/env/current_exe.rs2
-rw-r--r--src/tools/miri/tests/pass/shims/ptr_mask.rs18
-rw-r--r--src/tools/miri/tests/pass/shims/sleep_long.rs1
-rw-r--r--src/tools/miri/tests/pass/threadleak_ignored.rs4
-rw-r--r--src/version2
-rwxr-xr-xx6
-rwxr-xr-xx.ps113
511 files changed, 5779 insertions, 2705 deletions
diff --git a/RELEASES.md b/RELEASES.md
index 694bd09658f..a3df56f1d2a 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,106 @@
+Version 1.65.0 (2022-11-03)
+==========================
+
+Language
+--------
+- [Error on `as` casts of enums with `#[non_exhaustive]` variants](https://github.com/rust-lang/rust/pull/92744/)
+- [Stabilize `let else`](https://github.com/rust-lang/rust/pull/93628/)
+- [Stabilize generic associated types (GATs)](https://github.com/rust-lang/rust/pull/96709/)
+- [Add lints `let_underscore_drop`, `let_underscore_lock`, and `let_underscore_must_use` from Clippy](https://github.com/rust-lang/rust/pull/97739/)
+- [Stabilize `break`ing from arbitrary labeled blocks ("label-break-value")](https://github.com/rust-lang/rust/pull/99332/)
+- [Uninitialized integers, floats, and raw pointers are now considered immediate UB](https://github.com/rust-lang/rust/pull/98919/).
+  Usage of `MaybeUninit` is the correct way to work with uninitialized memory.
+- [Stabilize raw-dylib for Windows x86_64, aarch64, and thumbv7a](https://github.com/rust-lang/rust/pull/99916/)
+- [Do not allow `Drop` impl on foreign ADTs](https://github.com/rust-lang/rust/pull/99576/)
+
+Compiler
+--------
+- [Stabilize -Csplit-debuginfo on Linux](https://github.com/rust-lang/rust/pull/98051/)
+- [Use niche-filling optimization even when multiple variants have data](https://github.com/rust-lang/rust/pull/94075/)
+- [Associated type projections are now verified to be well-formed prior to resolving the underlying type](https://github.com/rust-lang/rust/pull/99217/#issuecomment-1209365630)
+- [Stringify non-shorthand visibility correctly](https://github.com/rust-lang/rust/pull/100350/)
+- [Normalize struct field types when unsizing](https://github.com/rust-lang/rust/pull/101831/)
+- [Update to LLVM 15](https://github.com/rust-lang/rust/pull/99464/)
+- [Fix aarch64 call abi to correctly zeroext when needed](https://github.com/rust-lang/rust/pull/97800/)
+- [debuginfo: Generalize C++-like encoding for enums](https://github.com/rust-lang/rust/pull/98393/)
+- [Add `special_module_name` lint](https://github.com/rust-lang/rust/pull/94467/)
+- [Add support for generating unique profraw files by default when using `-C instrument-coverage`](https://github.com/rust-lang/rust/pull/100384/)
+- [Allow dynamic linking for iOS/tvOS targets](https://github.com/rust-lang/rust/pull/100636/)
+
+New targets:
+
+- [Add armv4t-none-eabi as a tier 3 target](https://github.com/rust-lang/rust/pull/100244/)
+- [Add powerpc64-unknown-openbsd and riscv64-unknown-openbsd as tier 3 targets](https://github.com/rust-lang/rust/pull/101025/)
+  - Refer to Rust's [platform support page][platform-support-doc] for more
+    information on Rust's tiered platform support.
+
+Libraries
+---------
+
+- [Don't generate `PartialEq::ne` in derive(PartialEq)](https://github.com/rust-lang/rust/pull/98655/)
+- [Windows RNG: Use `BCRYPT_RNG_ALG_HANDLE` by default](https://github.com/rust-lang/rust/pull/101325/)
+- [Forbid mixing `System` with direct system allocator calls](https://github.com/rust-lang/rust/pull/101394/)
+- [Document no support for writing to non-blocking stdio/stderr](https://github.com/rust-lang/rust/pull/101416/)
+- [`std::layout::Layout` size must not overflow `isize::MAX` when rounded up to `align`](https://github.com/rust-lang/rust/pull/95295)
+  This also changes the safety conditions on `Layout::from_size_align_unchecked`.
+
+Stabilized APIs
+---------------
+
+- [`std::backtrace::Backtrace`](https://doc.rust-lang.org/stable/std/backtrace/struct.Backtrace.html)
+- [`Bound::as_ref`](https://doc.rust-lang.org/stable/std/ops/enum.Bound.html#method.as_ref)
+- [`std::io::read_to_string`](https://doc.rust-lang.org/stable/std/io/fn.read_to_string.html)
+- [`<*const T>::cast_mut`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.cast_mut)
+- [`<*mut T>::cast_const`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.cast_const)
+
+These APIs are now stable in const contexts:
+
+- [`<*const T>::offset_from`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from)
+- [`<*mut T>::offset_from`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from)
+
+Cargo
+-----
+
+- [Apply GitHub fast path even for partial hashes](https://github.com/rust-lang/cargo/pull/10807/)
+- [Do not add home bin path to PATH if it's already there](https://github.com/rust-lang/cargo/pull/11023/)
+- [Take priority into account within the pending queue](https://github.com/rust-lang/cargo/pull/11032/).
+  This slightly optimizes job scheduling by Cargo, with typically small improvements on larger crate graph builds.
+
+Compatibility Notes
+-------------------
+
+- [`std::layout::Layout` size must not overflow `isize::MAX` when rounded up to `align`](https://github.com/rust-lang/rust/pull/95295).
+  This also changes the safety conditions on `Layout::from_size_align_unchecked`.
+- [`PollFn` now only implements `Unpin` if the closure is `Unpin`](https://github.com/rust-lang/rust/pull/102737).
+  This is a possible breaking change if users were relying on the blanket unpin implementation.
+  See discussion on the PR for details of why this change was made.
+- [Drop ExactSizeIterator impl from std::char::EscapeAscii](https://github.com/rust-lang/rust/pull/99880)
+  This is a backwards-incompatible change to the standard library's surface
+  area, but is unlikely to affect real world usage.
+- [Do not consider a single repeated lifetime eligible for elision in the return type](https://github.com/rust-lang/rust/pull/103450)
+  This behavior was unintentionally changed in 1.64.0, and this release reverts that change by making this an error again.
+- [Reenable disabled early syntax gates as future-incompatibility lints](https://github.com/rust-lang/rust/pull/99935/)
+- [Update the minimum external LLVM to 13](https://github.com/rust-lang/rust/pull/100460/)
+- [Don't duplicate file descriptors into stdio fds](https://github.com/rust-lang/rust/pull/101426/)
+- [Sunset RLS](https://github.com/rust-lang/rust/pull/100863/)
+- [Deny usage of `#![cfg_attr(..., crate_type = ...)]` to set the crate type](https://github.com/rust-lang/rust/pull/99784/)
+  This strengthens the forward compatibility lint deprecated_cfg_attr_crate_type_name to deny.
+- [`llvm-has-rust-patches` allows setting the build system to treat the LLVM as having Rust-specific patches](https://github.com/rust-lang/rust/pull/101072)
+  This option may need to be set for distributions that are building Rust with a patched LLVM via `llvm-config`, not the built-in LLVM.
+
+Internal Changes
+----------------
+
+These changes do not affect any public interfaces of Rust, but they represent
+significant improvements to the performance or internals of rustc and related
+tools.
+
+- [Add `x.sh` and `x.ps1` shell scripts](https://github.com/rust-lang/rust/pull/99992/)
+- [compiletest: use target cfg instead of hard-coded tables](https://github.com/rust-lang/rust/pull/100260/)
+- [Use object instead of LLVM for reading bitcode from rlibs](https://github.com/rust-lang/rust/pull/98100/)
+- [Enable MIR inlining for optimized compilations](https://github.com/rust-lang/rust/pull/91743)
+  This provides a 3-10% improvement in compiletimes for real world crates. See [perf results](https://perf.rust-lang.org/compare.html?start=aedf78e56b2279cc869962feac5153b6ba7001ed&end=0075bb4fad68e64b6d1be06bf2db366c30bc75e1&stat=instructions:u).
+
 Version 1.64.0 (2022-09-22)
 ===========================
 
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index 6d716796343..f1851d7b40e 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -112,19 +112,19 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
 
     fn visit_nested_item(&mut self, item: ItemId) {
         debug!("visit_nested_item: {:?}", item);
-        self.insert_nested(item.def_id.def_id);
+        self.insert_nested(item.owner_id.def_id);
     }
 
     fn visit_nested_trait_item(&mut self, item_id: TraitItemId) {
-        self.insert_nested(item_id.def_id.def_id);
+        self.insert_nested(item_id.owner_id.def_id);
     }
 
     fn visit_nested_impl_item(&mut self, item_id: ImplItemId) {
-        self.insert_nested(item_id.def_id.def_id);
+        self.insert_nested(item_id.owner_id.def_id);
     }
 
     fn visit_nested_foreign_item(&mut self, foreign_id: ForeignItemId) {
-        self.insert_nested(foreign_id.def_id.def_id);
+        self.insert_nested(foreign_id.owner_id.def_id);
     }
 
     fn visit_nested_body(&mut self, id: BodyId) {
@@ -143,7 +143,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
 
     #[instrument(level = "debug", skip(self))]
     fn visit_item(&mut self, i: &'hir Item<'hir>) {
-        debug_assert_eq!(i.def_id, self.owner);
+        debug_assert_eq!(i.owner_id, self.owner);
         self.with_parent(i.hir_id(), |this| {
             if let ItemKind::Struct(ref struct_def, _) = i.kind {
                 // If this is a tuple or unit-like struct, register the constructor.
@@ -157,7 +157,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
 
     #[instrument(level = "debug", skip(self))]
     fn visit_foreign_item(&mut self, fi: &'hir ForeignItem<'hir>) {
-        debug_assert_eq!(fi.def_id, self.owner);
+        debug_assert_eq!(fi.owner_id, self.owner);
         self.with_parent(fi.hir_id(), |this| {
             intravisit::walk_foreign_item(this, fi);
         });
@@ -176,7 +176,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
 
     #[instrument(level = "debug", skip(self))]
     fn visit_trait_item(&mut self, ti: &'hir TraitItem<'hir>) {
-        debug_assert_eq!(ti.def_id, self.owner);
+        debug_assert_eq!(ti.owner_id, self.owner);
         self.with_parent(ti.hir_id(), |this| {
             intravisit::walk_trait_item(this, ti);
         });
@@ -184,7 +184,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
 
     #[instrument(level = "debug", skip(self))]
     fn visit_impl_item(&mut self, ii: &'hir ImplItem<'hir>) {
-        debug_assert_eq!(ii.def_id, self.owner);
+        debug_assert_eq!(ii.owner_id, self.owner);
         self.with_parent(ii.hir_id(), |this| {
             intravisit::walk_impl_item(this, ii);
         });
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 2117006df10..76316a574ac 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -178,7 +178,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
     pub(super) fn lower_item_ref(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {
         let mut node_ids =
-            smallvec![hir::ItemId { def_id: hir::OwnerId { def_id: self.local_def_id(i.id) } }];
+            smallvec![hir::ItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } }];
         if let ItemKind::Use(ref use_tree) = &i.kind {
             self.lower_item_id_use_tree(use_tree, i.id, &mut node_ids);
         }
@@ -195,7 +195,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             UseTreeKind::Nested(ref nested_vec) => {
                 for &(ref nested, id) in nested_vec {
                     vec.push(hir::ItemId {
-                        def_id: hir::OwnerId { def_id: self.local_def_id(id) },
+                        owner_id: hir::OwnerId { def_id: self.local_def_id(id) },
                     });
                     self.lower_item_id_use_tree(nested, id, vec);
                 }
@@ -206,7 +206,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     iter::zip(self.expect_full_res_from_use(base_id).skip(1), &[id1, id2])
                 {
                     vec.push(hir::ItemId {
-                        def_id: hir::OwnerId { def_id: self.local_def_id(id) },
+                        owner_id: hir::OwnerId { def_id: self.local_def_id(id) },
                     });
                 }
             }
@@ -220,7 +220,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let attrs = self.lower_attrs(hir_id, &i.attrs);
         let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, vis_span, &i.kind);
         let item = hir::Item {
-            def_id: hir_id.expect_owner(),
+            owner_id: hir_id.expect_owner(),
             ident: self.lower_ident(ident),
             kind,
             vis_span,
@@ -562,7 +562,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         }
 
                         let item = hir::Item {
-                            def_id: hir::OwnerId { def_id: new_id },
+                            owner_id: hir::OwnerId { def_id: new_id },
                             ident: this.lower_ident(ident),
                             kind,
                             vis_span,
@@ -640,7 +640,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         }
 
                         let item = hir::Item {
-                            def_id: hir::OwnerId { def_id: new_hir_id },
+                            owner_id: hir::OwnerId { def_id: new_hir_id },
                             ident: this.lower_ident(ident),
                             kind,
                             vis_span,
@@ -660,10 +660,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
     fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
         let hir_id = self.lower_node_id(i.id);
-        let def_id = hir_id.expect_owner();
+        let owner_id = hir_id.expect_owner();
         self.lower_attrs(hir_id, &i.attrs);
         let item = hir::ForeignItem {
-            def_id,
+            owner_id,
             ident: self.lower_ident(i.ident),
             kind: match i.kind {
                 ForeignItemKind::Fn(box Fn { ref sig, ref generics, .. }) => {
@@ -702,7 +702,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
     fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef {
         hir::ForeignItemRef {
-            id: hir::ForeignItemId { def_id: hir::OwnerId { def_id: self.local_def_id(i.id) } },
+            id: hir::ForeignItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } },
             ident: self.lower_ident(i.ident),
             span: self.lower_span(i.span),
         }
@@ -845,7 +845,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
         self.lower_attrs(hir_id, &i.attrs);
         let item = hir::TraitItem {
-            def_id: trait_item_def_id,
+            owner_id: trait_item_def_id,
             ident: self.lower_ident(i.ident),
             generics,
             kind,
@@ -864,7 +864,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             }
             AssocItemKind::MacCall(..) => unimplemented!(),
         };
-        let id = hir::TraitItemId { def_id: hir::OwnerId { def_id: self.local_def_id(i.id) } };
+        let id = hir::TraitItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } };
         hir::TraitItemRef {
             id,
             ident: self.lower_ident(i.ident),
@@ -931,7 +931,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let hir_id = self.lower_node_id(i.id);
         self.lower_attrs(hir_id, &i.attrs);
         let item = hir::ImplItem {
-            def_id: hir_id.expect_owner(),
+            owner_id: hir_id.expect_owner(),
             ident: self.lower_ident(i.ident),
             generics,
             kind,
@@ -944,7 +944,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
     fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef {
         hir::ImplItemRef {
-            id: hir::ImplItemId { def_id: hir::OwnerId { def_id: self.local_def_id(i.id) } },
+            id: hir::ImplItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } },
             ident: self.lower_ident(i.ident),
             span: self.lower_span(i.span),
             kind: match &i.kind {
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 427b71722ab..ff29d15f1b5 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1574,7 +1574,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
         // `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
         hir::TyKind::OpaqueDef(
-            hir::ItemId { def_id: hir::OwnerId { def_id: opaque_ty_def_id } },
+            hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } },
             lifetimes,
             in_trait,
         )
@@ -1593,7 +1593,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         // Generate an `type Foo = impl Trait;` declaration.
         trace!("registering opaque type with id {:#?}", opaque_ty_id);
         let opaque_ty_item = hir::Item {
-            def_id: hir::OwnerId { def_id: opaque_ty_id },
+            owner_id: hir::OwnerId { def_id: opaque_ty_id },
             ident: Ident::empty(),
             kind: opaque_ty_item_kind,
             vis_span: self.lower_span(span.shrink_to_lo()),
@@ -2044,7 +2044,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         // async fn, so the *type parameters* are inherited.  It's
         // only the lifetime parameters that we must supply.
         let opaque_ty_ref = hir::TyKind::OpaqueDef(
-            hir::ItemId { def_id: hir::OwnerId { def_id: opaque_ty_def_id } },
+            hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } },
             generic_args,
             in_trait,
         );
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 888776cccac..c6955741fd4 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -191,7 +191,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
                 }
                 GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args {
-                    ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data),
+                    ParenthesizedGenericArgs::Ok => {
+                        self.lower_parenthesized_parameter_data(data, itctx)
+                    }
                     ParenthesizedGenericArgs::Err => {
                         // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
                         let sub = if !data.inputs.is_empty() {
@@ -344,6 +346,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn lower_parenthesized_parameter_data(
         &mut self,
         data: &ParenthesizedArgs,
+        itctx: &ImplTraitContext,
     ) -> (GenericArgsCtor<'hir>, bool) {
         // Switch to `PassThrough` mode for anonymous lifetimes; this
         // means that we permit things like `&Ref<T>`, where `Ref` has
@@ -355,6 +358,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             self.lower_ty_direct(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam))
         }));
         let output_ty = match output {
+            // Only allow `impl Trait` in return position. i.e.:
+            // ```rust
+            // fn f(_: impl Fn() -> impl Debug) -> impl Fn() -> impl Debug
+            // //      disallowed --^^^^^^^^^^        allowed --^^^^^^^^^^
+            // ```
+            FnRetTy::Ty(ty)
+                if matches!(itctx, ImplTraitContext::ReturnPositionOpaqueTy { .. })
+                    && self.tcx.features().impl_trait_in_fn_trait_return =>
+            {
+                self.lower_ty(&ty, itctx)
+            }
             FnRetTy::Ty(ty) => {
                 self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn))
             }
diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs
index 58aeb43ef97..df04128135b 100644
--- a/compiler/rustc_borrowck/src/constraints/mod.rs
+++ b/compiler/rustc_borrowck/src/constraints/mod.rs
@@ -92,7 +92,7 @@ pub struct OutlivesConstraint<'tcx> {
     pub span: Span,
 
     /// What caused this constraint?
-    pub category: ConstraintCategory,
+    pub category: ConstraintCategory<'tcx>,
 
     /// Variance diagnostic information
     pub variance_info: VarianceDiagInfo<'tcx>,
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 3f5d9fb6206..583bc2e281d 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -983,7 +983,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         err: &mut Diagnostic,
         location: Location,
         issued_borrow: &BorrowData<'tcx>,
-        explanation: BorrowExplanation,
+        explanation: BorrowExplanation<'tcx>,
     ) {
         let used_in_call = matches!(
             explanation,
@@ -1333,7 +1333,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         borrow: &BorrowData<'tcx>,
         drop_span: Span,
         borrow_spans: UseSpans<'tcx>,
-        explanation: BorrowExplanation,
+        explanation: BorrowExplanation<'tcx>,
     ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
         debug!(
             "report_local_value_does_not_live_long_enough(\
@@ -1539,7 +1539,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         drop_span: Span,
         borrow_spans: UseSpans<'tcx>,
         proper_span: Span,
-        explanation: BorrowExplanation,
+        explanation: BorrowExplanation<'tcx>,
     ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
         if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } =
             explanation
@@ -1653,7 +1653,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         borrow: &BorrowData<'tcx>,
         borrow_span: Span,
         return_span: Span,
-        category: ConstraintCategory,
+        category: ConstraintCategory<'tcx>,
         opt_place_desc: Option<&String>,
     ) -> Option<DiagnosticBuilder<'cx, ErrorGuaranteed>> {
         let return_kind = match category {
@@ -1748,7 +1748,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         use_span: UseSpans<'tcx>,
         var_span: Span,
         fr_name: &RegionName,
-        category: ConstraintCategory,
+        category: ConstraintCategory<'tcx>,
         constraint_span: Span,
         captured_var: &str,
     ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index 545237bb392..582d683dd35 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -21,7 +21,7 @@ use crate::{
 use super::{find_use, RegionName, UseSpans};
 
 #[derive(Debug)]
-pub(crate) enum BorrowExplanation {
+pub(crate) enum BorrowExplanation<'tcx> {
     UsedLater(LaterUseKind, Span, Option<Span>),
     UsedLaterInLoop(LaterUseKind, Span, Option<Span>),
     UsedLaterWhenDropped {
@@ -30,7 +30,7 @@ pub(crate) enum BorrowExplanation {
         should_note_order: bool,
     },
     MustBeValidFor {
-        category: ConstraintCategory,
+        category: ConstraintCategory<'tcx>,
         from_closure: bool,
         span: Span,
         region_name: RegionName,
@@ -49,7 +49,7 @@ pub(crate) enum LaterUseKind {
     Other,
 }
 
-impl<'tcx> BorrowExplanation {
+impl<'tcx> BorrowExplanation<'tcx> {
     pub(crate) fn is_explained(&self) -> bool {
         !matches!(self, BorrowExplanation::Unexplained)
     }
@@ -284,7 +284,7 @@ impl<'tcx> BorrowExplanation {
     fn add_lifetime_bound_suggestion_to_diagnostic(
         &self,
         err: &mut Diagnostic,
-        category: &ConstraintCategory,
+        category: &ConstraintCategory<'tcx>,
         span: Span,
         region_name: &RegionName,
     ) {
@@ -316,7 +316,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         &self,
         borrow_region: RegionVid,
         outlived_region: RegionVid,
-    ) -> (ConstraintCategory, bool, Span, Option<RegionName>, Vec<ExtraConstraintInfo>) {
+    ) -> (ConstraintCategory<'tcx>, bool, Span, Option<RegionName>, Vec<ExtraConstraintInfo>) {
         let (blame_constraint, extra_info) = self.regioncx.best_blame_constraint(
             borrow_region,
             NllRegionVariableOrigin::FreeRegion,
@@ -348,7 +348,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         location: Location,
         borrow: &BorrowData<'tcx>,
         kind_place: Option<(WriteKind, Place<'tcx>)>,
-    ) -> BorrowExplanation {
+    ) -> BorrowExplanation<'tcx> {
         let regioncx = &self.regioncx;
         let body: &Body<'_> = &self.body;
         let tcx = self.infcx.tcx;
diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
index 245ea07d120..35c3df76899 100644
--- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
@@ -161,7 +161,7 @@ impl OutlivesSuggestionBuilder {
     pub(crate) fn intermediate_suggestion(
         &mut self,
         mbcx: &MirBorrowckCtxt<'_, '_>,
-        errci: &ErrorConstraintInfo,
+        errci: &ErrorConstraintInfo<'_>,
         diag: &mut Diagnostic,
     ) {
         // Emit an intermediate note.
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index b619537f317..15230718dc0 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -2,7 +2,6 @@
 #![deny(rustc::diagnostic_outside_of_impl)]
 //! Error reporting machinery for lifetime errors.
 
-use either::Either;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
 use rustc_hir::def_id::DefId;
@@ -17,7 +16,7 @@ use rustc_infer::infer::{
     NllRegionVariableOrigin, RelateParamBound,
 };
 use rustc_middle::hir::place::PlaceBase;
-use rustc_middle::mir::{ConstraintCategory, ReturnConstraint, TerminatorKind};
+use rustc_middle::mir::{ConstraintCategory, ReturnConstraint};
 use rustc_middle::ty::subst::InternalSubsts;
 use rustc_middle::ty::Region;
 use rustc_middle::ty::TypeVisitor;
@@ -40,7 +39,7 @@ use crate::{
     MirBorrowckCtxt,
 };
 
-impl ConstraintDescription for ConstraintCategory {
+impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> {
     fn description(&self) -> &'static str {
         // Must end with a space. Allows for empty names to be provided.
         match self {
@@ -116,7 +115,7 @@ pub(crate) enum RegionErrorKind<'tcx> {
 
 /// Information about the various region constraints involved in a borrow checker error.
 #[derive(Clone, Debug)]
-pub struct ErrorConstraintInfo {
+pub struct ErrorConstraintInfo<'tcx> {
     // fr: outlived_fr
     pub(super) fr: RegionVid,
     pub(super) fr_is_local: bool,
@@ -124,7 +123,7 @@ pub struct ErrorConstraintInfo {
     pub(super) outlived_fr_is_local: bool,
 
     // Category and span for best blame constraint
-    pub(super) category: ConstraintCategory,
+    pub(super) category: ConstraintCategory<'tcx>,
     pub(super) span: Span,
 }
 
@@ -499,7 +498,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
     /// ```
     fn report_fnmut_error(
         &self,
-        errci: &ErrorConstraintInfo,
+        errci: &ErrorConstraintInfo<'tcx>,
         kind: ReturnConstraint,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         let ErrorConstraintInfo { outlived_fr, span, .. } = errci;
@@ -572,7 +571,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
     #[instrument(level = "debug", skip(self))]
     fn report_escaping_data_error(
         &self,
-        errci: &ErrorConstraintInfo,
+        errci: &ErrorConstraintInfo<'tcx>,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         let ErrorConstraintInfo { span, category, .. } = errci;
 
@@ -676,7 +675,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
     /// ```
     fn report_general_error(
         &self,
-        errci: &ErrorConstraintInfo,
+        errci: &ErrorConstraintInfo<'tcx>,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         let ErrorConstraintInfo {
             fr,
@@ -789,7 +788,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         diag: &mut Diagnostic,
         f: Region<'tcx>,
         o: Region<'tcx>,
-        category: &ConstraintCategory,
+        category: &ConstraintCategory<'tcx>,
     ) {
         if !o.is_static() {
             return;
@@ -797,12 +796,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
         let tcx = self.infcx.tcx;
 
-        let instance =
-            if let ConstraintCategory::CallArgument(location) = category
-                && let Either::Right(term) = self.body.stmt_at(*location)
-                && let TerminatorKind::Call { func, .. } = &term.kind
-        {
-            let func_ty = func.ty(self.body, tcx);
+        let instance = if let ConstraintCategory::CallArgument(Some(func_ty)) = category {
             let (fn_did, substs) = match func_ty.kind() {
                 ty::FnDef(fn_did, substs) => (fn_did, substs),
                 _ => return,
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 85b9bde2c81..8b63294fbab 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -91,7 +91,7 @@ pub struct RegionInferenceContext<'tcx> {
 
     /// Map closure bounds to a `Span` that should be used for error reporting.
     closure_bounds_mapping:
-        FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>>,
+        FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory<'tcx>, Span)>>,
 
     /// Map universe indexes to information on why we created it.
     universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
@@ -267,7 +267,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         member_constraints_in: MemberConstraintSet<'tcx, RegionVid>,
         closure_bounds_mapping: FxHashMap<
             Location,
-            FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>,
+            FxHashMap<(RegionVid, RegionVid), (ConstraintCategory<'tcx>, Span)>,
         >,
         universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
         type_tests: Vec<TypeTest<'tcx>>,
@@ -1807,7 +1807,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     pub(crate) fn retrieve_closure_constraint_info(
         &self,
         constraint: OutlivesConstraint<'tcx>,
-    ) -> Option<(ConstraintCategory, Span)> {
+    ) -> Option<(ConstraintCategory<'tcx>, Span)> {
         match constraint.locations {
             Locations::All(_) => None,
             Locations::Single(loc) => {
@@ -1822,7 +1822,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         fr1: RegionVid,
         fr1_origin: NllRegionVariableOrigin,
         fr2: RegionVid,
-    ) -> (ConstraintCategory, ObligationCause<'tcx>) {
+    ) -> (ConstraintCategory<'tcx>, ObligationCause<'tcx>) {
         let BlameConstraint { category, cause, .. } = self
             .best_blame_constraint(fr1, fr1_origin, |r| self.provides_universal_region(r, fr1, fr2))
             .0;
@@ -2362,7 +2362,7 @@ impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx
 
 #[derive(Clone, Debug)]
 pub struct BlameConstraint<'tcx> {
-    pub category: ConstraintCategory,
+    pub category: ConstraintCategory<'tcx>,
     pub from_closure: bool,
     pub cause: ObligationCause<'tcx>,
     pub variance_info: ty::VarianceDiagInfo<'tcx>,
diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs
index 459ecfe17e3..a581726a15c 100644
--- a/compiler/rustc_borrowck/src/type_check/canonical.rs
+++ b/compiler/rustc_borrowck/src/type_check/canonical.rs
@@ -28,7 +28,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
     pub(super) fn fully_perform_op<R: fmt::Debug, Op>(
         &mut self,
         locations: Locations,
-        category: ConstraintCategory,
+        category: ConstraintCategory<'tcx>,
         op: Op,
     ) -> Fallible<R>
     where
@@ -85,7 +85,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         &mut self,
         trait_ref: ty::TraitRef<'tcx>,
         locations: Locations,
-        category: ConstraintCategory,
+        category: ConstraintCategory<'tcx>,
     ) {
         self.prove_predicate(
             ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate {
@@ -124,7 +124,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         &mut self,
         predicates: impl IntoIterator<Item = impl ToPredicate<'tcx>>,
         locations: Locations,
-        category: ConstraintCategory,
+        category: ConstraintCategory<'tcx>,
     ) {
         for predicate in predicates {
             let predicate = predicate.to_predicate(self.tcx());
@@ -139,7 +139,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         &mut self,
         predicate: ty::Predicate<'tcx>,
         locations: Locations,
-        category: ConstraintCategory,
+        category: ConstraintCategory<'tcx>,
     ) {
         let param_env = self.param_env;
         self.fully_perform_op(
@@ -164,7 +164,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         &mut self,
         value: T,
         location: impl NormalizeLocation,
-        category: ConstraintCategory,
+        category: ConstraintCategory<'tcx>,
     ) -> T
     where
         T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx,
diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
index d7e5a118a2e..d5bfc2f5208 100644
--- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
+++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
@@ -37,7 +37,7 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> {
     param_env: ty::ParamEnv<'tcx>,
     locations: Locations,
     span: Span,
-    category: ConstraintCategory,
+    category: ConstraintCategory<'tcx>,
     constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
 }
 
@@ -50,7 +50,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
         param_env: ty::ParamEnv<'tcx>,
         locations: Locations,
         span: Span,
-        category: ConstraintCategory,
+        category: ConstraintCategory<'tcx>,
         constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
     ) -> Self {
         Self {
@@ -175,7 +175,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
         &mut self,
         sup: ty::RegionVid,
         sub: ty::RegionVid,
-        category: ConstraintCategory,
+        category: ConstraintCategory<'tcx>,
     ) {
         let category = match self.category {
             ConstraintCategory::Boring | ConstraintCategory::BoringNoLocation => category,
@@ -203,7 +203,7 @@ impl<'a, 'b, 'tcx> TypeOutlivesDelegate<'tcx> for &'a mut ConstraintConversion<'
         _origin: SubregionOrigin<'tcx>,
         a: ty::Region<'tcx>,
         b: ty::Region<'tcx>,
-        constraint_category: ConstraintCategory,
+        constraint_category: ConstraintCategory<'tcx>,
     ) {
         let b = self.to_region_vid(b);
         let a = self.to_region_vid(a);
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 00cacd515a1..3c1c3ab45ce 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -942,7 +942,7 @@ pub(crate) struct MirTypeckRegionConstraints<'tcx> {
     pub(crate) member_constraints: MemberConstraintSet<'tcx, RegionVid>,
 
     pub(crate) closure_bounds_mapping:
-        FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>>,
+        FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory<'tcx>, Span)>>,
 
     pub(crate) universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
 
@@ -1133,7 +1133,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
     fn push_region_constraints(
         &mut self,
         locations: Locations,
-        category: ConstraintCategory,
+        category: ConstraintCategory<'tcx>,
         data: &QueryRegionConstraints<'tcx>,
     ) {
         debug!("constraints generated: {:#?}", data);
@@ -1158,7 +1158,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         sub: Ty<'tcx>,
         sup: Ty<'tcx>,
         locations: Locations,
-        category: ConstraintCategory,
+        category: ConstraintCategory<'tcx>,
     ) -> Fallible<()> {
         // Use this order of parameters because the sup type is usually the
         // "expected" type in diagnostics.
@@ -1171,7 +1171,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
         locations: Locations,
-        category: ConstraintCategory,
+        category: ConstraintCategory<'tcx>,
     ) -> Fallible<()> {
         self.relate_types(expected, ty::Variance::Invariant, found, locations, category)
     }
@@ -1183,7 +1183,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         v: ty::Variance,
         user_ty: &UserTypeProjection,
         locations: Locations,
-        category: ConstraintCategory,
+        category: ConstraintCategory<'tcx>,
     ) -> Fallible<()> {
         let annotated_type = self.user_type_annotations[user_ty.base].inferred_ty;
         let mut curr_projected_ty = PlaceTy::from_ty(annotated_type);
@@ -1618,12 +1618,19 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             span_mirbug!(self, term, "call to {:?} with wrong # of args", sig);
         }
 
+        let func_ty = if let TerminatorKind::Call { func, .. } = &term.kind {
+            Some(func.ty(body, self.infcx.tcx))
+        } else {
+            None
+        };
+        debug!(?func_ty);
+
         for (n, (fn_arg, op_arg)) in iter::zip(sig.inputs(), args).enumerate() {
             let op_arg_ty = op_arg.ty(body, self.tcx());
 
             let op_arg_ty = self.normalize(op_arg_ty, term_location);
             let category = if from_hir_call {
-                ConstraintCategory::CallArgument(term_location)
+                ConstraintCategory::CallArgument(self.infcx.tcx.erase_regions(func_ty))
             } else {
                 ConstraintCategory::Boring
             };
@@ -1776,7 +1783,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         // `Sized` bound in no way depends on precise regions, so this
         // shouldn't affect `is_sized`.
         let erased_ty = tcx.erase_regions(ty);
-        if !erased_ty.is_sized(tcx.at(span), self.param_env) {
+        if !erased_ty.is_sized(tcx, self.param_env) {
             // in current MIR construction, all non-control-flow rvalue
             // expressions evaluate through `as_temp` or `into` a return
             // slot or local, so to find all unsized rvalues it is enough
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index ca249938d04..4f2dc263bf5 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -28,7 +28,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         v: ty::Variance,
         b: Ty<'tcx>,
         locations: Locations,
-        category: ConstraintCategory,
+        category: ConstraintCategory<'tcx>,
     ) -> Fallible<()> {
         TypeRelating::new(
             self.infcx,
@@ -45,7 +45,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         a: ty::SubstsRef<'tcx>,
         b: ty::SubstsRef<'tcx>,
         locations: Locations,
-        category: ConstraintCategory,
+        category: ConstraintCategory<'tcx>,
     ) -> Fallible<()> {
         TypeRelating::new(
             self.infcx,
@@ -64,7 +64,7 @@ struct NllTypeRelatingDelegate<'me, 'bccx, 'tcx> {
     locations: Locations,
 
     /// What category do we assign the resulting `'a: 'b` relationships?
-    category: ConstraintCategory,
+    category: ConstraintCategory<'tcx>,
 
     /// Information so that error reporting knows what types we are relating
     /// when reporting a bound region error.
@@ -75,7 +75,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelatingDelegate<'me, 'bccx, 'tcx> {
     fn new(
         type_checker: &'me mut TypeChecker<'bccx, 'tcx>,
         locations: Locations,
-        category: ConstraintCategory,
+        category: ConstraintCategory<'tcx>,
         universe_info: UniverseInfo<'tcx>,
     ) -> Self {
         Self { type_checker, locations, category, universe_info }
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index a41b561598f..1db44502742 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -770,11 +770,7 @@ fn codegen_stmt<'tcx>(
                     lval.write_cvalue(fx, CValue::by_val(operand, box_layout));
                 }
                 Rvalue::NullaryOp(null_op, ty) => {
-                    assert!(
-                        lval.layout()
-                            .ty
-                            .is_sized(fx.tcx.at(stmt.source_info.span), ParamEnv::reveal_all())
-                    );
+                    assert!(lval.layout().ty.is_sized(fx.tcx, ParamEnv::reveal_all()));
                     let layout = fx.layout_of(fx.monomorphize(ty));
                     let val = match null_op {
                         NullOp::SizeOf => layout.size.bytes(),
diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs
index d4bc3543b2d..148b66d959e 100644
--- a/compiler/rustc_codegen_cranelift/src/constant.rs
+++ b/compiler/rustc_codegen_cranelift/src/constant.rs
@@ -5,7 +5,6 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir::interpret::{
     read_target_uint, AllocId, ConstAllocation, ConstValue, ErrorHandled, GlobalAlloc, Scalar,
 };
-use rustc_span::DUMMY_SP;
 
 use cranelift_module::*;
 
@@ -291,7 +290,7 @@ fn data_id_for_static(
     let is_mutable = if tcx.is_mutable_static(def_id) {
         true
     } else {
-        !ty.is_freeze(tcx.at(DUMMY_SP), ParamEnv::reveal_all())
+        !ty.is_freeze(tcx, ParamEnv::reveal_all())
     };
     let align = tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().align.pref.bytes();
 
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index fca43a0d86d..9cb36ce7f18 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -365,11 +365,14 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
                 Int(I64) => "llvm.ssub.with.overflow.i64",
                 Int(I128) => "llvm.ssub.with.overflow.i128",
 
-                Uint(U8) => "llvm.usub.with.overflow.i8",
-                Uint(U16) => "llvm.usub.with.overflow.i16",
-                Uint(U32) => "llvm.usub.with.overflow.i32",
-                Uint(U64) => "llvm.usub.with.overflow.i64",
-                Uint(U128) => "llvm.usub.with.overflow.i128",
+                Uint(_) => {
+                    // Emit sub and icmp instead of llvm.usub.with.overflow. LLVM considers these
+                    // to be the canonical form. It will attempt to reform llvm.usub.with.overflow
+                    // in the backend if profitable.
+                    let sub = self.sub(lhs, rhs);
+                    let cmp = self.icmp(IntPredicate::IntULT, lhs, rhs);
+                    return (sub, cmp);
+                }
 
                 _ => unreachable!(),
             },
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 84b89cd71a6..a92087305b8 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -22,7 +22,6 @@ use rustc_data_structures::sync::ParallelIterator;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::lang_items::LangItem;
-use rustc_hir::weak_lang_items::WEAK_ITEMS_SYMBOLS;
 use rustc_index::vec::Idx;
 use rustc_metadata::EncodedMetadata;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
@@ -887,14 +886,14 @@ impl CrateInfo {
         // by the compiler, but that's ok because all this stuff is unstable anyway.
         let target = &tcx.sess.target;
         if !are_upstream_rust_objects_already_included(tcx.sess) {
-            let missing_weak_lang_items: FxHashSet<&Symbol> = info
+            let missing_weak_lang_items: FxHashSet<Symbol> = info
                 .used_crates
                 .iter()
-                .flat_map(|cnum| {
-                    tcx.missing_lang_items(*cnum)
-                        .iter()
-                        .filter(|l| lang_items::required(tcx, **l))
-                        .filter_map(|item| WEAK_ITEMS_SYMBOLS.get(item))
+                .flat_map(|&cnum| tcx.missing_lang_items(cnum))
+                .filter(|l| l.is_weak())
+                .filter_map(|&l| {
+                    let name = l.link_name()?;
+                    lang_items::required(tcx, l).then_some(name)
                 })
                 .collect();
             let prefix = if target.is_like_windows && target.arch == "x86" { "_" } else { "" };
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 29b7c9b0a88..0802067cde6 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -17,6 +17,7 @@ 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_session::config::OptLevel;
 use rustc_span::source_map::Span;
 use rustc_span::{sym, Symbol};
 use rustc_symbol_mangling::typeid::typeid_for_fnabi;
@@ -286,12 +287,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         assert_eq!(discr.layout.ty, switch_ty);
         let mut target_iter = targets.iter();
         if target_iter.len() == 1 {
-            // If there are two targets (one conditional, one fallback), emit br instead of switch
+            // If there are two targets (one conditional, one fallback), emit `br` instead of
+            // `switch`.
             let (test_value, target) = target_iter.next().unwrap();
             let lltrue = helper.llbb_with_cleanup(self, target);
             let llfalse = helper.llbb_with_cleanup(self, targets.otherwise());
             if switch_ty == bx.tcx().types.bool {
-                // Don't generate trivial icmps when switching on bool
+                // Don't generate trivial icmps when switching on bool.
                 match test_value {
                     0 => bx.cond_br(discr.immediate(), llfalse, lltrue),
                     1 => bx.cond_br(discr.immediate(), lltrue, llfalse),
@@ -303,6 +305,30 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 let cmp = bx.icmp(IntPredicate::IntEQ, discr.immediate(), llval);
                 bx.cond_br(cmp, lltrue, llfalse);
             }
+        } else if self.cx.sess().opts.optimize == OptLevel::No
+            && target_iter.len() == 2
+            && self.mir[targets.otherwise()].is_empty_unreachable()
+        {
+            // In unoptimized builds, if there are two normal targets and the `otherwise` target is
+            // an unreachable BB, emit `br` instead of `switch`. This leaves behind the unreachable
+            // BB, which will usually (but not always) be dead code.
+            //
+            // Why only in unoptimized builds?
+            // - In unoptimized builds LLVM uses FastISel which does not support switches, so it
+            //   must fall back to the to the slower SelectionDAG isel. Therefore, using `br` gives
+            //   significant compile time speedups for unoptimized builds.
+            // - In optimized builds the above doesn't hold, and using `br` sometimes results in
+            //   worse generated code because LLVM can no longer tell that the value being switched
+            //   on can only have two values, e.g. 0 and 1.
+            //
+            let (test_value1, target1) = target_iter.next().unwrap();
+            let (_test_value2, target2) = target_iter.next().unwrap();
+            let ll1 = helper.llbb_with_cleanup(self, target1);
+            let ll2 = helper.llbb_with_cleanup(self, target2);
+            let switch_llty = bx.immediate_backend_type(bx.layout_of(switch_ty));
+            let llval = bx.const_uint_big(switch_llty, test_value1);
+            let cmp = bx.icmp(IntPredicate::IntEQ, discr.immediate(), llval);
+            bx.cond_br(cmp, ll1, ll2);
         } else {
             bx.switch(
                 discr.immediate(),
diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs
index 8158e8dd011..bdc6a91cf6a 100644
--- a/compiler/rustc_codegen_ssa/src/traits/type_.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs
@@ -5,7 +5,6 @@ use crate::common::TypeKind;
 use crate::mir::place::PlaceRef;
 use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::ty::{self, Ty};
-use rustc_span::DUMMY_SP;
 use rustc_target::abi::call::{ArgAbi, CastTarget, FnAbi, Reg};
 use rustc_target::abi::{AddressSpace, Integer};
 
@@ -75,16 +74,16 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
     }
 
     fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
-        ty.is_sized(self.tcx().at(DUMMY_SP), ty::ParamEnv::reveal_all())
+        ty.is_sized(self.tcx(), ty::ParamEnv::reveal_all())
     }
 
     fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
-        ty.is_freeze(self.tcx().at(DUMMY_SP), ty::ParamEnv::reveal_all())
+        ty.is_freeze(self.tcx(), ty::ParamEnv::reveal_all())
     }
 
     fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
         let param_env = ty::ParamEnv::reveal_all();
-        if ty.is_sized(self.tcx().at(DUMMY_SP), param_env) {
+        if ty.is_sized(self.tcx(), param_env) {
             return false;
         }
 
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index e5acacd9188..35d58d2f638 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -2,10 +2,10 @@ use rustc_hir::def::DefKind;
 use rustc_middle::mir;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use std::borrow::Borrow;
-use std::collections::hash_map::Entry;
 use std::hash::Hash;
 
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::FxIndexMap;
+use rustc_data_structures::fx::IndexEntry;
 use std::fmt;
 
 use rustc_ast::Mutability;
@@ -107,18 +107,18 @@ impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> {
     }
 }
 
-impl<K: Hash + Eq, V> interpret::AllocMap<K, V> for FxHashMap<K, V> {
+impl<K: Hash + Eq, V> interpret::AllocMap<K, V> for FxIndexMap<K, V> {
     #[inline(always)]
     fn contains_key<Q: ?Sized + Hash + Eq>(&mut self, k: &Q) -> bool
     where
         K: Borrow<Q>,
     {
-        FxHashMap::contains_key(self, k)
+        FxIndexMap::contains_key(self, k)
     }
 
     #[inline(always)]
     fn insert(&mut self, k: K, v: V) -> Option<V> {
-        FxHashMap::insert(self, k, v)
+        FxIndexMap::insert(self, k, v)
     }
 
     #[inline(always)]
@@ -126,7 +126,7 @@ impl<K: Hash + Eq, V> interpret::AllocMap<K, V> for FxHashMap<K, V> {
     where
         K: Borrow<Q>,
     {
-        FxHashMap::remove(self, k)
+        FxIndexMap::remove(self, k)
     }
 
     #[inline(always)]
@@ -148,8 +148,8 @@ impl<K: Hash + Eq, V> interpret::AllocMap<K, V> for FxHashMap<K, V> {
     #[inline(always)]
     fn get_mut_or<E>(&mut self, k: K, vacant: impl FnOnce() -> Result<V, E>) -> Result<&mut V, E> {
         match self.entry(k) {
-            Entry::Occupied(e) => Ok(e.into_mut()),
-            Entry::Vacant(e) => {
+            IndexEntry::Occupied(e) => Ok(e.into_mut()),
+            IndexEntry::Vacant(e) => {
                 let v = vacant()?;
                 Ok(e.insert(v))
             }
diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
index a964fe8465e..f4da1188395 100644
--- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs
+++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
@@ -212,7 +212,7 @@ fn create_pointee_place<'tcx>(
 ) -> MPlaceTy<'tcx> {
     let tcx = ecx.tcx.tcx;
 
-    if !ty.is_sized(ecx.tcx, ty::ParamEnv::empty()) {
+    if !ty.is_sized(*ecx.tcx, ty::ParamEnv::empty()) {
         // We need to create `Allocation`s for custom DSTs
 
         let (unsized_inner_ty, num_elems) = get_info_on_unsized_field(ty, valtree, tcx);
@@ -398,7 +398,7 @@ fn valtree_into_mplace<'tcx>(
 
                 let mut place_inner = match ty.kind() {
                     ty::Str | ty::Slice(_) => ecx.mplace_index(&place, i as u64).unwrap(),
-                    _ if !ty.is_sized(ecx.tcx, ty::ParamEnv::empty())
+                    _ if !ty.is_sized(*ecx.tcx, ty::ParamEnv::empty())
                         && i == branches.len() - 1 =>
                     {
                         // Note: For custom DSTs we need to manually process the last unsized field.
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index d2e0a0dd240..a9063ad31cf 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -468,7 +468,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
     #[inline]
     pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
-        ty.is_freeze(self.tcx, self.param_env)
+        ty.is_freeze(*self.tcx, self.param_env)
     }
 
     pub fn load_mir(
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs
index f72ae7413e3..6809a42dc45 100644
--- a/compiler/rustc_const_eval/src/interpret/intern.rs
+++ b/compiler/rustc_const_eval/src/interpret/intern.rs
@@ -15,7 +15,7 @@
 //! that contains allocations whose mutability we cannot identify.)
 
 use super::validity::RefTracking;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir as hir;
 use rustc_middle::mir::interpret::InterpResult;
@@ -37,7 +37,7 @@ pub trait CompileTimeMachine<'mir, 'tcx, T> = Machine<
     ExtraFnVal = !,
     FrameExtra = (),
     AllocExtra = (),
-    MemoryMap = FxHashMap<AllocId, (MemoryKind<T>, Allocation)>,
+    MemoryMap = FxIndexMap<AllocId, (MemoryKind<T>, Allocation)>,
 >;
 
 struct InternVisitor<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx, const_eval::MemoryKind>> {
@@ -47,7 +47,7 @@ struct InternVisitor<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx, const_ev
     ref_tracking: &'rt mut RefTracking<(MPlaceTy<'tcx>, InternMode)>,
     /// A list of all encountered allocations. After type-based interning, we traverse this list to
     /// also intern allocations that are only referenced by a raw pointer or inside a union.
-    leftover_allocations: &'rt mut FxHashSet<AllocId>,
+    leftover_allocations: &'rt mut FxIndexSet<AllocId>,
     /// The root kind of the value that we're looking at. This field is never mutated for a
     /// particular allocation. It is primarily used to make as many allocations as possible
     /// read-only so LLVM can place them in const memory.
@@ -79,7 +79,7 @@ struct IsStaticOrFn;
 /// to account for (e.g. for vtables).
 fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx, const_eval::MemoryKind>>(
     ecx: &'rt mut InterpCx<'mir, 'tcx, M>,
-    leftover_allocations: &'rt mut FxHashSet<AllocId>,
+    leftover_allocations: &'rt mut FxIndexSet<AllocId>,
     alloc_id: AllocId,
     mode: InternMode,
     ty: Option<Ty<'tcx>>,
@@ -114,7 +114,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx, const_eval:
     if let InternMode::Static(mutability) = mode {
         // For this, we need to take into account `UnsafeCell`. When `ty` is `None`, we assume
         // no interior mutability.
-        let frozen = ty.map_or(true, |ty| ty.is_freeze(ecx.tcx, ecx.param_env));
+        let frozen = ty.map_or(true, |ty| ty.is_freeze(*ecx.tcx, ecx.param_env));
         // For statics, allocation mutability is the combination of place mutability and
         // type mutability.
         // The entire allocation needs to be mutable if it contains an `UnsafeCell` anywhere.
@@ -355,7 +355,7 @@ pub fn intern_const_alloc_recursive<
     // `leftover_allocations` collects *all* allocations we see, because some might not
     // be available in a typed way. They get interned at the end.
     let mut ref_tracking = RefTracking::empty();
-    let leftover_allocations = &mut FxHashSet::default();
+    let leftover_allocations = &mut FxIndexSet::default();
 
     // start with the outermost allocation
     intern_shallow(
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs
index ffdb8de5b6c..b15606baee5 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs
@@ -4,7 +4,7 @@ use rustc_hir::definitions::DisambiguatedDefPathData;
 use rustc_middle::mir::interpret::{Allocation, ConstAllocation};
 use rustc_middle::ty::{
     self,
-    print::{with_no_verbose_constants, PrettyPrinter, Print, Printer},
+    print::{PrettyPrinter, Print, Printer},
     subst::{GenericArg, GenericArgKind},
     Ty, TyCtxt,
 };
@@ -179,6 +179,11 @@ impl<'tcx> PrettyPrinter<'tcx> for AbsolutePathPrinter<'tcx> {
 
         Ok(self)
     }
+
+    fn should_print_verbose(&self) -> bool {
+        // `std::any::type_name` should never print verbose type names
+        false
+    }
 }
 
 impl Write for AbsolutePathPrinter<'_> {
@@ -190,9 +195,7 @@ impl Write for AbsolutePathPrinter<'_> {
 
 /// Directly returns an `Allocation` containing an absolute path representation of the given type.
 pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAllocation<'tcx> {
-    let path = with_no_verbose_constants!(
-        AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path
-    );
+    let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path;
     let alloc = Allocation::from_bytes_byte_aligned_immutable(path.into_bytes());
     tcx.intern_const_alloc(alloc)
 }
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index 530e252b7c0..351152eba01 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -426,7 +426,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
     type ExtraFnVal = !;
 
     type MemoryMap =
-        rustc_data_structures::fx::FxHashMap<AllocId, (MemoryKind<Self::MemoryKind>, Allocation)>;
+        rustc_data_structures::fx::FxIndexMap<AllocId, (MemoryKind<Self::MemoryKind>, Allocation)>;
     const GLOBAL_KIND: Option<Self::MemoryKind> = None; // no copying of globals from `tcx` to machine memory
 
     type AllocExtra = ();
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index d4146c24241..8aa56c275d9 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -15,7 +15,6 @@ use rustc_middle::mir::interpret::InterpError;
 use rustc_middle::ty;
 use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
 use rustc_span::symbol::{sym, Symbol};
-use rustc_span::DUMMY_SP;
 use rustc_target::abi::{Abi, Scalar as ScalarAbi, Size, VariantIdx, Variants, WrappingRange};
 
 use std::hash::Hash;
@@ -726,7 +725,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
     ) -> InterpResult<'tcx> {
         // Special check preventing `UnsafeCell` inside unions in the inner part of constants.
         if matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { inner: true, .. })) {
-            if !op.layout.ty.is_freeze(self.ecx.tcx.at(DUMMY_SP), self.ecx.param_env) {
+            if !op.layout.ty.is_freeze(*self.ecx.tcx, self.ecx.param_env) {
                 throw_validation_failure!(self.path, { "`UnsafeCell` in a `const`" });
             }
         }
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index 230f841cf4d..443c01fdb90 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -22,7 +22,6 @@ Rust MIR: a lowered representation of Rust.
 #![feature(yeet_expr)]
 #![feature(is_some_and)]
 #![recursion_limit = "256"]
-#![allow(rustc::potential_query_instability)]
 
 #[macro_use]
 extern crate tracing;
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
index b77b213b51a..335992342a6 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
@@ -8,7 +8,6 @@ use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::mir;
 use rustc_middle::mir::*;
 use rustc_middle::ty::{self, subst::SubstsRef, AdtDef, Ty};
-use rustc_span::DUMMY_SP;
 use rustc_trait_selection::traits::{
     self, ImplSource, Obligation, ObligationCause, SelectionContext,
 };
@@ -92,7 +91,7 @@ impl Qualif for HasMutInterior {
     }
 
     fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
-        !ty.is_freeze(cx.tcx.at(DUMMY_SP), cx.param_env)
+        !ty.is_freeze(cx.tcx, cx.param_env)
     }
 
     fn in_adt_inherently<'tcx>(
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs b/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs
index 60c1e495029..805e6096b35 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs
@@ -8,7 +8,6 @@ use rustc_middle::mir::{self, BasicBlock, Local, Location, Statement, StatementK
 use rustc_mir_dataflow::fmt::DebugWithContext;
 use rustc_mir_dataflow::JoinSemiLattice;
 use rustc_mir_dataflow::{Analysis, AnalysisDomain, CallReturnPlaces};
-use rustc_span::DUMMY_SP;
 
 use std::fmt;
 use std::marker::PhantomData;
@@ -120,10 +119,7 @@ where
     ///
     /// [rust-lang/unsafe-code-guidelines#134]: https://github.com/rust-lang/unsafe-code-guidelines/issues/134
     fn shared_borrow_allows_mutation(&self, place: mir::Place<'tcx>) -> bool {
-        !place
-            .ty(self.ccx.body, self.ccx.tcx)
-            .ty
-            .is_freeze(self.ccx.tcx.at(DUMMY_SP), self.ccx.param_env)
+        !place.ty(self.ccx.body, self.ccx.tcx).ty.is_freeze(self.ccx.tcx, self.ccx.param_env)
     }
 }
 
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 7f78d963e9f..81b82a21fa1 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -235,9 +235,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
             // `Operand::Copy` is only supposed to be used with `Copy` types.
             if let Operand::Copy(place) = operand {
                 let ty = place.ty(&self.body.local_decls, self.tcx).ty;
-                let span = self.body.source_info(location).span;
 
-                if !ty.is_copy_modulo_regions(self.tcx.at(span), self.param_env) {
+                if !ty.is_copy_modulo_regions(self.tcx, self.param_env) {
                     self.fail(location, format!("`Operand::Copy` with non-`Copy` type {}", ty));
                 }
             }
diff --git a/compiler/rustc_const_eval/src/util/call_kind.rs b/compiler/rustc_const_eval/src/util/call_kind.rs
index af9d83f0609..5446ccb1a47 100644
--- a/compiler/rustc_const_eval/src/util/call_kind.rs
+++ b/compiler/rustc_const_eval/src/util/call_kind.rs
@@ -3,7 +3,7 @@
 //! context.
 
 use rustc_hir::def_id::DefId;
-use rustc_hir::lang_items::LangItemGroup;
+use rustc_hir::lang_items;
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::{self, AssocItemContainer, DefIdTree, Instance, ParamEnv, Ty, TyCtxt};
 use rustc_span::symbol::Ident;
@@ -74,22 +74,24 @@ pub fn call_kind<'tcx>(
         }
     });
 
-    let fn_call = parent
-        .and_then(|p| tcx.lang_items().group(LangItemGroup::Fn).iter().find(|did| **did == p));
+    let fn_call = parent.and_then(|p| {
+        lang_items::FN_TRAITS.iter().filter_map(|&l| tcx.lang_items().get(l)).find(|&id| id == p)
+    });
 
-    let operator = (!from_hir_call)
-        .then(|| parent)
-        .flatten()
-        .and_then(|p| tcx.lang_items().group(LangItemGroup::Op).iter().find(|did| **did == p));
+    let operator = if !from_hir_call && let Some(p) = parent {
+        lang_items::OPERATORS.iter().filter_map(|&l| tcx.lang_items().get(l)).find(|&id| id == p)
+    } else {
+        None
+    };
 
     let is_deref = !from_hir_call && tcx.is_diagnostic_item(sym::deref_method, method_did);
 
     // Check for a 'special' use of 'self' -
     // an FnOnce call, an operator (e.g. `<<`), or a
     // deref coercion.
-    let kind = if let Some(&trait_id) = fn_call {
+    let kind = if let Some(trait_id) = fn_call {
         Some(CallKind::FnCall { fn_trait_id: trait_id, self_ty: method_substs.type_at(0) })
-    } else if let Some(&trait_id) = operator {
+    } else if let Some(trait_id) = operator {
         Some(CallKind::Operator { self_arg, trait_id, self_ty: method_substs.type_at(0) })
     } else if is_deref {
         let deref_target = tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 467ac401d08..3a2000233c5 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -22,6 +22,7 @@
 #![feature(new_uninit)]
 #![feature(once_cell)]
 #![feature(rustc_attrs)]
+#![feature(negative_impls)]
 #![feature(test)]
 #![feature(thread_id_value)]
 #![feature(vec_into_raw_parts)]
@@ -86,6 +87,7 @@ pub mod steal;
 pub mod tagged_ptr;
 pub mod temp_dir;
 pub mod unhash;
+pub mod unord;
 
 pub use ena::undo_log;
 pub use ena::unify;
diff --git a/compiler/rustc_data_structures/src/unord.rs b/compiler/rustc_data_structures/src/unord.rs
new file mode 100644
index 00000000000..c015f1232cd
--- /dev/null
+++ b/compiler/rustc_data_structures/src/unord.rs
@@ -0,0 +1,382 @@
+//! This module contains collection types that don't expose their internal
+//! ordering. This is a useful property for deterministic computations, such
+//! as required by the query system.
+
+use rustc_hash::{FxHashMap, FxHashSet};
+use smallvec::SmallVec;
+use std::{
+    borrow::Borrow,
+    hash::Hash,
+    iter::{Product, Sum},
+};
+
+use crate::{
+    fingerprint::Fingerprint,
+    stable_hasher::{HashStable, StableHasher, ToStableHashKey},
+};
+
+/// `UnordItems` is the order-less version of `Iterator`. It only contains methods
+/// that don't (easily) expose an ordering of the underlying items.
+///
+/// Most methods take an `Fn` where the `Iterator`-version takes an `FnMut`. This
+/// is to reduce the risk of accidentally leaking the internal order via the closure
+/// environment. Otherwise one could easily do something like
+///
+/// ```rust,ignore (pseudo code)
+/// let mut ordered = vec![];
+/// unordered_items.all(|x| ordered.push(x));
+/// ```
+///
+/// It's still possible to do the same thing with an `Fn` by using interior mutability,
+/// but the chance of doing it accidentally is reduced.
+pub struct UnordItems<T, I: Iterator<Item = T>>(I);
+
+impl<T, I: Iterator<Item = T>> UnordItems<T, I> {
+    #[inline]
+    pub fn map<U, F: Fn(T) -> U>(self, f: F) -> UnordItems<U, impl Iterator<Item = U>> {
+        UnordItems(self.0.map(f))
+    }
+
+    #[inline]
+    pub fn all<U, F: Fn(T) -> bool>(mut self, f: F) -> bool {
+        self.0.all(f)
+    }
+
+    #[inline]
+    pub fn any<U, F: Fn(T) -> bool>(mut self, f: F) -> bool {
+        self.0.any(f)
+    }
+
+    #[inline]
+    pub fn filter<U, F: Fn(&T) -> bool>(self, f: F) -> UnordItems<T, impl Iterator<Item = T>> {
+        UnordItems(self.0.filter(f))
+    }
+
+    #[inline]
+    pub fn filter_map<U, F: Fn(T) -> Option<U>>(
+        self,
+        f: F,
+    ) -> UnordItems<U, impl Iterator<Item = U>> {
+        UnordItems(self.0.filter_map(f))
+    }
+
+    #[inline]
+    pub fn max(self) -> Option<T>
+    where
+        T: Ord,
+    {
+        self.0.max()
+    }
+
+    #[inline]
+    pub fn min(self) -> Option<T>
+    where
+        T: Ord,
+    {
+        self.0.min()
+    }
+
+    #[inline]
+    pub fn sum<S>(self) -> S
+    where
+        S: Sum<T>,
+    {
+        self.0.sum()
+    }
+
+    #[inline]
+    pub fn product<S>(self) -> S
+    where
+        S: Product<T>,
+    {
+        self.0.product()
+    }
+
+    #[inline]
+    pub fn count(self) -> usize {
+        self.0.count()
+    }
+}
+
+impl<'a, T: Clone + 'a, I: Iterator<Item = &'a T>> UnordItems<&'a T, I> {
+    #[inline]
+    pub fn cloned(self) -> UnordItems<T, impl Iterator<Item = T>> {
+        UnordItems(self.0.cloned())
+    }
+}
+
+impl<'a, T: Copy + 'a, I: Iterator<Item = &'a T>> UnordItems<&'a T, I> {
+    #[inline]
+    pub fn copied(self) -> UnordItems<T, impl Iterator<Item = T>> {
+        UnordItems(self.0.copied())
+    }
+}
+
+impl<T: Ord, I: Iterator<Item = T>> UnordItems<T, I> {
+    pub fn into_sorted<HCX>(self, hcx: &HCX) -> Vec<T>
+    where
+        T: ToStableHashKey<HCX>,
+    {
+        let mut items: Vec<T> = self.0.collect();
+        items.sort_by_cached_key(|x| x.to_stable_hash_key(hcx));
+        items
+    }
+
+    pub fn into_sorted_small_vec<HCX, const LEN: usize>(self, hcx: &HCX) -> SmallVec<[T; LEN]>
+    where
+        T: ToStableHashKey<HCX>,
+    {
+        let mut items: SmallVec<[T; LEN]> = self.0.collect();
+        items.sort_by_cached_key(|x| x.to_stable_hash_key(hcx));
+        items
+    }
+}
+
+/// This is a set collection type that tries very hard to not expose
+/// any internal iteration. This is a useful property when trying to
+/// uphold the determinism invariants imposed by the query system.
+///
+/// This collection type is a good choice for set-like collections the
+/// keys of which don't have a semantic ordering.
+///
+/// See [MCP 533](https://github.com/rust-lang/compiler-team/issues/533)
+/// for more information.
+#[derive(Debug, Eq, PartialEq, Clone, Encodable, Decodable)]
+pub struct UnordSet<V: Eq + Hash> {
+    inner: FxHashSet<V>,
+}
+
+impl<V: Eq + Hash> Default for UnordSet<V> {
+    fn default() -> Self {
+        Self { inner: FxHashSet::default() }
+    }
+}
+
+impl<V: Eq + Hash> UnordSet<V> {
+    #[inline]
+    pub fn new() -> Self {
+        Self { inner: Default::default() }
+    }
+
+    #[inline]
+    pub fn len(&self) -> usize {
+        self.inner.len()
+    }
+
+    #[inline]
+    pub fn insert(&mut self, v: V) -> bool {
+        self.inner.insert(v)
+    }
+
+    #[inline]
+    pub fn contains<Q: ?Sized>(&self, v: &Q) -> bool
+    where
+        V: Borrow<Q>,
+        Q: Hash + Eq,
+    {
+        self.inner.contains(v)
+    }
+
+    #[inline]
+    pub fn items<'a>(&'a self) -> UnordItems<&'a V, impl Iterator<Item = &'a V>> {
+        UnordItems(self.inner.iter())
+    }
+
+    #[inline]
+    pub fn into_items(self) -> UnordItems<V, impl Iterator<Item = V>> {
+        UnordItems(self.inner.into_iter())
+    }
+
+    // We can safely extend this UnordSet from a set of unordered values because that
+    // won't expose the internal ordering anywhere.
+    #[inline]
+    pub fn extend<I: Iterator<Item = V>>(&mut self, items: UnordItems<V, I>) {
+        self.inner.extend(items.0)
+    }
+}
+
+impl<V: Hash + Eq> Extend<V> for UnordSet<V> {
+    fn extend<T: IntoIterator<Item = V>>(&mut self, iter: T) {
+        self.inner.extend(iter)
+    }
+}
+
+impl<HCX, V: Hash + Eq + HashStable<HCX>> HashStable<HCX> for UnordSet<V> {
+    #[inline]
+    fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
+        hash_iter_order_independent(self.inner.iter(), hcx, hasher);
+    }
+}
+
+/// This is a map collection type that tries very hard to not expose
+/// any internal iteration. This is a useful property when trying to
+/// uphold the determinism invariants imposed by the query system.
+///
+/// This collection type is a good choice for map-like collections the
+/// keys of which don't have a semantic ordering.
+///
+/// See [MCP 533](https://github.com/rust-lang/compiler-team/issues/533)
+/// for more information.
+#[derive(Debug, Eq, PartialEq, Clone, Encodable, Decodable)]
+pub struct UnordMap<K: Eq + Hash, V> {
+    inner: FxHashMap<K, V>,
+}
+
+impl<K: Eq + Hash, V> Default for UnordMap<K, V> {
+    fn default() -> Self {
+        Self { inner: FxHashMap::default() }
+    }
+}
+
+impl<K: Hash + Eq, V> Extend<(K, V)> for UnordMap<K, V> {
+    fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
+        self.inner.extend(iter)
+    }
+}
+
+impl<K: Eq + Hash, V> UnordMap<K, V> {
+    #[inline]
+    pub fn len(&self) -> usize {
+        self.inner.len()
+    }
+
+    #[inline]
+    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
+        self.inner.insert(k, v)
+    }
+
+    #[inline]
+    pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
+    where
+        K: Borrow<Q>,
+        Q: Hash + Eq,
+    {
+        self.inner.contains_key(k)
+    }
+
+    #[inline]
+    pub fn items<'a>(&'a self) -> UnordItems<(&'a K, &'a V), impl Iterator<Item = (&'a K, &'a V)>> {
+        UnordItems(self.inner.iter())
+    }
+
+    #[inline]
+    pub fn into_items(self) -> UnordItems<(K, V), impl Iterator<Item = (K, V)>> {
+        UnordItems(self.inner.into_iter())
+    }
+
+    // We can safely extend this UnordMap from a set of unordered values because that
+    // won't expose the internal ordering anywhere.
+    #[inline]
+    pub fn extend<I: Iterator<Item = (K, V)>>(&mut self, items: UnordItems<(K, V), I>) {
+        self.inner.extend(items.0)
+    }
+}
+
+impl<HCX, K: Hash + Eq + HashStable<HCX>, V: HashStable<HCX>> HashStable<HCX> for UnordMap<K, V> {
+    #[inline]
+    fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
+        hash_iter_order_independent(self.inner.iter(), hcx, hasher);
+    }
+}
+
+/// This is a collection type that tries very hard to not expose
+/// any internal iteration. This is a useful property when trying to
+/// uphold the determinism invariants imposed by the query system.
+///
+/// This collection type is a good choice for collections the
+/// keys of which don't have a semantic ordering and don't implement
+/// `Hash` or `Eq`.
+///
+/// See [MCP 533](https://github.com/rust-lang/compiler-team/issues/533)
+/// for more information.
+#[derive(Default, Debug, Eq, PartialEq, Clone, Encodable, Decodable)]
+pub struct UnordBag<V> {
+    inner: Vec<V>,
+}
+
+impl<V> UnordBag<V> {
+    #[inline]
+    pub fn new() -> Self {
+        Self { inner: Default::default() }
+    }
+
+    #[inline]
+    pub fn len(&self) -> usize {
+        self.inner.len()
+    }
+
+    #[inline]
+    pub fn push(&mut self, v: V) {
+        self.inner.push(v);
+    }
+
+    #[inline]
+    pub fn items<'a>(&'a self) -> UnordItems<&'a V, impl Iterator<Item = &'a V>> {
+        UnordItems(self.inner.iter())
+    }
+
+    #[inline]
+    pub fn into_items(self) -> UnordItems<V, impl Iterator<Item = V>> {
+        UnordItems(self.inner.into_iter())
+    }
+
+    // We can safely extend this UnordSet from a set of unordered values because that
+    // won't expose the internal ordering anywhere.
+    #[inline]
+    pub fn extend<I: Iterator<Item = V>>(&mut self, items: UnordItems<V, I>) {
+        self.inner.extend(items.0)
+    }
+}
+
+impl<T> Extend<T> for UnordBag<T> {
+    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
+        self.inner.extend(iter)
+    }
+}
+
+impl<HCX, V: Hash + Eq + HashStable<HCX>> HashStable<HCX> for UnordBag<V> {
+    #[inline]
+    fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
+        hash_iter_order_independent(self.inner.iter(), hcx, hasher);
+    }
+}
+
+fn hash_iter_order_independent<
+    HCX,
+    T: HashStable<HCX>,
+    I: Iterator<Item = T> + ExactSizeIterator,
+>(
+    mut it: I,
+    hcx: &mut HCX,
+    hasher: &mut StableHasher,
+) {
+    let len = it.len();
+    len.hash_stable(hcx, hasher);
+
+    match len {
+        0 => {
+            // We're done
+        }
+        1 => {
+            // No need to instantiate a hasher
+            it.next().unwrap().hash_stable(hcx, hasher);
+        }
+        _ => {
+            let mut accumulator = Fingerprint::ZERO;
+            for item in it {
+                let mut item_hasher = StableHasher::new();
+                item.hash_stable(hcx, &mut item_hasher);
+                let item_fingerprint: Fingerprint = item_hasher.finish();
+                accumulator = accumulator.combine_commutative(item_fingerprint);
+            }
+            accumulator.hash_stable(hcx, hasher);
+        }
+    }
+}
+
+// Do not implement IntoIterator for the collections in this module.
+// They only exist to hide iteration order in the first place.
+impl<T> !IntoIterator for UnordBag<T> {}
+impl<V> !IntoIterator for UnordSet<V> {}
+impl<K, V> !IntoIterator for UnordMap<K, V> {}
+impl<T, I> !IntoIterator for UnordItems<T, I> {}
diff --git a/compiler/rustc_error_codes/src/error_codes/E0382.md b/compiler/rustc_error_codes/src/error_codes/E0382.md
index d1408a06296..cbc4980f8ca 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0382.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0382.md
@@ -61,7 +61,7 @@ with `#[derive(Clone)]`.
 
 Some types have no ownership semantics at all and are trivial to duplicate. An
 example is `i32` and the other number types. We don't have to call `.clone()` to
-clone them, because they are marked `Copy` in addition to `Clone`.  Implicit
+clone them, because they are marked `Copy` in addition to `Clone`. Implicit
 cloning is more convenient in this case. We can mark our own types `Copy` if
 all their members also are marked `Copy`.
 
diff --git a/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl
index 7ac44312695..74088f4dfbe 100644
--- a/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl
@@ -93,7 +93,7 @@ hir_analysis_expected_default_return_type = expected `()` because of default ret
 hir_analysis_expected_return_type = expected `{$expected}` because of return type
 
 hir_analysis_unconstrained_opaque_type = unconstrained opaque type
-    .note = `{$name}` must be used in combination with a concrete type within the same module
+    .note = `{$name}` must be used in combination with a concrete type within the same {$what}
 
 hir_analysis_missing_type_params =
     the type {$parameterCount ->
@@ -146,3 +146,7 @@ hir_analysis_const_impl_for_non_const_trait =
 
 hir_analysis_const_bound_for_non_const_trait =
     ~const can only be applied to `#[const_trait]` traits
+
+hir_analysis_self_in_impl_self =
+    `Self` is not valid in the self type of an impl block
+    .note = replace `Self` with a different type
diff --git a/compiler/rustc_error_messages/locales/en-US/middle.ftl b/compiler/rustc_error_messages/locales/en-US/middle.ftl
index b9e4499d47f..81d8e8a473b 100644
--- a/compiler/rustc_error_messages/locales/en-US/middle.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/middle.ftl
@@ -27,3 +27,7 @@ middle_values_too_big =
 
 middle_cannot_be_normalized =
     unable to determine layout for `{$ty}` because `{$failure_ty}` cannot be normalized
+
+middle_strict_coherence_needs_negative_coherence =
+    to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled
+    .label = due to this attribute
diff --git a/compiler/rustc_error_messages/locales/en-US/monomorphize.ftl b/compiler/rustc_error_messages/locales/en-US/monomorphize.ftl
index 42c84fdd2d1..48ddb54b79e 100644
--- a/compiler/rustc_error_messages/locales/en-US/monomorphize.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/monomorphize.ftl
@@ -21,6 +21,3 @@ monomorphize_large_assignments =
     moving {$size} bytes
     .label = value moved from here
     .note = The current maximum size is {$limit}, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
-
-monomorphize_requires_lang_item =
-    requires `{$lang_item}` lang_item
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 4facb6140a3..7900f150048 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -388,6 +388,9 @@ declare_features! (
     (active, exclusive_range_pattern, "1.11.0", Some(37854), None),
     /// Allows exhaustive pattern matching on types that contain uninhabited types.
     (active, exhaustive_patterns, "1.13.0", Some(51085), None),
+    /// Allows using `efiapi`, `sysv64` and `win64` as calling convention
+    /// for functions with varargs.
+    (active, extended_varargs_abi_support, "1.65.0", Some(100189), None),
     /// Allows defining `extern type`s.
     (active, extern_types, "1.23.0", Some(43467), None),
     /// Allows the use of `#[ffi_const]` on foreign functions.
@@ -412,6 +415,8 @@ declare_features! (
     (active, half_open_range_patterns_in_slices, "CURRENT_RUSTC_VERSION", Some(67264), None),
     /// Allows `if let` guard in match arms.
     (active, if_let_guard, "1.47.0", Some(51114), None),
+    /// Allows `impl Trait` as output type in `Fn` traits in return position of functions.
+    (active, impl_trait_in_fn_trait_return, "1.64.0", Some(99697), None),
     /// Allows using imported `main` function
     (active, imported_main, "1.53.0", Some(28937), None),
     /// Allows associated types in inherent impls.
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index bc149e48d89..ef00c1ffc30 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -2207,14 +2207,14 @@ pub struct FnSig<'hir> {
 // so it can fetched later.
 #[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
 pub struct TraitItemId {
-    pub def_id: OwnerId,
+    pub owner_id: OwnerId,
 }
 
 impl TraitItemId {
     #[inline]
     pub fn hir_id(&self) -> HirId {
         // Items are always HIR owners.
-        HirId::make_owner(self.def_id.def_id)
+        HirId::make_owner(self.owner_id.def_id)
     }
 }
 
@@ -2225,7 +2225,7 @@ impl TraitItemId {
 #[derive(Debug, HashStable_Generic)]
 pub struct TraitItem<'hir> {
     pub ident: Ident,
-    pub def_id: OwnerId,
+    pub owner_id: OwnerId,
     pub generics: &'hir Generics<'hir>,
     pub kind: TraitItemKind<'hir>,
     pub span: Span,
@@ -2236,11 +2236,11 @@ impl TraitItem<'_> {
     #[inline]
     pub fn hir_id(&self) -> HirId {
         // Items are always HIR owners.
-        HirId::make_owner(self.def_id.def_id)
+        HirId::make_owner(self.owner_id.def_id)
     }
 
     pub fn trait_item_id(&self) -> TraitItemId {
-        TraitItemId { def_id: self.def_id }
+        TraitItemId { owner_id: self.owner_id }
     }
 }
 
@@ -2271,14 +2271,14 @@ pub enum TraitItemKind<'hir> {
 // so it can fetched later.
 #[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
 pub struct ImplItemId {
-    pub def_id: OwnerId,
+    pub owner_id: OwnerId,
 }
 
 impl ImplItemId {
     #[inline]
     pub fn hir_id(&self) -> HirId {
         // Items are always HIR owners.
-        HirId::make_owner(self.def_id.def_id)
+        HirId::make_owner(self.owner_id.def_id)
     }
 }
 
@@ -2286,7 +2286,7 @@ impl ImplItemId {
 #[derive(Debug, HashStable_Generic)]
 pub struct ImplItem<'hir> {
     pub ident: Ident,
-    pub def_id: OwnerId,
+    pub owner_id: OwnerId,
     pub generics: &'hir Generics<'hir>,
     pub kind: ImplItemKind<'hir>,
     pub defaultness: Defaultness,
@@ -2298,11 +2298,11 @@ impl ImplItem<'_> {
     #[inline]
     pub fn hir_id(&self) -> HirId {
         // Items are always HIR owners.
-        HirId::make_owner(self.def_id.def_id)
+        HirId::make_owner(self.owner_id.def_id)
     }
 
     pub fn impl_item_id(&self) -> ImplItemId {
-        ImplItemId { def_id: self.def_id }
+        ImplItemId { owner_id: self.owner_id }
     }
 }
 
@@ -2418,6 +2418,30 @@ impl<'hir> Ty<'hir> {
         }
         final_ty
     }
+
+    pub fn find_self_aliases(&self) -> Vec<Span> {
+        use crate::intravisit::Visitor;
+        struct MyVisitor(Vec<Span>);
+        impl<'v> Visitor<'v> for MyVisitor {
+            fn visit_ty(&mut self, t: &'v Ty<'v>) {
+                if matches!(
+                    &t.kind,
+                    TyKind::Path(QPath::Resolved(
+                        _,
+                        Path { res: crate::def::Res::SelfTyAlias { .. }, .. },
+                    ))
+                ) {
+                    self.0.push(t.span);
+                    return;
+                }
+                crate::intravisit::walk_ty(self, t);
+            }
+        }
+
+        let mut my_visitor = MyVisitor(vec![]);
+        my_visitor.visit_ty(self);
+        my_visitor.0
+    }
 }
 
 /// Not represented directly in the AST; referred to by name through a `ty_path`.
@@ -2890,14 +2914,14 @@ impl<'hir> VariantData<'hir> {
 // so it can fetched later.
 #[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
 pub struct ItemId {
-    pub def_id: OwnerId,
+    pub owner_id: OwnerId,
 }
 
 impl ItemId {
     #[inline]
     pub fn hir_id(&self) -> HirId {
         // Items are always HIR owners.
-        HirId::make_owner(self.def_id.def_id)
+        HirId::make_owner(self.owner_id.def_id)
     }
 }
 
@@ -2907,7 +2931,7 @@ impl ItemId {
 #[derive(Debug, HashStable_Generic)]
 pub struct Item<'hir> {
     pub ident: Ident,
-    pub def_id: OwnerId,
+    pub owner_id: OwnerId,
     pub kind: ItemKind<'hir>,
     pub span: Span,
     pub vis_span: Span,
@@ -2917,11 +2941,11 @@ impl Item<'_> {
     #[inline]
     pub fn hir_id(&self) -> HirId {
         // Items are always HIR owners.
-        HirId::make_owner(self.def_id.def_id)
+        HirId::make_owner(self.owner_id.def_id)
     }
 
     pub fn item_id(&self) -> ItemId {
-        ItemId { def_id: self.def_id }
+        ItemId { owner_id: self.owner_id }
     }
 }
 
@@ -3134,14 +3158,14 @@ pub enum AssocItemKind {
 // so it can fetched later.
 #[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
 pub struct ForeignItemId {
-    pub def_id: OwnerId,
+    pub owner_id: OwnerId,
 }
 
 impl ForeignItemId {
     #[inline]
     pub fn hir_id(&self) -> HirId {
         // Items are always HIR owners.
-        HirId::make_owner(self.def_id.def_id)
+        HirId::make_owner(self.owner_id.def_id)
     }
 }
 
@@ -3162,7 +3186,7 @@ pub struct ForeignItemRef {
 pub struct ForeignItem<'hir> {
     pub ident: Ident,
     pub kind: ForeignItemKind<'hir>,
-    pub def_id: OwnerId,
+    pub owner_id: OwnerId,
     pub span: Span,
     pub vis_span: Span,
 }
@@ -3171,11 +3195,11 @@ impl ForeignItem<'_> {
     #[inline]
     pub fn hir_id(&self) -> HirId {
         // Items are always HIR owners.
-        HirId::make_owner(self.def_id.def_id)
+        HirId::make_owner(self.owner_id.def_id)
     }
 
     pub fn foreign_item_id(&self) -> ForeignItemId {
-        ForeignItemId { def_id: self.def_id }
+        ForeignItemId { owner_id: self.owner_id }
     }
 }
 
@@ -3267,10 +3291,10 @@ impl<'hir> OwnerNode<'hir> {
 
     pub fn def_id(self) -> OwnerId {
         match self {
-            OwnerNode::Item(Item { def_id, .. })
-            | OwnerNode::TraitItem(TraitItem { def_id, .. })
-            | OwnerNode::ImplItem(ImplItem { def_id, .. })
-            | OwnerNode::ForeignItem(ForeignItem { def_id, .. }) => *def_id,
+            OwnerNode::Item(Item { owner_id, .. })
+            | OwnerNode::TraitItem(TraitItem { owner_id, .. })
+            | OwnerNode::ImplItem(ImplItem { owner_id, .. })
+            | OwnerNode::ForeignItem(ForeignItem { owner_id, .. }) => *owner_id,
             OwnerNode::Crate(..) => crate::CRATE_HIR_ID.owner,
         }
     }
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index f3bde099b13..9ee5e25c9bf 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -410,12 +410,7 @@ pub trait Visitor<'v>: Sized {
         walk_inf(self, inf);
     }
     fn visit_generic_arg(&mut self, generic_arg: &'v GenericArg<'v>) {
-        match generic_arg {
-            GenericArg::Lifetime(lt) => self.visit_lifetime(lt),
-            GenericArg::Type(ty) => self.visit_ty(ty),
-            GenericArg::Const(ct) => self.visit_anon_const(&ct.value),
-            GenericArg::Infer(inf) => self.visit_infer(inf),
-        }
+        walk_generic_arg(self, generic_arg);
     }
     fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
         walk_lifetime(self, lifetime)
@@ -480,6 +475,15 @@ pub fn walk_label<'v, V: Visitor<'v>>(visitor: &mut V, label: &'v Label) {
     visitor.visit_ident(label.ident);
 }
 
+pub fn walk_generic_arg<'v, V: Visitor<'v>>(visitor: &mut V, generic_arg: &'v GenericArg<'v>) {
+    match generic_arg {
+        GenericArg::Lifetime(lt) => visitor.visit_lifetime(lt),
+        GenericArg::Type(ty) => visitor.visit_ty(ty),
+        GenericArg::Const(ct) => visitor.visit_anon_const(&ct.value),
+        GenericArg::Infer(inf) => visitor.visit_infer(inf),
+    }
+}
+
 pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) {
     visitor.visit_id(lifetime.hir_id);
     match lifetime.name {
@@ -912,7 +916,7 @@ pub fn walk_fn<'v, V: Visitor<'v>>(
 
 pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem<'v>) {
     // N.B., deliberately force a compilation error if/when new fields are added.
-    let TraitItem { ident, generics, ref defaultness, ref kind, span, def_id: _ } = *trait_item;
+    let TraitItem { ident, generics, ref defaultness, ref kind, span, owner_id: _ } = *trait_item;
     let hir_id = trait_item.hir_id();
     visitor.visit_ident(ident);
     visitor.visit_generics(&generics);
@@ -952,7 +956,7 @@ pub fn walk_trait_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_item_ref:
 pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem<'v>) {
     // N.B., deliberately force a compilation error if/when new fields are added.
     let ImplItem {
-        def_id: _,
+        owner_id: _,
         ident,
         ref generics,
         ref kind,
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index ca615a4912a..72ed73e81b4 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -12,35 +12,56 @@ use crate::errors::LangItemError;
 use crate::{MethodKind, Target};
 
 use rustc_ast as ast;
-use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_macros::HashStable_Generic;
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::Span;
 
-use std::sync::LazyLock;
-
-pub enum LangItemGroup {
-    Op,
-    Fn,
+/// All of the language items, defined or not.
+/// Defined lang items can come from the current crate or its dependencies.
+#[derive(HashStable_Generic, Debug)]
+pub struct LanguageItems {
+    /// Mappings from lang items to their possibly found [`DefId`]s.
+    /// The index corresponds to the order in [`LangItem`].
+    items: [Option<DefId>; std::mem::variant_count::<LangItem>()],
+    /// Lang items that were not found during collection.
+    pub missing: Vec<LangItem>,
 }
 
-const NUM_GROUPS: usize = 2;
+impl LanguageItems {
+    /// Construct an empty collection of lang items and no missing ones.
+    pub fn new() -> Self {
+        Self { items: [None; std::mem::variant_count::<LangItem>()], missing: Vec::new() }
+    }
+
+    pub fn get(&self, item: LangItem) -> Option<DefId> {
+        self.items[item as usize]
+    }
 
-macro_rules! expand_group {
-    () => {
-        None
-    };
-    ($group:expr) => {
-        Some($group)
-    };
+    pub fn set(&mut self, item: LangItem, def_id: DefId) {
+        self.items[item as usize] = Some(def_id);
+    }
+
+    /// Requires that a given `LangItem` was bound and returns the corresponding `DefId`.
+    /// If it wasn't bound, e.g. due to a missing `#[lang = "<it.name()>"]`,
+    /// returns an error encapsulating the `LangItem`.
+    pub fn require(&self, it: LangItem) -> Result<DefId, LangItemError> {
+        self.get(it).ok_or_else(|| LangItemError(it))
+    }
+
+    pub fn iter<'a>(&'a self) -> impl Iterator<Item = (LangItem, DefId)> + 'a {
+        self.items
+            .iter()
+            .enumerate()
+            .filter_map(|(i, id)| id.map(|id| (LangItem::from_u32(i as u32).unwrap(), id)))
+    }
 }
 
 // The actual lang items defined come at the end of this file in one handy table.
 // So you probably just want to nip down to the end.
 macro_rules! language_item_table {
     (
-        $( $(#[$attr:meta])* $variant:ident $($group:expr)?, $module:ident :: $name:ident, $method:ident, $target:expr, $generics:expr; )*
+        $( $(#[$attr:meta])* $variant:ident, $module:ident :: $name:ident, $method:ident, $target:expr, $generics:expr; )*
     ) => {
 
         enum_from_u32! {
@@ -66,12 +87,17 @@ macro_rules! language_item_table {
                 }
             }
 
-            /// The [group](LangItemGroup) that this lang item belongs to,
-            /// or `None` if it doesn't belong to a group.
-            pub fn group(self) -> Option<LangItemGroup> {
-                use LangItemGroup::*;
+            /// Opposite of [`LangItem::name`]
+            pub fn from_name(name: Symbol) -> Option<Self> {
+                match name {
+                    $( $module::$name => Some(LangItem::$variant), )*
+                    _ => None,
+                }
+            }
+
+            pub fn target(self) -> Target {
                 match self {
-                    $( LangItem::$variant => expand_group!($($group)*), )*
+                    $( LangItem::$variant => $target, )*
                 }
             }
 
@@ -82,50 +108,7 @@ macro_rules! language_item_table {
             }
         }
 
-        /// All of the language items, defined or not.
-        /// Defined lang items can come from the current crate or its dependencies.
-        #[derive(HashStable_Generic, Debug)]
-        pub struct LanguageItems {
-            /// Mappings from lang items to their possibly found [`DefId`]s.
-            /// The index corresponds to the order in [`LangItem`].
-            pub items: Vec<Option<DefId>>,
-            /// Lang items that were not found during collection.
-            pub missing: Vec<LangItem>,
-            /// Mapping from [`LangItemGroup`] discriminants to all
-            /// [`DefId`]s of lang items in that group.
-            pub groups: [Vec<DefId>; NUM_GROUPS],
-        }
-
         impl LanguageItems {
-            /// Construct an empty collection of lang items and no missing ones.
-            pub fn new() -> Self {
-                fn init_none(_: LangItem) -> Option<DefId> { None }
-                const EMPTY: Vec<DefId> = Vec::new();
-
-                Self {
-                    items: vec![$(init_none(LangItem::$variant)),*],
-                    missing: Vec::new(),
-                    groups: [EMPTY; NUM_GROUPS],
-                }
-            }
-
-            /// Returns the mappings to the possibly found `DefId`s for each lang item.
-            pub fn items(&self) -> &[Option<DefId>] {
-                &*self.items
-            }
-
-            /// Requires that a given `LangItem` was bound and returns the corresponding `DefId`.
-            /// If it wasn't bound, e.g. due to a missing `#[lang = "<it.name()>"]`,
-            /// returns an error encapsulating the `LangItem`.
-            pub fn require(&self, it: LangItem) -> Result<DefId, LangItemError> {
-                self.items[it as usize].ok_or_else(|| LangItemError(it))
-            }
-
-            /// Returns the [`DefId`]s of all lang items in a group.
-            pub fn group(&self, group: LangItemGroup) -> &[DefId] {
-                self.groups[group as usize].as_ref()
-            }
-
             $(
                 #[doc = concat!("Returns the [`DefId`] of the `", stringify!($name), "` lang item if it is defined.")]
                 pub fn $method(&self) -> Option<DefId> {
@@ -133,15 +116,6 @@ macro_rules! language_item_table {
                 }
             )*
         }
-
-        /// A mapping from the name of the lang item to its order and the form it must be of.
-        pub static ITEM_REFS: LazyLock<FxIndexMap<Symbol, (usize, Target)>> = LazyLock::new(|| {
-            let mut item_refs = FxIndexMap::default();
-            $( item_refs.insert($module::$name, (LangItem::$variant as usize, $target)); )*
-            item_refs
-        });
-
-// End of the macro
     }
 }
 
@@ -196,30 +170,30 @@ language_item_table! {
     TransmuteOpts,           sym::transmute_opts,      transmute_opts,             Target::Struct,         GenericRequirement::Exact(0);
     TransmuteTrait,          sym::transmute_trait,     transmute_trait,            Target::Trait,          GenericRequirement::Exact(3);
 
-    Add(Op),                 sym::add,                 add_trait,                  Target::Trait,          GenericRequirement::Exact(1);
-    Sub(Op),                 sym::sub,                 sub_trait,                  Target::Trait,          GenericRequirement::Exact(1);
-    Mul(Op),                 sym::mul,                 mul_trait,                  Target::Trait,          GenericRequirement::Exact(1);
-    Div(Op),                 sym::div,                 div_trait,                  Target::Trait,          GenericRequirement::Exact(1);
-    Rem(Op),                 sym::rem,                 rem_trait,                  Target::Trait,          GenericRequirement::Exact(1);
-    Neg(Op),                 sym::neg,                 neg_trait,                  Target::Trait,          GenericRequirement::Exact(0);
-    Not(Op),                 sym::not,                 not_trait,                  Target::Trait,          GenericRequirement::Exact(0);
-    BitXor(Op),              sym::bitxor,              bitxor_trait,               Target::Trait,          GenericRequirement::Exact(1);
-    BitAnd(Op),              sym::bitand,              bitand_trait,               Target::Trait,          GenericRequirement::Exact(1);
-    BitOr(Op),               sym::bitor,               bitor_trait,                Target::Trait,          GenericRequirement::Exact(1);
-    Shl(Op),                 sym::shl,                 shl_trait,                  Target::Trait,          GenericRequirement::Exact(1);
-    Shr(Op),                 sym::shr,                 shr_trait,                  Target::Trait,          GenericRequirement::Exact(1);
-    AddAssign(Op),           sym::add_assign,          add_assign_trait,           Target::Trait,          GenericRequirement::Exact(1);
-    SubAssign(Op),           sym::sub_assign,          sub_assign_trait,           Target::Trait,          GenericRequirement::Exact(1);
-    MulAssign(Op),           sym::mul_assign,          mul_assign_trait,           Target::Trait,          GenericRequirement::Exact(1);
-    DivAssign(Op),           sym::div_assign,          div_assign_trait,           Target::Trait,          GenericRequirement::Exact(1);
-    RemAssign(Op),           sym::rem_assign,          rem_assign_trait,           Target::Trait,          GenericRequirement::Exact(1);
-    BitXorAssign(Op),        sym::bitxor_assign,       bitxor_assign_trait,        Target::Trait,          GenericRequirement::Exact(1);
-    BitAndAssign(Op),        sym::bitand_assign,       bitand_assign_trait,        Target::Trait,          GenericRequirement::Exact(1);
-    BitOrAssign(Op),         sym::bitor_assign,        bitor_assign_trait,         Target::Trait,          GenericRequirement::Exact(1);
-    ShlAssign(Op),           sym::shl_assign,          shl_assign_trait,           Target::Trait,          GenericRequirement::Exact(1);
-    ShrAssign(Op),           sym::shr_assign,          shr_assign_trait,           Target::Trait,          GenericRequirement::Exact(1);
-    Index(Op),               sym::index,               index_trait,                Target::Trait,          GenericRequirement::Exact(1);
-    IndexMut(Op),            sym::index_mut,           index_mut_trait,            Target::Trait,          GenericRequirement::Exact(1);
+    Add,                     sym::add,                 add_trait,                  Target::Trait,          GenericRequirement::Exact(1);
+    Sub,                     sym::sub,                 sub_trait,                  Target::Trait,          GenericRequirement::Exact(1);
+    Mul,                     sym::mul,                 mul_trait,                  Target::Trait,          GenericRequirement::Exact(1);
+    Div,                     sym::div,                 div_trait,                  Target::Trait,          GenericRequirement::Exact(1);
+    Rem,                     sym::rem,                 rem_trait,                  Target::Trait,          GenericRequirement::Exact(1);
+    Neg,                     sym::neg,                 neg_trait,                  Target::Trait,          GenericRequirement::Exact(0);
+    Not,                     sym::not,                 not_trait,                  Target::Trait,          GenericRequirement::Exact(0);
+    BitXor,                  sym::bitxor,              bitxor_trait,               Target::Trait,          GenericRequirement::Exact(1);
+    BitAnd,                  sym::bitand,              bitand_trait,               Target::Trait,          GenericRequirement::Exact(1);
+    BitOr,                   sym::bitor,               bitor_trait,                Target::Trait,          GenericRequirement::Exact(1);
+    Shl,                     sym::shl,                 shl_trait,                  Target::Trait,          GenericRequirement::Exact(1);
+    Shr,                     sym::shr,                 shr_trait,                  Target::Trait,          GenericRequirement::Exact(1);
+    AddAssign,               sym::add_assign,          add_assign_trait,           Target::Trait,          GenericRequirement::Exact(1);
+    SubAssign,               sym::sub_assign,          sub_assign_trait,           Target::Trait,          GenericRequirement::Exact(1);
+    MulAssign,               sym::mul_assign,          mul_assign_trait,           Target::Trait,          GenericRequirement::Exact(1);
+    DivAssign,               sym::div_assign,          div_assign_trait,           Target::Trait,          GenericRequirement::Exact(1);
+    RemAssign,               sym::rem_assign,          rem_assign_trait,           Target::Trait,          GenericRequirement::Exact(1);
+    BitXorAssign,            sym::bitxor_assign,       bitxor_assign_trait,        Target::Trait,          GenericRequirement::Exact(1);
+    BitAndAssign,            sym::bitand_assign,       bitand_assign_trait,        Target::Trait,          GenericRequirement::Exact(1);
+    BitOrAssign,             sym::bitor_assign,        bitor_assign_trait,         Target::Trait,          GenericRequirement::Exact(1);
+    ShlAssign,               sym::shl_assign,          shl_assign_trait,           Target::Trait,          GenericRequirement::Exact(1);
+    ShrAssign,               sym::shr_assign,          shr_assign_trait,           Target::Trait,          GenericRequirement::Exact(1);
+    Index,                   sym::index,               index_trait,                Target::Trait,          GenericRequirement::Exact(1);
+    IndexMut,                sym::index_mut,           index_mut_trait,            Target::Trait,          GenericRequirement::Exact(1);
 
     UnsafeCell,              sym::unsafe_cell,         unsafe_cell_type,           Target::Struct,         GenericRequirement::None;
     VaList,                  sym::va_list,             va_list,                    Target::Struct,         GenericRequirement::None;
@@ -229,9 +203,9 @@ language_item_table! {
     DerefTarget,             sym::deref_target,        deref_target,               Target::AssocTy,        GenericRequirement::None;
     Receiver,                sym::receiver,            receiver_trait,             Target::Trait,          GenericRequirement::None;
 
-    Fn(Fn),                  kw::Fn,                   fn_trait,                   Target::Trait,          GenericRequirement::Exact(1);
-    FnMut(Fn),               sym::fn_mut,              fn_mut_trait,               Target::Trait,          GenericRequirement::Exact(1);
-    FnOnce(Fn),              sym::fn_once,             fn_once_trait,              Target::Trait,          GenericRequirement::Exact(1);
+    Fn,                      kw::Fn,                   fn_trait,                   Target::Trait,          GenericRequirement::Exact(1);
+    FnMut,                   sym::fn_mut,              fn_mut_trait,               Target::Trait,          GenericRequirement::Exact(1);
+    FnOnce,                  sym::fn_once,             fn_once_trait,              Target::Trait,          GenericRequirement::Exact(1);
 
     FnOnceOutput,            sym::fn_once_output,      fn_once_output,             Target::AssocTy,        GenericRequirement::None;
 
@@ -241,8 +215,8 @@ language_item_table! {
     Unpin,                   sym::unpin,               unpin_trait,                Target::Trait,          GenericRequirement::None;
     Pin,                     sym::pin,                 pin_type,                   Target::Struct,         GenericRequirement::None;
 
-    PartialEq(Op),           sym::eq,                  eq_trait,                   Target::Trait,          GenericRequirement::Exact(1);
-    PartialOrd(Op),          sym::partial_ord,         partial_ord_trait,          Target::Trait,          GenericRequirement::Exact(1);
+    PartialEq,               sym::eq,                  eq_trait,                   Target::Trait,          GenericRequirement::Exact(1);
+    PartialOrd,              sym::partial_ord,         partial_ord_trait,          Target::Trait,          GenericRequirement::Exact(1);
 
     // A number of panic-related lang items. The `panic` item corresponds to divide-by-zero and
     // various panic cases with `match`. The `panic_bounds_check` item is for indexing arrays.
@@ -338,3 +312,34 @@ pub enum GenericRequirement {
     Minimum(usize),
     Exact(usize),
 }
+
+pub static FN_TRAITS: &'static [LangItem] = &[LangItem::Fn, LangItem::FnMut, LangItem::FnOnce];
+
+pub static OPERATORS: &'static [LangItem] = &[
+    LangItem::Add,
+    LangItem::Sub,
+    LangItem::Mul,
+    LangItem::Div,
+    LangItem::Rem,
+    LangItem::Neg,
+    LangItem::Not,
+    LangItem::BitXor,
+    LangItem::BitAnd,
+    LangItem::BitOr,
+    LangItem::Shl,
+    LangItem::Shr,
+    LangItem::AddAssign,
+    LangItem::SubAssign,
+    LangItem::MulAssign,
+    LangItem::DivAssign,
+    LangItem::RemAssign,
+    LangItem::BitXorAssign,
+    LangItem::BitAndAssign,
+    LangItem::BitOrAssign,
+    LangItem::ShlAssign,
+    LangItem::ShrAssign,
+    LangItem::Index,
+    LangItem::IndexMut,
+    LangItem::PartialEq,
+    LangItem::PartialOrd,
+];
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index 1c4aa420c9b..1c55cd8fee8 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -5,10 +5,10 @@
 #![feature(associated_type_defaults)]
 #![feature(closure_track_caller)]
 #![feature(const_btree_len)]
-#![feature(once_cell)]
 #![feature(min_specialization)]
 #![feature(never_type)]
 #![feature(rustc_attrs)]
+#![feature(variant_count)]
 #![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs
index 06b7a65662e..23423e8f3b3 100644
--- a/compiler/rustc_hir/src/stable_hash_impls.rs
+++ b/compiler/rustc_hir/src/stable_hash_impls.rs
@@ -49,7 +49,7 @@ impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ItemId {
 
     #[inline]
     fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
-        self.def_id.def_id.to_stable_hash_key(hcx)
+        self.owner_id.def_id.to_stable_hash_key(hcx)
     }
 }
 
@@ -58,7 +58,7 @@ impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for TraitItemId {
 
     #[inline]
     fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
-        self.def_id.def_id.to_stable_hash_key(hcx)
+        self.owner_id.def_id.to_stable_hash_key(hcx)
     }
 }
 
@@ -67,7 +67,7 @@ impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ImplItemId {
 
     #[inline]
     fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
-        self.def_id.def_id.to_stable_hash_key(hcx)
+        self.owner_id.def_id.to_stable_hash_key(hcx)
     }
 }
 
@@ -76,7 +76,7 @@ impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ForeignItemId
 
     #[inline]
     fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
-        self.def_id.def_id.to_stable_hash_key(hcx)
+        self.owner_id.def_id.to_stable_hash_key(hcx)
     }
 }
 
diff --git a/compiler/rustc_hir/src/weak_lang_items.rs b/compiler/rustc_hir/src/weak_lang_items.rs
index da9c9c1216e..d8e5dd4ffdc 100644
--- a/compiler/rustc_hir/src/weak_lang_items.rs
+++ b/compiler/rustc_hir/src/weak_lang_items.rs
@@ -1,53 +1,31 @@
 //! Validity checking for weak lang items
 
-use crate::def_id::DefId;
-use crate::{lang_items, LangItem, LanguageItems};
+use crate::LangItem;
 
-use rustc_ast as ast;
-use rustc_data_structures::fx::FxIndexMap;
 use rustc_span::symbol::{sym, Symbol};
 
-use std::sync::LazyLock;
-
 macro_rules! weak_lang_items {
-    ($($name:ident, $item:ident, $sym:ident;)*) => (
-
-pub static WEAK_ITEMS_REFS: LazyLock<FxIndexMap<Symbol, LangItem>> = LazyLock::new(|| {
-    let mut map = FxIndexMap::default();
-    $(map.insert(sym::$name, LangItem::$item);)*
-    map
-});
-
-pub static WEAK_ITEMS_SYMBOLS: LazyLock<FxIndexMap<LangItem, Symbol>> = LazyLock::new(|| {
-    let mut map = FxIndexMap::default();
-    $(map.insert(LangItem::$item, sym::$sym);)*
-    map
-});
-
-pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol>
-{
-    lang_items::extract(attrs).and_then(|(name, _)| {
-        $(if name == sym::$name {
-            Some(sym::$sym)
-        } else)* {
-            None
+    ($($item:ident, $sym:ident;)*) => {
+        pub static WEAK_LANG_ITEMS: &[LangItem] = &[$(LangItem::$item,)*];
+
+        impl LangItem {
+            pub fn is_weak(self) -> bool {
+                matches!(self, $(LangItem::$item)|*)
+            }
+
+            pub fn link_name(self) -> Option<Symbol> {
+                match self {
+                    $( LangItem::$item => Some(sym::$sym),)*
+                    _ => None,
+                }
+            }
         }
-    })
-}
-
-impl LanguageItems {
-    pub fn is_weak_lang_item(&self, item_def_id: DefId) -> bool {
-        let did = Some(item_def_id);
-
-        $(self.$name() == did)||*
     }
 }
 
-) }
-
 weak_lang_items! {
-    panic_impl,         PanicImpl,          rust_begin_unwind;
-    eh_personality,     EhPersonality,      rust_eh_personality;
-    eh_catch_typeinfo,  EhCatchTypeinfo,    rust_eh_catch_typeinfo;
-    oom,                Oom,                rust_oom;
+    PanicImpl,          rust_begin_unwind;
+    EhPersonality,      rust_eh_personality;
+    EhCatchTypeinfo,    rust_eh_catch_typeinfo;
+    Oom,                rust_oom;
 }
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 6baf9844977..39b178f5976 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -23,7 +23,6 @@ use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{walk_generics, Visitor as _};
-use rustc_hir::lang_items::LangItem;
 use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
 use rustc_middle::middle::stability::AllowUnstable;
 use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
@@ -884,9 +883,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             }
         }
 
-        let sized_def_id = tcx.lang_items().require(LangItem::Sized);
+        let sized_def_id = tcx.lang_items().sized_trait();
         match (&sized_def_id, unbound) {
-            (Ok(sized_def_id), Some(tpb))
+            (Some(sized_def_id), Some(tpb))
                 if tpb.path.res == Res::Def(DefKind::Trait, *sized_def_id) =>
             {
                 // There was in fact a `?Sized` bound, return without doing anything
@@ -906,7 +905,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 // There was no `?Sized` bound; add implicitly sized if `Sized` is available.
             }
         }
-        if sized_def_id.is_err() {
+        if sized_def_id.is_none() {
             // No lang item for `Sized`, so we can't add it as a bound.
             return;
         }
@@ -2661,7 +2660,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             }
             hir::TyKind::OpaqueDef(item_id, lifetimes, in_trait) => {
                 let opaque_ty = tcx.hir().item(item_id);
-                let def_id = item_id.def_id.to_def_id();
+                let def_id = item_id.owner_id.to_def_id();
 
                 match opaque_ty.kind {
                     hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index b302cee4816..b70ac02058d 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -114,7 +114,7 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
                 _ => {
                     // Fallback case: allow `ManuallyDrop` and things that are `Copy`.
                     ty.ty_adt_def().is_some_and(|adt_def| adt_def.is_manually_drop())
-                        || ty.is_copy_modulo_regions(tcx.at(span), param_env)
+                        || ty.is_copy_modulo_regions(tcx, param_env)
                 }
             }
         }
@@ -227,17 +227,17 @@ fn check_opaque<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
         return;
     }
 
-    let substs = InternalSubsts::identity_for_item(tcx, item.def_id.to_def_id());
-    let span = tcx.def_span(item.def_id.def_id);
+    let substs = InternalSubsts::identity_for_item(tcx, item.owner_id.to_def_id());
+    let span = tcx.def_span(item.owner_id.def_id);
 
-    check_opaque_for_inheriting_lifetimes(tcx, item.def_id.def_id, span);
-    if tcx.type_of(item.def_id.def_id).references_error() {
+    check_opaque_for_inheriting_lifetimes(tcx, item.owner_id.def_id, span);
+    if tcx.type_of(item.owner_id.def_id).references_error() {
         return;
     }
-    if check_opaque_for_cycles(tcx, item.def_id.def_id, substs, span, &origin).is_err() {
+    if check_opaque_for_cycles(tcx, item.owner_id.def_id, substs, span, &origin).is_err() {
         return;
     }
-    check_opaque_meets_bounds(tcx, item.def_id.def_id, substs, span, &origin);
+    check_opaque_meets_bounds(tcx, item.owner_id.def_id, substs, span, &origin);
 }
 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
 /// in "inheriting lifetimes".
@@ -492,25 +492,25 @@ fn check_opaque_meets_bounds<'tcx>(
 fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
     debug!(
         "check_item_type(it.def_id={:?}, it.name={})",
-        id.def_id,
-        tcx.def_path_str(id.def_id.to_def_id())
+        id.owner_id,
+        tcx.def_path_str(id.owner_id.to_def_id())
     );
     let _indenter = indenter();
-    match tcx.def_kind(id.def_id) {
+    match tcx.def_kind(id.owner_id) {
         DefKind::Static(..) => {
-            tcx.ensure().typeck(id.def_id.def_id);
-            maybe_check_static_with_link_section(tcx, id.def_id.def_id);
-            check_static_inhabited(tcx, id.def_id.def_id);
+            tcx.ensure().typeck(id.owner_id.def_id);
+            maybe_check_static_with_link_section(tcx, id.owner_id.def_id);
+            check_static_inhabited(tcx, id.owner_id.def_id);
         }
         DefKind::Const => {
-            tcx.ensure().typeck(id.def_id.def_id);
+            tcx.ensure().typeck(id.owner_id.def_id);
         }
         DefKind::Enum => {
             let item = tcx.hir().item(id);
             let hir::ItemKind::Enum(ref enum_definition, _) = item.kind else {
                 return;
             };
-            check_enum(tcx, &enum_definition.variants, item.def_id.def_id);
+            check_enum(tcx, &enum_definition.variants, item.owner_id.def_id);
         }
         DefKind::Fn => {} // entirely within check_item_body
         DefKind::Impl => {
@@ -518,12 +518,12 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
             let hir::ItemKind::Impl(ref impl_) = it.kind else {
                 return;
             };
-            debug!("ItemKind::Impl {} with id {:?}", it.ident, it.def_id);
-            if let Some(impl_trait_ref) = tcx.impl_trait_ref(it.def_id) {
+            debug!("ItemKind::Impl {} with id {:?}", it.ident, it.owner_id);
+            if let Some(impl_trait_ref) = tcx.impl_trait_ref(it.owner_id) {
                 check_impl_items_against_trait(
                     tcx,
                     it.span,
-                    it.def_id.def_id,
+                    it.owner_id.def_id,
                     impl_trait_ref,
                     &impl_.items,
                 );
@@ -545,15 +545,15 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
                         fn_maybe_err(tcx, item.ident.span, abi);
                     }
                     hir::TraitItemKind::Type(.., Some(default)) => {
-                        let assoc_item = tcx.associated_item(item.def_id);
+                        let assoc_item = tcx.associated_item(item.owner_id);
                         let trait_substs =
-                            InternalSubsts::identity_for_item(tcx, it.def_id.to_def_id());
+                            InternalSubsts::identity_for_item(tcx, it.owner_id.to_def_id());
                         let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
                             tcx,
                             assoc_item,
                             assoc_item,
                             default.span,
-                            ty::TraitRef { def_id: it.def_id.to_def_id(), substs: trait_substs },
+                            ty::TraitRef { def_id: it.owner_id.to_def_id(), substs: trait_substs },
                         );
                     }
                     _ => {}
@@ -561,16 +561,16 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
             }
         }
         DefKind::Struct => {
-            check_struct(tcx, id.def_id.def_id);
+            check_struct(tcx, id.owner_id.def_id);
         }
         DefKind::Union => {
-            check_union(tcx, id.def_id.def_id);
+            check_union(tcx, id.owner_id.def_id);
         }
         DefKind::OpaqueTy => {
             check_opaque(tcx, id);
         }
         DefKind::ImplTraitPlaceholder => {
-            let parent = tcx.impl_trait_in_trait_parent(id.def_id.to_def_id());
+            let parent = tcx.impl_trait_in_trait_parent(id.owner_id.to_def_id());
             // Only check the validity of this opaque type if the function has a default body
             if let hir::Node::TraitItem(hir::TraitItem {
                 kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)),
@@ -581,8 +581,8 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
             }
         }
         DefKind::TyAlias => {
-            let pty_ty = tcx.type_of(id.def_id);
-            let generics = tcx.generics_of(id.def_id);
+            let pty_ty = tcx.type_of(id.owner_id);
+            let generics = tcx.generics_of(id.owner_id);
             check_type_params_are_used(tcx, &generics, pty_ty);
         }
         DefKind::ForeignMod => {
@@ -604,7 +604,7 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
                 }
             } else {
                 for item in items {
-                    let def_id = item.id.def_id.def_id;
+                    let def_id = item.id.owner_id.def_id;
                     let generics = tcx.generics_of(def_id);
                     let own_counts = generics.own_counts();
                     if generics.params.len() - own_counts.lifetimes != 0 {
@@ -659,7 +659,7 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
 
 pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
     // an error would be reported if this fails.
-    let _ = traits::OnUnimplementedDirective::of_item(tcx, item.def_id.to_def_id());
+    let _ = traits::OnUnimplementedDirective::of_item(tcx, item.owner_id.to_def_id());
 }
 
 pub(super) fn check_specialization_validity<'tcx>(
@@ -746,7 +746,7 @@ fn check_impl_items_against_trait<'tcx>(
     let trait_def = tcx.trait_def(impl_trait_ref.def_id);
 
     for impl_item in impl_item_refs {
-        let ty_impl_item = tcx.associated_item(impl_item.id.def_id);
+        let ty_impl_item = tcx.associated_item(impl_item.id.owner_id);
         let ty_trait_item = if let Some(trait_item_id) = ty_impl_item.trait_item_def_id {
             tcx.associated_item(trait_item_id)
         } else {
@@ -758,7 +758,7 @@ fn check_impl_items_against_trait<'tcx>(
         match impl_item_full.kind {
             hir::ImplItemKind::Const(..) => {
                 let _ = tcx.compare_assoc_const_impl_item_with_trait_item((
-                    impl_item.id.def_id.def_id,
+                    impl_item.id.owner_id.def_id,
                     ty_impl_item.trait_item_def_id.unwrap(),
                 ));
             }
diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs
index e72f18012ab..32f66b06f83 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_method.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs
@@ -597,7 +597,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
                 let num_trait_substs = trait_to_impl_substs.len();
                 let num_impl_substs = tcx.generics_of(impl_m.container_id(tcx)).params.len();
                 let ty = tcx.fold_regions(ty, |region, _| {
-                    let ty::ReFree(_) = region.kind() else { return region; };
+                    let (ty::ReFree(_) | ty::ReEarlyBound(_)) = region.kind() else { return region; };
                     let Some(ty::ReEarlyBound(e)) = map.get(&region.into()).map(|r| r.expect_region().kind())
                     else {
                         tcx
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 8be1cf04f8b..609095c9cea 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -26,7 +26,7 @@ fn equate_intrinsic_type<'tcx>(
 ) {
     let (own_counts, span) = match &it.kind {
         hir::ForeignItemKind::Fn(.., generics) => {
-            let own_counts = tcx.generics_of(it.def_id.to_def_id()).own_counts();
+            let own_counts = tcx.generics_of(it.owner_id.to_def_id()).own_counts();
             (own_counts, generics.span)
         }
         _ => {
@@ -57,7 +57,7 @@ fn equate_intrinsic_type<'tcx>(
     {
         let fty = tcx.mk_fn_ptr(sig);
         let cause = ObligationCause::new(it.span, it.hir_id(), ObligationCauseCode::IntrinsicType);
-        require_same_types(tcx, &cause, tcx.mk_fn_ptr(tcx.fn_sig(it.def_id)), fty);
+        require_same_types(tcx, &cause, tcx.mk_fn_ptr(tcx.fn_sig(it.owner_id)), fty);
     }
 }
 
@@ -129,7 +129,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: DefId) -> hir
 /// and in `library/core/src/intrinsics.rs`.
 pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
     let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n)));
-    let intrinsic_id = it.def_id.to_def_id();
+    let intrinsic_id = it.owner_id.to_def_id();
     let intrinsic_name = tcx.item_name(intrinsic_id);
     let name_str = intrinsic_name.as_str();
 
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index a026f8033c8..17c4d0d482f 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -33,7 +33,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
     fn is_thin_ptr_ty(&self, ty: Ty<'tcx>) -> bool {
         // Type still may have region variables, but `Sized` does not depend
         // on those, so just erase them before querying.
-        if ty.is_sized(self.tcx.at(DUMMY_SP), self.param_env) {
+        if ty.is_sized(self.tcx, self.param_env) {
             return true;
         }
         if let ty::Foreign(..) = ty.kind() {
@@ -128,7 +128,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
 
         // Check that the type implements Copy. The only case where this can
         // possibly fail is for SIMD types which don't #[derive(Copy)].
-        if !ty.is_copy_modulo_regions(self.tcx.at(expr.span), self.param_env) {
+        if !ty.is_copy_modulo_regions(self.tcx, self.param_env) {
             let msg = "arguments for inline assembly must be copyable";
             let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
             err.note(&format!("`{ty}` does not implement the Copy trait"));
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 70a171c02b2..a2357500465 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -147,10 +147,10 @@ fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) {
 /// the types first.
 #[instrument(skip(tcx), level = "debug")]
 fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
-    let def_id = item.def_id.def_id;
+    let def_id = item.owner_id.def_id;
 
     debug!(
-        ?item.def_id,
+        ?item.owner_id,
         item.name = ? tcx.def_path_str(def_id.to_def_id())
     );
 
@@ -246,10 +246,10 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
 }
 
 fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) {
-    let def_id = item.def_id.def_id;
+    let def_id = item.owner_id.def_id;
 
     debug!(
-        ?item.def_id,
+        ?item.owner_id,
         item.name = ? tcx.def_path_str(def_id.to_def_id())
     );
 
@@ -263,7 +263,7 @@ fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) {
 }
 
 fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) {
-    let def_id = trait_item.def_id.def_id;
+    let def_id = trait_item.owner_id.def_id;
 
     let (method_sig, span) = match trait_item.kind {
         hir::TraitItemKind::Fn(ref sig, _) => (Some(sig), trait_item.span),
@@ -275,7 +275,7 @@ fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) {
 
     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.def_id.to_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() {
@@ -348,7 +348,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
     loop {
         let mut should_continue = false;
         for gat_item in associated_items {
-            let gat_def_id = gat_item.id.def_id;
+            let gat_def_id = gat_item.id.owner_id;
             let gat_item = tcx.associated_item(gat_def_id);
             // If this item is not an assoc ty, or has no substs, then it's not a GAT
             if gat_item.kind != ty::AssocKind::Type {
@@ -365,7 +365,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
             // constrains the GAT with individually.
             let mut new_required_bounds: Option<FxHashSet<ty::Predicate<'_>>> = None;
             for item in associated_items {
-                let item_def_id = item.id.def_id;
+                let item_def_id = item.id.owner_id;
                 // Skip our own GAT, since it does not constrain itself at all.
                 if item_def_id == gat_def_id {
                     continue;
@@ -790,7 +790,7 @@ fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem
     let (trait_name, trait_def_id) =
         match tcx.hir().get_by_def_id(tcx.hir().get_parent_item(item.hir_id()).def_id) {
             hir::Node::Item(item) => match item.kind {
-                hir::ItemKind::Trait(..) => (item.ident, item.def_id),
+                hir::ItemKind::Trait(..) => (item.ident, item.owner_id),
                 _ => return,
             },
             _ => return,
@@ -845,7 +845,7 @@ fn check_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) {
         _ => (None, impl_item.span),
     };
 
-    check_associated_item(tcx, impl_item.def_id.def_id, span, method_sig);
+    check_associated_item(tcx, impl_item.owner_id.def_id, span, method_sig);
 }
 
 fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
@@ -1045,11 +1045,11 @@ fn check_type_defn<'tcx, F>(
 ) where
     F: FnMut(&WfCheckingCtxt<'_, 'tcx>) -> Vec<AdtVariant<'tcx>>,
 {
-    let _ = tcx.representability(item.def_id.def_id);
+    let _ = tcx.representability(item.owner_id.def_id);
 
-    enter_wf_checking_ctxt(tcx, item.span, item.def_id.def_id, |wfcx| {
+    enter_wf_checking_ctxt(tcx, item.span, item.owner_id.def_id, |wfcx| {
         let variants = lookup_fields(wfcx);
-        let packed = tcx.adt_def(item.def_id).repr().packed();
+        let packed = tcx.adt_def(item.owner_id).repr().packed();
 
         for variant in &variants {
             // All field types must be well-formed.
@@ -1073,7 +1073,7 @@ fn check_type_defn<'tcx, F>(
                         // Just treat unresolved type expression as if it needs drop.
                         true
                     } else {
-                        ty.needs_drop(tcx, tcx.param_env(item.def_id))
+                        ty.needs_drop(tcx, tcx.param_env(item.owner_id))
                     }
                 }
             };
@@ -1121,15 +1121,15 @@ fn check_type_defn<'tcx, F>(
             }
         }
 
-        check_where_clauses(wfcx, item.span, item.def_id.def_id);
+        check_where_clauses(wfcx, item.span, item.owner_id.def_id);
     });
 }
 
 #[instrument(skip(tcx, item))]
 fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
-    debug!(?item.def_id);
+    debug!(?item.owner_id);
 
-    let def_id = item.def_id.def_id;
+    let def_id = item.owner_id.def_id;
     let trait_def = tcx.trait_def(def_id);
     if trait_def.is_marker
         || matches!(trait_def.specialization_kind, TraitSpecializationKind::Marker)
@@ -1240,13 +1240,13 @@ fn check_impl<'tcx>(
     ast_trait_ref: &Option<hir::TraitRef<'_>>,
     constness: hir::Constness,
 ) {
-    enter_wf_checking_ctxt(tcx, item.span, item.def_id.def_id, |wfcx| {
+    enter_wf_checking_ctxt(tcx, item.span, item.owner_id.def_id, |wfcx| {
         match *ast_trait_ref {
             Some(ref ast_trait_ref) => {
                 // `#[rustc_reservation_impl]` impls are not real impls and
                 // therefore don't need to be WF (the trait's `Self: Trait` predicate
                 // won't hold).
-                let trait_ref = tcx.impl_trait_ref(item.def_id).unwrap();
+                let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap();
                 let trait_ref = wfcx.normalize(ast_trait_ref.path.span, None, trait_ref);
                 let trait_pred = ty::TraitPredicate {
                     trait_ref,
@@ -1268,7 +1268,7 @@ fn check_impl<'tcx>(
                 wfcx.register_obligations(obligations);
             }
             None => {
-                let self_ty = tcx.type_of(item.def_id);
+                let self_ty = tcx.type_of(item.owner_id);
                 let self_ty = wfcx.normalize(
                     item.span,
                     Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
@@ -1282,7 +1282,7 @@ fn check_impl<'tcx>(
             }
         }
 
-        check_where_clauses(wfcx, item.span, item.def_id.def_id);
+        check_where_clauses(wfcx, item.span, item.owner_id.def_id);
     });
 }
 
@@ -1778,14 +1778,14 @@ fn check_variances_for_type_defn<'tcx>(
     item: &hir::Item<'tcx>,
     hir_generics: &hir::Generics<'_>,
 ) {
-    let ty = tcx.type_of(item.def_id);
+    let ty = tcx.type_of(item.owner_id);
     if tcx.has_error_field(ty) {
         return;
     }
 
-    let ty_predicates = tcx.predicates_of(item.def_id);
+    let ty_predicates = tcx.predicates_of(item.owner_id);
     assert_eq!(ty_predicates.parent, None);
-    let variances = tcx.variances_of(item.def_id);
+    let variances = tcx.variances_of(item.owner_id);
 
     let mut constrained_parameters: FxHashSet<_> = variances
         .iter()
@@ -1798,7 +1798,7 @@ fn check_variances_for_type_defn<'tcx>(
 
     // Lazily calculated because it is only needed in case of an error.
     let explicitly_bounded_params = LazyCell::new(|| {
-        let icx = crate::collect::ItemCtxt::new(tcx, item.def_id.to_def_id());
+        let icx = crate::collect::ItemCtxt::new(tcx, item.owner_id.to_def_id());
         hir_generics
             .predicates
             .iter()
@@ -1919,10 +1919,10 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
 
 fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalDefId) {
     let items = tcx.hir_module_items(module);
-    items.par_items(|item| tcx.ensure().check_well_formed(item.def_id));
-    items.par_impl_items(|item| tcx.ensure().check_well_formed(item.def_id));
-    items.par_trait_items(|item| tcx.ensure().check_well_formed(item.def_id));
-    items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.def_id));
+    items.par_items(|item| tcx.ensure().check_well_formed(item.owner_id));
+    items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id));
+    items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id));
+    items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id));
 }
 
 ///////////////////////////////////////////////////////////////////////////
diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs
index 922833f8580..d0c31733481 100644
--- a/compiler/rustc_hir_analysis/src/check_unused.rs
+++ b/compiler/rustc_hir_analysis/src/check_unused.rs
@@ -1,5 +1,6 @@
 use crate::errors::{ExternCrateNotIdiomatic, UnusedExternCrate};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::unord::UnordSet;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
@@ -8,12 +9,12 @@ use rustc_session::lint;
 use rustc_span::{Span, Symbol};
 
 pub fn check_crate(tcx: TyCtxt<'_>) {
-    let mut used_trait_imports: FxHashSet<LocalDefId> = FxHashSet::default();
+    let mut used_trait_imports: UnordSet<LocalDefId> = Default::default();
 
     for item_def_id in tcx.hir().body_owners() {
         let imports = tcx.used_trait_imports(item_def_id);
         debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports);
-        used_trait_imports.extend(imports.iter());
+        used_trait_imports.extend(imports.items().copied());
     }
 
     for &id in tcx.maybe_unused_trait_imports(()) {
@@ -89,11 +90,11 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
     let mut crates_to_lint = vec![];
 
     for id in tcx.hir().items() {
-        if matches!(tcx.def_kind(id.def_id), DefKind::ExternCrate) {
+        if matches!(tcx.def_kind(id.owner_id), DefKind::ExternCrate) {
             let item = tcx.hir().item(id);
             if let hir::ItemKind::ExternCrate(orig_name) = item.kind {
                 crates_to_lint.push(ExternCrateToLint {
-                    def_id: item.def_id.to_def_id(),
+                    def_id: item.owner_id.to_def_id(),
                     span: item.span,
                     orig_name,
                     warn_if_unused: !item.ident.as_str().starts_with('_'),
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
index 308ad5d5fc2..2890c149b3a 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
@@ -58,7 +58,7 @@ const ADD_ATTR: &str =
 
 impl<'tcx> InherentCollect<'tcx> {
     fn check_def_id(&mut self, item: &hir::Item<'_>, self_ty: Ty<'tcx>, def_id: DefId) {
-        let impl_def_id = item.def_id;
+        let impl_def_id = item.owner_id;
         if let Some(def_id) = def_id.as_local() {
             // Add the implementation to the mapping from implementation to base
             // type def ID, if there is a base type for this implementation and
@@ -89,7 +89,7 @@ impl<'tcx> InherentCollect<'tcx> {
             for impl_item in items {
                 if !self
                     .tcx
-                    .has_attr(impl_item.id.def_id.to_def_id(), sym::rustc_allow_incoherent_impl)
+                    .has_attr(impl_item.id.owner_id.to_def_id(), sym::rustc_allow_incoherent_impl)
                 {
                     struct_span_err!(
                         self.tcx.sess,
@@ -135,7 +135,7 @@ impl<'tcx> InherentCollect<'tcx> {
                 for item in items {
                     if !self
                         .tcx
-                        .has_attr(item.id.def_id.to_def_id(), sym::rustc_allow_incoherent_impl)
+                        .has_attr(item.id.owner_id.to_def_id(), sym::rustc_allow_incoherent_impl)
                     {
                         struct_span_err!(
                             self.tcx.sess,
@@ -177,7 +177,7 @@ impl<'tcx> InherentCollect<'tcx> {
     }
 
     fn check_item(&mut self, id: hir::ItemId) {
-        if !matches!(self.tcx.def_kind(id.def_id), DefKind::Impl) {
+        if !matches!(self.tcx.def_kind(id.owner_id), DefKind::Impl) {
             return;
         }
 
@@ -186,7 +186,7 @@ impl<'tcx> InherentCollect<'tcx> {
             return;
         };
 
-        let self_ty = self.tcx.type_of(item.def_id);
+        let self_ty = self.tcx.type_of(item.owner_id);
         match *self_ty.kind() {
             ty::Adt(def, _) => {
                 self.check_def_id(item, self_ty, def.did());
@@ -221,7 +221,7 @@ impl<'tcx> InherentCollect<'tcx> {
             | ty::Never
             | ty::FnPtr(_)
             | ty::Tuple(..) => {
-                self.check_primitive_impl(item.def_id.def_id, self_ty, items, ty.span)
+                self.check_primitive_impl(item.owner_id.def_id, self_ty, items, ty.span)
             }
             ty::Projection(..) | ty::Opaque(..) | ty::Param(_) => {
                 let mut err = struct_span_err!(
@@ -243,7 +243,7 @@ impl<'tcx> InherentCollect<'tcx> {
             | ty::Bound(..)
             | ty::Placeholder(_)
             | ty::Infer(_) => {
-                bug!("unexpected impl self type of impl: {:?} {:?}", item.def_id, self_ty);
+                bug!("unexpected impl self type of impl: {:?} {:?}", item.owner_id, self_ty);
             }
             ty::Error(_) => {}
         }
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
index 130eb8005b0..972769eb197 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
@@ -156,14 +156,14 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
     }
 
     fn check_item(&mut self, id: hir::ItemId) {
-        let def_kind = self.tcx.def_kind(id.def_id);
+        let def_kind = self.tcx.def_kind(id.owner_id);
         if !matches!(def_kind, DefKind::Enum | DefKind::Struct | DefKind::Trait | DefKind::Union) {
             return;
         }
 
-        let impls = self.tcx.inherent_impls(id.def_id);
+        let impls = self.tcx.inherent_impls(id.owner_id);
 
-        let overlap_mode = OverlapMode::get(self.tcx, id.def_id.to_def_id());
+        let overlap_mode = OverlapMode::get(self.tcx, id.owner_id.to_def_id());
 
         let impls_items = impls
             .iter()
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index 1307f74f210..bb45c3823d8 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -101,7 +101,7 @@ fn do_orphan_check_impl<'tcx>(
         span_bug!(sp, "opaque type not found, but `has_opaque_types` is set")
     }
 
-    match traits::orphan_check(tcx, item.def_id.to_def_id()) {
+    match traits::orphan_check(tcx, item.owner_id.to_def_id()) {
         Ok(()) => {}
         Err(err) => emit_orphan_check_error(
             tcx,
diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
index e45fb5fe41c..a34815b45b3 100644
--- a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
@@ -13,7 +13,7 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
     let item = tcx.hir().expect_item(def_id);
     let hir::ItemKind::Impl(ref impl_) = item.kind else { bug!() };
 
-    if let Some(trait_ref) = tcx.impl_trait_ref(item.def_id) {
+    if let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id) {
         let trait_def = tcx.trait_def(trait_ref.def_id);
         let unsafe_attr =
             impl_.generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle");
@@ -26,6 +26,12 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
                     "implementing the trait `{}` is not unsafe",
                     trait_ref.print_only_trait_path()
                 )
+                .span_suggestion_verbose(
+                    item.span.with_hi(item.span.lo() + rustc_span::BytePos(7)),
+                    "remove `unsafe` from this trait implementation",
+                    "",
+                    rustc_errors::Applicability::MachineApplicable,
+                )
                 .emit();
             }
 
@@ -37,6 +43,18 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
                     "the trait `{}` requires an `unsafe impl` declaration",
                     trait_ref.print_only_trait_path()
                 )
+                .note(format!(
+                    "the trait `{}` enforces invariants that the compiler can't check. \
+                    Review the trait documentation and make sure this implementation \
+                    upholds those invariants before adding the `unsafe` keyword",
+                    trait_ref.print_only_trait_path()
+                ))
+                .span_suggestion_verbose(
+                    item.span.shrink_to_lo(),
+                    "add `unsafe` to this trait implementation",
+                    "unsafe ",
+                    rustc_errors::Applicability::MaybeIncorrect,
+                )
                 .emit();
             }
 
@@ -48,6 +66,18 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
                     "requires an `unsafe impl` declaration due to `#[{}]` attribute",
                     attr_name
                 )
+                .note(format!(
+                    "the trait `{}` enforces invariants that the compiler can't check. \
+                    Review the trait documentation and make sure this implementation \
+                    upholds those invariants before adding the `unsafe` keyword",
+                    trait_ref.print_only_trait_path()
+                ))
+                .span_suggestion_verbose(
+                    item.span.shrink_to_lo(),
+                    "add `unsafe` to this trait implementation",
+                    "unsafe ",
+                    rustc_errors::Applicability::MaybeIncorrect,
+                )
                 .emit();
             }
 
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index e261bb07f95..65a1d61e87c 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -27,8 +27,8 @@ use rustc_hir as hir;
 use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
 use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::weak_lang_items;
-use rustc_hir::{GenericParamKind, Node};
+use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
+use rustc_hir::{lang_items, GenericParamKind, LangItem, Node};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
 use rustc_middle::mir::mono::Linkage;
@@ -571,7 +571,7 @@ fn get_new_lifetime_name<'tcx>(
 fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
     let it = tcx.hir().item(item_id);
     debug!("convert: item {} with id {}", it.ident, it.hir_id());
-    let def_id = item_id.def_id.def_id;
+    let def_id = item_id.owner_id.def_id;
 
     match it.kind {
         // These don't define types.
@@ -583,11 +583,11 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
         hir::ItemKind::ForeignMod { items, .. } => {
             for item in items {
                 let item = tcx.hir().foreign_item(item.id);
-                tcx.ensure().generics_of(item.def_id);
-                tcx.ensure().type_of(item.def_id);
-                tcx.ensure().predicates_of(item.def_id);
+                tcx.ensure().generics_of(item.owner_id);
+                tcx.ensure().type_of(item.owner_id);
+                tcx.ensure().predicates_of(item.owner_id);
                 match item.kind {
-                    hir::ForeignItemKind::Fn(..) => tcx.ensure().fn_sig(item.def_id),
+                    hir::ForeignItemKind::Fn(..) => tcx.ensure().fn_sig(item.owner_id),
                     hir::ForeignItemKind::Static(..) => {
                         let mut visitor = HirPlaceholderCollector::default();
                         visitor.visit_foreign_item(item);
@@ -683,7 +683,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
 
 fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
     let trait_item = tcx.hir().trait_item(trait_item_id);
-    let def_id = trait_item_id.def_id;
+    let def_id = trait_item_id.owner_id;
     tcx.ensure().generics_of(def_id);
 
     match trait_item.kind {
@@ -730,7 +730,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
 }
 
 fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
-    let def_id = impl_item_id.def_id;
+    let def_id = impl_item_id.owner_id;
     tcx.ensure().generics_of(def_id);
     tcx.ensure().type_of(def_id);
     tcx.ensure().predicates_of(def_id);
@@ -1010,7 +1010,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
 
                 match item {
                     Some(item) if matches!(item.kind, hir::AssocItemKind::Fn { .. }) => {
-                        if !tcx.impl_defaultness(item.id.def_id).has_value() {
+                        if !tcx.impl_defaultness(item.id.owner_id).has_value() {
                             tcx.sess
                                 .struct_span_err(
                                     item.span,
@@ -2104,12 +2104,15 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
     // strippable by the linker.
     //
     // Additionally weak lang items have predetermined symbol names.
-    if tcx.is_weak_lang_item(did.to_def_id()) {
+    if WEAK_LANG_ITEMS.iter().any(|&l| tcx.lang_items().get(l) == Some(did.to_def_id())) {
         codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
     }
-    if let Some(name) = weak_lang_items::link_name(attrs) {
-        codegen_fn_attrs.export_name = Some(name);
-        codegen_fn_attrs.link_name = Some(name);
+    if let Some((name, _)) = lang_items::extract(attrs)
+        && let Some(lang_item) = LangItem::from_name(name)
+        && let Some(link_name) = lang_item.link_name()
+    {
+        codegen_fn_attrs.export_name = Some(link_name);
+        codegen_fn_attrs.link_name = Some(link_name);
     }
     check_link_name_xor_ordinal(tcx, &codegen_fn_attrs, link_ordinal_span);
 
diff --git a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs
index c1214698cf7..3f263a6de24 100644
--- a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs
+++ b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs
@@ -331,8 +331,8 @@ fn convert_named_region_map(named_region_map: NamedRegionMap) -> ResolveLifetime
 /// `resolve_lifetimes`.
 fn resolve_lifetimes_for<'tcx>(tcx: TyCtxt<'tcx>, def_id: hir::OwnerId) -> &'tcx ResolveLifetimes {
     let item_id = item_for(tcx, def_id.def_id);
-    let local_def_id = item_id.def_id.def_id;
-    if item_id.def_id == def_id {
+    let local_def_id = item_id.owner_id.def_id;
+    if item_id.owner_id == def_id {
         let item = tcx.hir().item(item_id);
         match item.kind {
             hir::ItemKind::Trait(..) => tcx.resolve_lifetimes_trait_definition(local_def_id),
@@ -557,11 +557,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                 // their owner, we can keep going until we find the Item that owns that. We then
                 // conservatively add all resolved lifetimes. Otherwise we run into problems in
                 // cases like `type Foo<'a> = impl Bar<As = impl Baz + 'a>`.
-                for (_hir_id, node) in self.tcx.hir().parent_iter(item.def_id.into()) {
+                for (_hir_id, node) in self.tcx.hir().parent_iter(item.owner_id.into()) {
                     match node {
                         hir::Node::Item(parent_item) => {
                             let resolved_lifetimes: &ResolveLifetimes = self.tcx.resolve_lifetimes(
-                                item_for(self.tcx, parent_item.def_id.def_id).def_id.def_id,
+                                item_for(self.tcx, parent_item.owner_id.def_id).owner_id.def_id,
                             );
                             // We need to add *all* deps, since opaque tys may want them from *us*
                             for (&owner, defs) in resolved_lifetimes.defs.iter() {
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 32f359a8158..c29a645eb4a 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -319,7 +319,15 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                     }
                 }
                 ItemKind::TyAlias(self_ty, _) => icx.to_ty(self_ty),
-                ItemKind::Impl(hir::Impl { self_ty, .. }) => icx.to_ty(*self_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()
+                        },
+                        _ => icx.to_ty(*self_ty),
+                    }
+                },
                 ItemKind::Fn(..) => {
                     let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
                     tcx.mk_fn_def(def_id.to_def_id(), substs)
@@ -635,24 +643,24 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
             intravisit::walk_expr(self, ex);
         }
         fn visit_item(&mut self, it: &'tcx Item<'tcx>) {
-            trace!(?it.def_id);
+            trace!(?it.owner_id);
             // The opaque type itself or its children are not within its reveal scope.
-            if it.def_id.def_id != self.def_id {
-                self.check(it.def_id.def_id);
+            if it.owner_id.def_id != self.def_id {
+                self.check(it.owner_id.def_id);
                 intravisit::walk_item(self, it);
             }
         }
         fn visit_impl_item(&mut self, it: &'tcx ImplItem<'tcx>) {
-            trace!(?it.def_id);
+            trace!(?it.owner_id);
             // The opaque type itself or its children are not within its reveal scope.
-            if it.def_id.def_id != self.def_id {
-                self.check(it.def_id.def_id);
+            if it.owner_id.def_id != self.def_id {
+                self.check(it.owner_id.def_id);
                 intravisit::walk_impl_item(self, it);
             }
         }
         fn visit_trait_item(&mut self, it: &'tcx TraitItem<'tcx>) {
-            trace!(?it.def_id);
-            self.check(it.def_id.def_id);
+            trace!(?it.owner_id);
+            self.check(it.owner_id.def_id);
             intravisit::walk_trait_item(self, it);
         }
     }
@@ -693,6 +701,12 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
         tcx.sess.emit_err(UnconstrainedOpaqueType {
             span: tcx.def_span(def_id),
             name: tcx.item_name(tcx.local_parent(def_id).to_def_id()),
+            what: match tcx.hir().get(scope) {
+                _ if scope == hir::CRATE_HIR_ID => "module",
+                Node::Item(hir::Item { kind: hir::ItemKind::Mod(_), .. }) => "module",
+                Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => "impl",
+                _ => "item",
+            },
         });
         return tcx.ty_error();
     };
@@ -764,24 +778,24 @@ fn find_opaque_ty_constraints_for_rpit(
             intravisit::walk_expr(self, ex);
         }
         fn visit_item(&mut self, it: &'tcx Item<'tcx>) {
-            trace!(?it.def_id);
+            trace!(?it.owner_id);
             // The opaque type itself or its children are not within its reveal scope.
-            if it.def_id.def_id != self.def_id {
-                self.check(it.def_id.def_id);
+            if it.owner_id.def_id != self.def_id {
+                self.check(it.owner_id.def_id);
                 intravisit::walk_item(self, it);
             }
         }
         fn visit_impl_item(&mut self, it: &'tcx ImplItem<'tcx>) {
-            trace!(?it.def_id);
+            trace!(?it.owner_id);
             // The opaque type itself or its children are not within its reveal scope.
-            if it.def_id.def_id != self.def_id {
-                self.check(it.def_id.def_id);
+            if it.owner_id.def_id != self.def_id {
+                self.check(it.owner_id.def_id);
                 intravisit::walk_impl_item(self, it);
             }
         }
         fn visit_trait_item(&mut self, it: &'tcx TraitItem<'tcx>) {
-            trace!(?it.def_id);
-            self.check(it.def_id.def_id);
+            trace!(?it.owner_id);
+            self.check(it.owner_id.def_id);
             intravisit::walk_trait_item(self, it);
         }
     }
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index bd0c1f5dd10..d5b1a7ce1c2 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1,7 +1,7 @@
 //! Errors emitted by `rustc_hir_analysis`.
 
-use rustc_errors::IntoDiagnostic;
 use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler};
+use rustc_errors::{IntoDiagnostic, MultiSpan};
 use rustc_macros::{Diagnostic, LintDiagnostic};
 use rustc_middle::ty::Ty;
 use rustc_span::{symbol::Ident, Span, Symbol};
@@ -143,6 +143,7 @@ pub struct UnconstrainedOpaqueType {
     #[primary_span]
     pub span: Span,
     pub name: Symbol,
+    pub what: &'static str,
 }
 
 pub struct MissingTypeParams {
@@ -270,3 +271,12 @@ pub struct ConstBoundForNonConstTrait {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_self_in_impl_self)]
+pub struct SelfInImplSelf {
+    #[primary_span]
+    pub span: MultiSpan,
+    #[note]
+    pub note: (),
+}
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
index a84257b939c..136f6199911 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
@@ -55,10 +55,10 @@ fn check_mod_impl_wf(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
     let min_specialization = tcx.features().min_specialization;
     let module = tcx.hir_module_items(module_def_id);
     for id in module.items() {
-        if matches!(tcx.def_kind(id.def_id), DefKind::Impl) {
-            enforce_impl_params_are_constrained(tcx, id.def_id.def_id);
+        if matches!(tcx.def_kind(id.owner_id), DefKind::Impl) {
+            enforce_impl_params_are_constrained(tcx, id.owner_id.def_id);
             if min_specialization {
-                check_min_specialization(tcx, id.def_id.def_id);
+                check_min_specialization(tcx, id.owner_id.def_id);
             }
         }
     }
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index dba505149de..bd1a461b935 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -106,7 +106,7 @@ use rustc_middle::middle;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::util;
-use rustc_session::config::EntryFnType;
+use rustc_session::{config::EntryFnType, parse::feature_err};
 use rustc_span::{symbol::sym, Span, DUMMY_SP};
 use rustc_target::spec::abi::Abi;
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
@@ -118,20 +118,40 @@ use astconv::AstConv;
 use bounds::Bounds;
 
 fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi, span: Span) {
-    match (decl.c_variadic, abi) {
-        // The function has the correct calling convention, or isn't a "C-variadic" function.
-        (false, _) | (true, Abi::C { .. }) | (true, Abi::Cdecl { .. }) => {}
-        // The function is a "C-variadic" function with an incorrect calling convention.
-        (true, _) => {
-            let mut err = struct_span_err!(
-                tcx.sess,
+    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 =
+        "using calling conventions other than `C` or `cdecl` for varargs functions is unstable";
+
+    if !decl.c_variadic || matches!(abi, Abi::C { .. } | Abi::Cdecl { .. }) {
+        return;
+    }
+
+    let extended_abi_support = tcx.features().extended_varargs_abi_support;
+    let conventions = match (extended_abi_support, abi.supports_varargs()) {
+        // User enabled additional ABI support for varargs and function ABI matches those ones.
+        (true, true) => return,
+
+        // Using this ABI would be ok, if the feature for additional ABI support was enabled.
+        // Return CONVENTIONS_STABLE, because we want the other error to look the same.
+        (false, true) => {
+            feature_err(
+                &tcx.sess.parse_sess,
+                sym::extended_varargs_abi_support,
                 span,
-                E0045,
-                "C-variadic function must have C or cdecl calling convention"
-            );
-            err.span_label(span, "C-variadics require C or cdecl calling convention").emit();
+                UNSTABLE_EXPLAIN,
+            )
+            .emit();
+            CONVENTIONS_STABLE
         }
-    }
+
+        (false, false) => CONVENTIONS_STABLE,
+        (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();
 }
 
 fn require_same_types<'tcx>(
@@ -381,7 +401,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
                         error = true;
                     }
                     if let hir::IsAsync::Async = sig.header.asyncness {
-                        let span = tcx.def_span(it.def_id);
+                        let span = tcx.def_span(it.owner_id);
                         struct_span_err!(
                             tcx.sess,
                             span,
diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
index 064a70107fe..90c6edb65e4 100644
--- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
@@ -29,7 +29,7 @@ pub(super) fn infer_predicates<'tcx>(
 
         // Visit all the crates and infer predicates
         for id in tcx.hir().items() {
-            let item_did = id.def_id;
+            let item_did = id.owner_id;
 
             debug!("InferVisitor::visit_item(item={:?})", item_did);
 
diff --git a/compiler/rustc_hir_analysis/src/outlives/test.rs b/compiler/rustc_hir_analysis/src/outlives/test.rs
index eb0e1203405..fa2ac56593b 100644
--- a/compiler/rustc_hir_analysis/src/outlives/test.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/test.rs
@@ -6,11 +6,11 @@ pub fn test_inferred_outlives(tcx: TyCtxt<'_>) {
     for id in tcx.hir().items() {
         // For unit testing: check for a special "rustc_outlives"
         // attribute and report an error with various results if found.
-        if tcx.has_attr(id.def_id.to_def_id(), sym::rustc_outlives) {
-            let inferred_outlives_of = tcx.inferred_outlives_of(id.def_id);
+        if tcx.has_attr(id.owner_id.to_def_id(), sym::rustc_outlives) {
+            let inferred_outlives_of = tcx.inferred_outlives_of(id.owner_id);
             struct_span_err!(
                 tcx.sess,
-                tcx.def_span(id.def_id),
+                tcx.def_span(id.owner_id),
                 E0640,
                 "{:?}",
                 inferred_outlives_of
diff --git a/compiler/rustc_hir_analysis/src/variance/test.rs b/compiler/rustc_hir_analysis/src/variance/test.rs
index 2ba87db880b..83ed3e44b3d 100644
--- a/compiler/rustc_hir_analysis/src/variance/test.rs
+++ b/compiler/rustc_hir_analysis/src/variance/test.rs
@@ -6,9 +6,10 @@ pub fn test_variance(tcx: TyCtxt<'_>) {
     // For unit testing: check for a special "rustc_variance"
     // attribute and report an error with various results if found.
     for id in tcx.hir().items() {
-        if tcx.has_attr(id.def_id.to_def_id(), sym::rustc_variance) {
-            let variances_of = tcx.variances_of(id.def_id);
-            struct_span_err!(tcx.sess, tcx.def_span(id.def_id), E0208, "{:?}", variances_of).emit();
+        if tcx.has_attr(id.owner_id.to_def_id(), sym::rustc_variance) {
+            let variances_of = tcx.variances_of(id.owner_id);
+            struct_span_err!(tcx.sess, tcx.def_span(id.owner_id), E0208, "{:?}", variances_of)
+                .emit();
         }
     }
 }
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 0e7576ecf8b..d1dab0540be 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -60,6 +60,8 @@ pub struct CastCheck<'tcx> {
     cast_ty: Ty<'tcx>,
     cast_span: Span,
     span: Span,
+    /// whether the cast is made in a const context or not.
+    pub constness: hir::Constness,
 }
 
 /// The kind of pointer and associated metadata (thin, length or vtable) - we
@@ -210,9 +212,10 @@ impl<'a, 'tcx> CastCheck<'tcx> {
         cast_ty: Ty<'tcx>,
         cast_span: Span,
         span: Span,
+        constness: hir::Constness,
     ) -> Result<CastCheck<'tcx>, ErrorGuaranteed> {
         let expr_span = expr.span.find_ancestor_inside(span).unwrap_or(expr.span);
-        let check = CastCheck { expr, expr_ty, expr_span, cast_ty, cast_span, span };
+        let check = CastCheck { expr, expr_ty, expr_span, cast_ty, cast_span, span, constness };
 
         // For better error messages, check for some obviously unsized
         // cases now. We do a more thorough check at the end, once
@@ -866,7 +869,13 @@ impl<'a, 'tcx> CastCheck<'tcx> {
 
             (Int(_) | Float, Int(_) | Float) => Ok(CastKind::NumericCast),
 
-            (_, DynStar) | (DynStar, _) => bug!("should be handled by `try_coerce`"),
+            (_, DynStar) | (DynStar, _) => {
+                if fcx.tcx.features().dyn_star {
+                    bug!("should be handled by `try_coerce`")
+                } else {
+                    Err(CastError::IllegalCast)
+                }
+            }
         }
     }
 
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index be14234afe2..16febfc46da 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -530,24 +530,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         checked_ty: Ty<'tcx>,
         hir_id: hir::HirId,
     ) -> Vec<AssocItem> {
-        let mut methods =
-            self.probe_for_return_type(span, probe::Mode::MethodCall, expected, checked_ty, hir_id);
-        methods.retain(|m| {
-            self.has_only_self_parameter(m)
-                && self
-                    .tcx
-                    // This special internal attribute is used to permit
-                    // "identity-like" conversion methods to be suggested here.
-                    //
-                    // FIXME (#46459 and #46460): ideally
-                    // `std::convert::Into::into` and `std::borrow:ToOwned` would
-                    // also be `#[rustc_conversion_suggestion]`, if not for
-                    // method-probing false-positives and -negatives (respectively).
-                    //
-                    // FIXME? Other potential candidate methods: `as_ref` and
-                    // `as_mut`?
-                    .has_attr(m.def_id, sym::rustc_conversion_suggestion)
-        });
+        let methods = self.probe_for_return_type(
+            span,
+            probe::Mode::MethodCall,
+            expected,
+            checked_ty,
+            hir_id,
+            |m| {
+                self.has_only_self_parameter(m)
+                    && self
+                        .tcx
+                        // This special internal attribute is used to permit
+                        // "identity-like" conversion methods to be suggested here.
+                        //
+                        // FIXME (#46459 and #46460): ideally
+                        // `std::convert::Into::into` and `std::borrow:ToOwned` would
+                        // also be `#[rustc_conversion_suggestion]`, if not for
+                        // method-probing false-positives and -negatives (respectively).
+                        //
+                        // FIXME? Other potential candidate methods: `as_ref` and
+                        // `as_mut`?
+                        .has_attr(m.def_id, sym::rustc_conversion_suggestion)
+            },
+        );
 
         methods
     }
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 41b00fda03e..9fde62a81a1 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1272,7 +1272,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         } else {
             // Defer other checks until we're done type checking.
             let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
-            match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
+            match cast::CastCheck::new(
+                self,
+                e,
+                t_expr,
+                t_cast,
+                t.span,
+                expr.span,
+                self.param_env.constness(),
+            ) {
                 Ok(cast_check) => {
                     debug!(
                         "check_expr_cast: deferring cast from {:?} to {:?}: {:?}",
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 08a3cbccfb0..8e0fcb56c7f 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -33,16 +33,27 @@ use rustc_span::{self, sym, Span};
 use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext};
 
 use std::iter;
+use std::mem;
 use std::ops::ControlFlow;
 use std::slice;
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-    pub(in super::super) fn check_casts(&self) {
-        let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
+    pub(in super::super) fn check_casts(&mut self) {
+        // don't hold the borrow to deferred_cast_checks while checking to avoid borrow checker errors
+        // when writing to `self.param_env`.
+        let mut deferred_cast_checks = mem::take(&mut *self.deferred_cast_checks.borrow_mut());
+
         debug!("FnCtxt::check_casts: {} deferred checks", deferred_cast_checks.len());
         for cast in deferred_cast_checks.drain(..) {
+            let prev_env = self.param_env;
+            self.param_env = self.param_env.with_constness(cast.constness);
+
             cast.check(self);
+
+            self.param_env = prev_env;
         }
+
+        *self.deferred_cast_checks.borrow_mut() = deferred_cast_checks;
     }
 
     pub(in super::super) fn check_transmutes(&self) {
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index e862d577573..959c5486645 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -52,7 +52,7 @@ pub use inherited::{Inherited, InheritedBuilder};
 use crate::check::check_fn;
 use crate::coercion::DynamicCoerceMany;
 use crate::gather_locals::GatherLocalsVisitor;
-use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::unord::UnordSet;
 use rustc_errors::{struct_span_err, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def::Res;
@@ -174,7 +174,7 @@ fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     }
 }
 
-fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &FxHashSet<LocalDefId> {
+fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &UnordSet<LocalDefId> {
     &*tcx.typeck(def_id).used_trait_imports
 }
 
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 74cf2ac32aa..28aa2302f88 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -252,7 +252,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// would result in an error (basically, the same criteria we
     /// would use to decide if a method is a plausible fit for
     /// ambiguity purposes).
-    #[instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self, candidate_filter))]
     pub fn probe_for_return_type(
         &self,
         span: Span,
@@ -260,6 +260,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         return_type: Ty<'tcx>,
         self_ty: Ty<'tcx>,
         scope_expr_id: hir::HirId,
+        candidate_filter: impl Fn(&ty::AssocItem) -> bool,
     ) -> Vec<ty::AssocItem> {
         let method_names = self
             .probe_op(
@@ -271,7 +272,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self_ty,
                 scope_expr_id,
                 ProbeScope::AllTraits,
-                |probe_cx| Ok(probe_cx.candidate_method_names()),
+                |probe_cx| Ok(probe_cx.candidate_method_names(candidate_filter)),
             )
             .unwrap_or_default();
         method_names
@@ -966,12 +967,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         }
     }
 
-    fn candidate_method_names(&self) -> Vec<Ident> {
+    fn candidate_method_names(
+        &self,
+        candidate_filter: impl Fn(&ty::AssocItem) -> bool,
+    ) -> Vec<Ident> {
         let mut set = FxHashSet::default();
         let mut names: Vec<_> = self
             .inherent_candidates
             .iter()
             .chain(&self.extension_candidates)
+            .filter(|candidate| candidate_filter(&candidate.item))
             .filter(|candidate| {
                 if let Some(return_ty) = self.return_type {
                     self.matches_return_type(&candidate.item, None, return_ty)
@@ -1689,7 +1694,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             pcx.allow_similar_names = true;
             pcx.assemble_inherent_candidates();
 
-            let method_names = pcx.candidate_method_names();
+            let method_names = pcx.candidate_method_names(|_| true);
             pcx.allow_similar_names = false;
             let applicable_close_candidates: Vec<ty::AssocItem> = method_names
                 .iter()
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index f4351bfa84a..6c21ed902d0 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -106,7 +106,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let report_candidates = |span: Span,
                                  err: &mut Diagnostic,
-                                 mut sources: Vec<CandidateSource>,
+                                 sources: &mut Vec<CandidateSource>,
                                  sugg_span: Span| {
             sources.sort();
             sources.dedup();
@@ -248,7 +248,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         match error {
             MethodError::NoMatch(NoMatchData {
-                static_candidates: static_sources,
+                static_candidates: mut static_sources,
                 unsatisfied_predicates,
                 out_of_scope_traits,
                 lev_candidate,
@@ -422,9 +422,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         err.help(&format!("try with `{}::{}`", ty_str, item_name,));
                     }
 
-                    report_candidates(span, &mut err, static_sources, sugg_span);
+                    report_candidates(span, &mut err, &mut static_sources, sugg_span);
                 } else if static_sources.len() > 1 {
-                    report_candidates(span, &mut err, static_sources, sugg_span);
+                    report_candidates(span, &mut err, &mut static_sources, sugg_span);
                 }
 
                 let mut bound_spans = vec![];
@@ -1007,6 +1007,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         source,
                         out_of_scope_traits,
                         &unsatisfied_predicates,
+                        &static_sources,
                         unsatisfied_bounds,
                     );
                 }
@@ -1079,7 +1080,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 return Some(err);
             }
 
-            MethodError::Ambiguity(sources) => {
+            MethodError::Ambiguity(mut sources) => {
                 let mut err = struct_span_err!(
                     self.sess(),
                     item_name.span,
@@ -1088,7 +1089,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 );
                 err.span_label(item_name.span, format!("multiple `{}` found", item_name));
 
-                report_candidates(span, &mut err, sources, sugg_span);
+                report_candidates(span, &mut err, &mut sources, sugg_span);
                 err.emit();
             }
 
@@ -2015,6 +2016,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             Option<ty::Predicate<'tcx>>,
             Option<ObligationCause<'tcx>>,
         )],
+        static_candidates: &[CandidateSource],
         unsatisfied_bounds: bool,
     ) {
         let mut alt_rcvr_sugg = false;
@@ -2129,6 +2131,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 None => true,
             })
             .filter(|info| {
+                // Static candidates are already implemented, and known not to work
+                // Do not suggest them again
+                static_candidates.iter().all(|sc| match *sc {
+                    CandidateSource::Trait(def_id) => def_id != info.def_id,
+                    CandidateSource::Impl(def_id) => {
+                        self.tcx.trait_id_of_impl(def_id) != Some(info.def_id)
+                    }
+                })
+            })
+            .filter(|info| {
                 // We approximate the coherence rules to only suggest
                 // traits that are legal to implement by requiring that
                 // either the type or trait is local. Multi-dispatch means
diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs
index 9c19f16a496..79e2d371ed3 100644
--- a/compiler/rustc_incremental/src/persist/dirty_clean.rs
+++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs
@@ -149,19 +149,19 @@ pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
         let crate_items = tcx.hir_crate_items(());
 
         for id in crate_items.items() {
-            dirty_clean_visitor.check_item(id.def_id.def_id);
+            dirty_clean_visitor.check_item(id.owner_id.def_id);
         }
 
         for id in crate_items.trait_items() {
-            dirty_clean_visitor.check_item(id.def_id.def_id);
+            dirty_clean_visitor.check_item(id.owner_id.def_id);
         }
 
         for id in crate_items.impl_items() {
-            dirty_clean_visitor.check_item(id.def_id.def_id);
+            dirty_clean_visitor.check_item(id.owner_id.def_id);
         }
 
         for id in crate_items.foreign_items() {
-            dirty_clean_visitor.check_item(id.def_id.def_id);
+            dirty_clean_visitor.check_item(id.owner_id.def_id);
         }
 
         let mut all_attrs = FindAllAttrs { tcx, found_attrs: vec![] };
diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index 4d287988e33..a299a3e578d 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -632,7 +632,7 @@ impl<'tcx> InferCtxt<'tcx> {
 /// creates query region constraints.
 pub fn make_query_region_constraints<'tcx>(
     tcx: TyCtxt<'tcx>,
-    outlives_obligations: impl Iterator<Item = (Ty<'tcx>, ty::Region<'tcx>, ConstraintCategory)>,
+    outlives_obligations: impl Iterator<Item = (Ty<'tcx>, ty::Region<'tcx>, ConstraintCategory<'tcx>)>,
     region_constraints: &RegionConstraintData<'tcx>,
 ) -> QueryRegionConstraints<'tcx> {
     let RegionConstraintData { constraints, verifys, givens, member_constraints } =
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 a74c172fa0c..9bf755d7fcd 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
@@ -306,7 +306,7 @@ pub fn suggest_new_region_bound(
                 };
 
                 // Get the identity type for this RPIT
-                let did = item_id.def_id.to_def_id();
+                let did = item_id.owner_id.to_def_id();
                 let ty = tcx.mk_opaque(did, ty::InternalSubsts::identity_for_item(tcx, did));
 
                 if let Some(span) = opaque
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 7e2ea6c0e26..ffb020398b8 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -425,7 +425,7 @@ pub enum SubregionOrigin<'tcx> {
 static_assert_size!(SubregionOrigin<'_>, 32);
 
 impl<'tcx> SubregionOrigin<'tcx> {
-    pub fn to_constraint_category(&self) -> ConstraintCategory {
+    pub fn to_constraint_category(&self) -> ConstraintCategory<'tcx> {
         match self {
             Self::Subtype(type_trace) => type_trace.cause.to_constraint_category(),
             Self::AscribeUserTypeProvePredicate(span) => ConstraintCategory::Predicate(*span),
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index 5ebf80b7b74..6ca884799aa 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -210,7 +210,7 @@ pub trait TypeOutlivesDelegate<'tcx> {
         origin: SubregionOrigin<'tcx>,
         a: ty::Region<'tcx>,
         b: ty::Region<'tcx>,
-        constraint_category: ConstraintCategory,
+        constraint_category: ConstraintCategory<'tcx>,
     );
 
     fn push_verify(
@@ -259,7 +259,7 @@ where
         origin: infer::SubregionOrigin<'tcx>,
         ty: Ty<'tcx>,
         region: ty::Region<'tcx>,
-        category: ConstraintCategory,
+        category: ConstraintCategory<'tcx>,
     ) {
         assert!(!ty.has_escaping_bound_vars());
 
@@ -273,7 +273,7 @@ where
         origin: infer::SubregionOrigin<'tcx>,
         components: &[Component<'tcx>],
         region: ty::Region<'tcx>,
-        category: ConstraintCategory,
+        category: ConstraintCategory<'tcx>,
     ) {
         for component in components.iter() {
             let origin = origin.clone();
@@ -529,7 +529,7 @@ impl<'cx, 'tcx> TypeOutlivesDelegate<'tcx> for &'cx InferCtxt<'tcx> {
         origin: SubregionOrigin<'tcx>,
         a: ty::Region<'tcx>,
         b: ty::Region<'tcx>,
-        _constraint_category: ConstraintCategory,
+        _constraint_category: ConstraintCategory<'tcx>,
     ) {
         self.sub_regions(origin, a, b)
     }
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 9d2325e8265..7f1d21bf1d8 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -927,7 +927,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
     sess.time("misc_checking_3", || {
         parallel!(
             {
-                tcx.ensure().privacy_access_levels(());
+                tcx.ensure().effective_visibilities(());
 
                 parallel!(
                     {
diff --git a/compiler/rustc_interface/src/proc_macro_decls.rs b/compiler/rustc_interface/src/proc_macro_decls.rs
index 2b1b931b732..4c236c693d0 100644
--- a/compiler/rustc_interface/src/proc_macro_decls.rs
+++ b/compiler/rustc_interface/src/proc_macro_decls.rs
@@ -9,7 +9,7 @@ fn proc_macro_decls_static(tcx: TyCtxt<'_>, (): ()) -> Option<LocalDefId> {
     for id in tcx.hir().items() {
         let attrs = finder.tcx.hir().attrs(id.hir_id());
         if finder.tcx.sess.contains_name(attrs, sym::rustc_proc_macro_decls) {
-            finder.decls = Some(id.def_id.def_id);
+            finder.decls = Some(id.owner_id.def_id);
         }
     }
 
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 53c49105134..27c04d82811 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -40,7 +40,7 @@ use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, Gate
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID};
-use rustc_hir::{ForeignItemKind, GenericParamKind, HirId, PatKind, PredicateOrigin};
+use rustc_hir::{ForeignItemKind, GenericParamKind, HirId, Node, PatKind, PredicateOrigin};
 use rustc_index::vec::Idx;
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::layout::{LayoutError, LayoutOf};
@@ -177,7 +177,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxPointers {
             | hir::ItemKind::Enum(..)
             | hir::ItemKind::Struct(..)
             | hir::ItemKind::Union(..) => {
-                self.check_heap_type(cx, it.span, cx.tcx.type_of(it.def_id))
+                self.check_heap_type(cx, it.span, cx.tcx.type_of(it.owner_id))
             }
             _ => (),
         }
@@ -563,7 +563,7 @@ impl MissingDoc {
         // It's an option so the crate root can also use this function (it doesn't
         // have a `NodeId`).
         if def_id != CRATE_DEF_ID {
-            if !cx.access_levels.is_exported(def_id) {
+            if !cx.effective_visibilities.is_exported(def_id) {
                 return;
             }
         }
@@ -606,9 +606,9 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
         match it.kind {
             hir::ItemKind::Trait(..) => {
                 // Issue #11592: traits are always considered exported, even when private.
-                if cx.tcx.visibility(it.def_id)
+                if cx.tcx.visibility(it.owner_id)
                     == ty::Visibility::Restricted(
-                        cx.tcx.parent_module_from_def_id(it.def_id.def_id).to_def_id(),
+                        cx.tcx.parent_module_from_def_id(it.owner_id.def_id).to_def_id(),
                     )
                 {
                     return;
@@ -627,15 +627,15 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
             _ => return,
         };
 
-        let (article, desc) = cx.tcx.article_and_description(it.def_id.to_def_id());
+        let (article, desc) = cx.tcx.article_and_description(it.owner_id.to_def_id());
 
-        self.check_missing_docs_attrs(cx, it.def_id.def_id, article, desc);
+        self.check_missing_docs_attrs(cx, it.owner_id.def_id, article, desc);
     }
 
     fn check_trait_item(&mut self, cx: &LateContext<'_>, trait_item: &hir::TraitItem<'_>) {
-        let (article, desc) = cx.tcx.article_and_description(trait_item.def_id.to_def_id());
+        let (article, desc) = cx.tcx.article_and_description(trait_item.owner_id.to_def_id());
 
-        self.check_missing_docs_attrs(cx, trait_item.def_id.def_id, article, desc);
+        self.check_missing_docs_attrs(cx, trait_item.owner_id.def_id, article, desc);
     }
 
     fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {
@@ -662,13 +662,13 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
             }
         }
 
-        let (article, desc) = cx.tcx.article_and_description(impl_item.def_id.to_def_id());
-        self.check_missing_docs_attrs(cx, impl_item.def_id.def_id, article, desc);
+        let (article, desc) = cx.tcx.article_and_description(impl_item.owner_id.to_def_id());
+        self.check_missing_docs_attrs(cx, impl_item.owner_id.def_id, article, desc);
     }
 
     fn check_foreign_item(&mut self, cx: &LateContext<'_>, foreign_item: &hir::ForeignItem<'_>) {
-        let (article, desc) = cx.tcx.article_and_description(foreign_item.def_id.to_def_id());
-        self.check_missing_docs_attrs(cx, foreign_item.def_id.def_id, article, desc);
+        let (article, desc) = cx.tcx.article_and_description(foreign_item.owner_id.to_def_id());
+        self.check_missing_docs_attrs(cx, foreign_item.owner_id.def_id, article, desc);
     }
 
     fn check_field_def(&mut self, cx: &LateContext<'_>, sf: &hir::FieldDef<'_>) {
@@ -721,7 +721,7 @@ declare_lint_pass!(MissingCopyImplementations => [MISSING_COPY_IMPLEMENTATIONS])
 
 impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
     fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
-        if !cx.access_levels.is_reachable(item.def_id.def_id) {
+        if !cx.effective_visibilities.is_reachable(item.owner_id.def_id) {
             return;
         }
         let (def, ty) = match item.kind {
@@ -729,21 +729,21 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
                 if !ast_generics.params.is_empty() {
                     return;
                 }
-                let def = cx.tcx.adt_def(item.def_id);
+                let def = cx.tcx.adt_def(item.owner_id);
                 (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
             }
             hir::ItemKind::Union(_, ref ast_generics) => {
                 if !ast_generics.params.is_empty() {
                     return;
                 }
-                let def = cx.tcx.adt_def(item.def_id);
+                let def = cx.tcx.adt_def(item.owner_id);
                 (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
             }
             hir::ItemKind::Enum(_, ref ast_generics) => {
                 if !ast_generics.params.is_empty() {
                     return;
                 }
-                let def = cx.tcx.adt_def(item.def_id);
+                let def = cx.tcx.adt_def(item.owner_id);
                 (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
             }
             _ => return,
@@ -752,7 +752,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
             return;
         }
         let param_env = ty::ParamEnv::empty();
-        if ty.is_copy_modulo_regions(cx.tcx.at(item.span), param_env) {
+        if ty.is_copy_modulo_regions(cx.tcx, param_env) {
             return;
         }
         if can_type_implement_copy(
@@ -814,7 +814,7 @@ impl_lint_pass!(MissingDebugImplementations => [MISSING_DEBUG_IMPLEMENTATIONS]);
 
 impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
     fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
-        if !cx.access_levels.is_reachable(item.def_id.def_id) {
+        if !cx.effective_visibilities.is_reachable(item.owner_id.def_id) {
             return;
         }
 
@@ -841,7 +841,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
             debug!("{:?}", self.impling_types);
         }
 
-        if !self.impling_types.as_ref().unwrap().contains(&item.def_id.def_id) {
+        if !self.impling_types.as_ref().unwrap().contains(&item.owner_id.def_id) {
             cx.struct_span_lint(
                 MISSING_DEBUG_IMPLEMENTATIONS,
                 item.span,
@@ -1226,7 +1226,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
                             check_no_mangle_on_generic_fn(
                                 no_mangle_attr,
                                 Some(generics),
-                                cx.tcx.hir().get_generics(it.id.def_id.def_id).unwrap(),
+                                cx.tcx.hir().get_generics(it.id.owner_id.def_id).unwrap(),
                                 it.span,
                             );
                         }
@@ -1385,7 +1385,8 @@ impl UnreachablePub {
         exportable: bool,
     ) {
         let mut applicability = Applicability::MachineApplicable;
-        if cx.tcx.visibility(def_id).is_public() && !cx.access_levels.is_reachable(def_id) {
+        if cx.tcx.visibility(def_id).is_public() && !cx.effective_visibilities.is_reachable(def_id)
+        {
             if vis_span.from_expansion() {
                 applicability = Applicability::MaybeIncorrect;
             }
@@ -1414,22 +1415,26 @@ impl<'tcx> LateLintPass<'tcx> for UnreachablePub {
         if let hir::ItemKind::Use(_, hir::UseKind::ListStem) = &item.kind {
             return;
         }
-        self.perform_lint(cx, "item", item.def_id.def_id, item.vis_span, true);
+        self.perform_lint(cx, "item", item.owner_id.def_id, item.vis_span, true);
     }
 
     fn check_foreign_item(&mut self, cx: &LateContext<'_>, foreign_item: &hir::ForeignItem<'tcx>) {
-        self.perform_lint(cx, "item", foreign_item.def_id.def_id, foreign_item.vis_span, true);
+        self.perform_lint(cx, "item", foreign_item.owner_id.def_id, foreign_item.vis_span, true);
     }
 
     fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) {
-        let def_id = cx.tcx.hir().local_def_id(field.hir_id);
+        let map = cx.tcx.hir();
+        let def_id = map.local_def_id(field.hir_id);
+        if matches!(map.get(map.get_parent_node(field.hir_id)), Node::Variant(_)) {
+            return;
+        }
         self.perform_lint(cx, "field", def_id, field.vis_span, false);
     }
 
     fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {
         // Only lint inherent impl items.
-        if cx.tcx.associated_item(impl_item.def_id).trait_item_def_id.is_none() {
-            self.perform_lint(cx, "item", impl_item.def_id.def_id, impl_item.vis_span, false);
+        if cx.tcx.associated_item(impl_item.owner_id).trait_item_def_id.is_none() {
+            self.perform_lint(cx, "item", impl_item.owner_id.def_id, impl_item.vis_span, false);
         }
     }
 }
@@ -1638,7 +1643,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
         use rustc_middle::ty::PredicateKind::*;
 
         if cx.tcx.features().trivial_bounds {
-            let predicates = cx.tcx.predicates_of(item.def_id);
+            let predicates = cx.tcx.predicates_of(item.owner_id);
             for &(predicate, span) in predicates.predicates {
                 let predicate_kind_name = match predicate.kind().skip_binder() {
                     Trait(..) => "trait",
@@ -1881,7 +1886,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnameableTestItems {
             if let hir::ItemKind::Mod(..) = it.kind {
             } else {
                 self.items_nameable = false;
-                self.boundary = Some(it.def_id);
+                self.boundary = Some(it.owner_id);
             }
             return;
         }
@@ -1898,7 +1903,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnameableTestItems {
     }
 
     fn check_item_post(&mut self, _cx: &LateContext<'_>, it: &hir::Item<'_>) {
-        if !self.items_nameable && self.boundary == Some(it.def_id) {
+        if !self.items_nameable && self.boundary == Some(it.owner_id) {
             self.items_nameable = true;
         }
     }
@@ -2164,7 +2169,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
         use rustc_middle::middle::resolve_lifetime::Region;
 
-        let def_id = item.def_id.def_id;
+        let def_id = item.owner_id.def_id;
         if let hir::ItemKind::Struct(_, ref hir_generics)
         | hir::ItemKind::Enum(_, ref hir_generics)
         | hir::ItemKind::Union(_, ref hir_generics) = item.kind
@@ -2743,7 +2748,7 @@ impl ClashingExternDeclarations {
     /// Insert a new foreign item into the seen set. If a symbol with the same name already exists
     /// for the item, return its HirId without updating the set.
     fn insert(&mut self, tcx: TyCtxt<'_>, fi: &hir::ForeignItem<'_>) -> Option<HirId> {
-        let did = fi.def_id.to_def_id();
+        let did = fi.owner_id.to_def_id();
         let instance = Instance::new(did, ty::List::identity_for_item(tcx, did));
         let name = Symbol::intern(tcx.symbol_name(instance).name);
         if let Some(&hir_id) = self.seen_decls.get(&name) {
@@ -2761,14 +2766,14 @@ impl ClashingExternDeclarations {
     /// symbol's name.
     fn name_of_extern_decl(tcx: TyCtxt<'_>, fi: &hir::ForeignItem<'_>) -> SymbolName {
         if let Some((overridden_link_name, overridden_link_name_span)) =
-            tcx.codegen_fn_attrs(fi.def_id).link_name.map(|overridden_link_name| {
+            tcx.codegen_fn_attrs(fi.owner_id).link_name.map(|overridden_link_name| {
                 // FIXME: Instead of searching through the attributes again to get span
                 // information, we could have codegen_fn_attrs also give span information back for
                 // where the attribute was defined. However, until this is found to be a
                 // bottleneck, this does just fine.
                 (
                     overridden_link_name,
-                    tcx.get_attr(fi.def_id.to_def_id(), sym::link_name).unwrap().span,
+                    tcx.get_attr(fi.owner_id.to_def_id(), sym::link_name).unwrap().span,
                 )
             })
         {
@@ -2985,10 +2990,10 @@ impl<'tcx> LateLintPass<'tcx> for ClashingExternDeclarations {
             let tcx = cx.tcx;
             if let Some(existing_hid) = self.insert(tcx, this_fi) {
                 let existing_decl_ty = tcx.type_of(tcx.hir().local_def_id(existing_hid));
-                let this_decl_ty = tcx.type_of(this_fi.def_id);
+                let this_decl_ty = tcx.type_of(this_fi.owner_id);
                 debug!(
                     "ClashingExternDeclarations: Comparing existing {:?}: {:?} to this {:?}: {:?}",
-                    existing_hid, existing_decl_ty, this_fi.def_id, this_decl_ty
+                    existing_hid, existing_decl_ty, this_fi.owner_id, this_decl_ty
                 );
                 // Check that the declarations match.
                 if !Self::structurally_same_type(
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 63a11877333..cec0003ffea 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -31,7 +31,7 @@ use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::{CrateNum, DefId};
 use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
-use rustc_middle::middle::privacy::AccessLevels;
+use rustc_middle::middle::privacy::EffectiveVisibilities;
 use rustc_middle::middle::stability;
 use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
 use rustc_middle::ty::print::with_no_trimmed_paths;
@@ -542,7 +542,7 @@ pub struct LateContext<'tcx> {
     pub param_env: ty::ParamEnv<'tcx>,
 
     /// Items accessible from the crate being checked.
-    pub access_levels: &'tcx AccessLevels,
+    pub effective_visibilities: &'tcx EffectiveVisibilities,
 
     /// The store of registered lints and the lint levels.
     pub lint_store: &'tcx LintStore,
diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs
index d4e19ef6b22..303fcb1a1d1 100644
--- a/compiler/rustc_lint/src/late.rs
+++ b/compiler/rustc_lint/src/late.rs
@@ -338,14 +338,14 @@ fn late_lint_mod_pass<'tcx, T: LateLintPass<'tcx>>(
     module_def_id: LocalDefId,
     pass: T,
 ) {
-    let access_levels = &tcx.privacy_access_levels(());
+    let effective_visibilities = &tcx.effective_visibilities(());
 
     let context = LateContext {
         tcx,
         enclosing_body: None,
         cached_typeck_results: Cell::new(None),
         param_env: ty::ParamEnv::empty(),
-        access_levels,
+        effective_visibilities,
         lint_store: unerased_lint_store(tcx),
         last_node_with_lint_attrs: tcx.hir().local_def_id_to_hir_id(module_def_id),
         generics: None,
@@ -386,14 +386,14 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx>>(
 }
 
 fn late_lint_pass_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, pass: T) {
-    let access_levels = &tcx.privacy_access_levels(());
+    let effective_visibilities = &tcx.effective_visibilities(());
 
     let context = LateContext {
         tcx,
         enclosing_body: None,
         cached_typeck_results: Cell::new(None),
         param_env: ty::ParamEnv::empty(),
-        access_levels,
+        effective_visibilities,
         lint_store: unerased_lint_store(tcx),
         last_node_with_lint_attrs: hir::CRATE_HIR_ID,
         generics: None,
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index fee6e080c4f..5288fc542d7 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -212,7 +212,7 @@ macro_rules! late_lint_mod_passes {
                 TypeLimits: TypeLimits::new(),
                 NonSnakeCase: NonSnakeCase,
                 InvalidNoMangleItems: InvalidNoMangleItems,
-                // Depends on access levels
+                // Depends on effective visibilities
                 UnreachablePub: UnreachablePub,
                 ExplicitOutlivesRequirements: ExplicitOutlivesRequirements,
                 InvalidValue: InvalidValue,
diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
index 7f6f4a0abb4..00bf287ba6b 100644
--- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
+++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
@@ -61,7 +61,7 @@ declare_lint_pass!(OpaqueHiddenInferredBound => [OPAQUE_HIDDEN_INFERRED_BOUND]);
 impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
         let hir::ItemKind::OpaqueTy(_) = &item.kind else { return; };
-        let def_id = item.def_id.def_id.to_def_id();
+        let def_id = item.owner_id.def_id.to_def_id();
         let infcx = &cx.tcx.infer_ctxt().build();
         // For every projection predicate in the opaque type's explicit bounds,
         // check that the type that we're assigning actually satisfies the bounds
diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs
index a118dda8b40..f22f38aa2ce 100644
--- a/compiler/rustc_lint/src/traits.rs
+++ b/compiler/rustc_lint/src/traits.rs
@@ -89,7 +89,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
         use rustc_middle::ty::PredicateKind::*;
 
-        let predicates = cx.tcx.explicit_predicates_of(item.def_id);
+        let predicates = cx.tcx.explicit_predicates_of(item.owner_id);
         for &(predicate, span) in predicates.predicates {
             let Trait(trait_predicate) = predicate.kind().skip_binder() else {
                 continue
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 7c99bb2790f..37caab2da0f 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -11,7 +11,7 @@ use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::{self, AdtKind, DefIdTree, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable};
 use rustc_span::source_map;
 use rustc_span::symbol::sym;
-use rustc_span::{Span, Symbol, DUMMY_SP};
+use rustc_span::{Span, Symbol};
 use rustc_target::abi::{Abi, WrappingRange};
 use rustc_target::abi::{Integer, TagEncoding, Variants};
 use rustc_target::spec::abi::Abi as SpecAbi;
@@ -931,7 +931,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         match *ty.kind() {
             ty::Adt(def, substs) => {
                 if def.is_box() && matches!(self.mode, CItemKind::Definition) {
-                    if ty.boxed_ty().is_sized(tcx.at(DUMMY_SP), self.cx.param_env) {
+                    if ty.boxed_ty().is_sized(tcx, self.cx.param_env) {
                         return FfiSafe;
                     } else {
                         return FfiUnsafe {
@@ -1082,7 +1082,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _)
                 if {
                     matches!(self.mode, CItemKind::Definition)
-                        && ty.is_sized(self.cx.tcx.at(DUMMY_SP), self.cx.param_env)
+                        && ty.is_sized(self.cx.tcx, self.cx.param_env)
                 } =>
             {
                 FfiSafe
@@ -1360,7 +1360,7 @@ declare_lint_pass!(VariantSizeDifferences => [VARIANT_SIZE_DIFFERENCES]);
 impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences {
     fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
         if let hir::ItemKind::Enum(ref enum_definition, _) = it.kind {
-            let t = cx.tcx.type_of(it.def_id);
+            let t = cx.tcx.type_of(it.owner_id);
             let ty = cx.tcx.erase_regions(t);
             let Ok(layout) = cx.layout_of(ty) else { return };
             let Variants::Multiple {
diff --git a/compiler/rustc_metadata/src/foreign_modules.rs b/compiler/rustc_metadata/src/foreign_modules.rs
index 2ca4cd17fdf..d1c2f3104d0 100644
--- a/compiler/rustc_metadata/src/foreign_modules.rs
+++ b/compiler/rustc_metadata/src/foreign_modules.rs
@@ -6,13 +6,13 @@ use rustc_session::cstore::ForeignModule;
 pub(crate) fn collect(tcx: TyCtxt<'_>) -> Vec<ForeignModule> {
     let mut modules = Vec::new();
     for id in tcx.hir().items() {
-        if !matches!(tcx.def_kind(id.def_id), DefKind::ForeignMod) {
+        if !matches!(tcx.def_kind(id.owner_id), DefKind::ForeignMod) {
             continue;
         }
         let item = tcx.hir().item(id);
         if let hir::ItemKind::ForeignMod { items, .. } = item.kind {
-            let foreign_items = items.iter().map(|it| it.id.def_id.to_def_id()).collect();
-            modules.push(ForeignModule { foreign_items, def_id: id.def_id.to_def_id() });
+            let foreign_items = items.iter().map(|it| it.id.owner_id.to_def_id()).collect();
+            modules.push(ForeignModule { foreign_items, def_id: id.owner_id.to_def_id() });
         }
     }
     modules
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index 676c67bad82..20a2e78299a 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -98,7 +98,7 @@ struct Collector<'tcx> {
 
 impl<'tcx> Collector<'tcx> {
     fn process_item(&mut self, id: rustc_hir::ItemId) {
-        if !matches!(self.tcx.def_kind(id.def_id), DefKind::ForeignMod) {
+        if !matches!(self.tcx.def_kind(id.owner_id), DefKind::ForeignMod) {
             return;
         }
 
@@ -372,17 +372,17 @@ impl<'tcx> Collector<'tcx> {
                 }
                 _ => {
                     for child_item in foreign_mod_items {
-                        if self.tcx.def_kind(child_item.id.def_id).has_codegen_attrs()
+                        if self.tcx.def_kind(child_item.id.owner_id).has_codegen_attrs()
                             && self
                                 .tcx
-                                .codegen_fn_attrs(child_item.id.def_id)
+                                .codegen_fn_attrs(child_item.id.owner_id)
                                 .link_ordinal
                                 .is_some()
                         {
                             let link_ordinal_attr = self
                                 .tcx
                                 .hir()
-                                .attrs(child_item.id.def_id.into())
+                                .attrs(child_item.id.owner_id.into())
                                 .iter()
                                 .find(|a| a.has_name(sym::link_ordinal))
                                 .unwrap();
@@ -402,7 +402,7 @@ impl<'tcx> Collector<'tcx> {
                 filename,
                 kind,
                 cfg,
-                foreign_module: Some(it.def_id.to_def_id()),
+                foreign_module: Some(it.owner_id.to_def_id()),
                 wasm_import_module: wasm_import_module.map(|(name, _)| name),
                 verbatim,
                 dll_imports,
@@ -505,7 +505,7 @@ impl<'tcx> Collector<'tcx> {
     fn i686_arg_list_size(&self, item: &hir::ForeignItemRef) -> usize {
         let argument_types: &List<Ty<'_>> = self.tcx.erase_late_bound_regions(
             self.tcx
-                .type_of(item.id.def_id)
+                .type_of(item.id.owner_id)
                 .fn_sig(self.tcx)
                 .inputs()
                 .map_bound(|slice| self.tcx.mk_type_list(slice.iter())),
@@ -557,7 +557,7 @@ impl<'tcx> Collector<'tcx> {
             }
         };
 
-        let codegen_fn_attrs = self.tcx.codegen_fn_attrs(item.id.def_id);
+        let codegen_fn_attrs = self.tcx.codegen_fn_attrs(item.id.owner_id);
         let import_name_type = codegen_fn_attrs
             .link_ordinal
             .map_or(import_name_type, |ord| Some(PeImportNameType::Ordinal(ord)));
@@ -567,7 +567,7 @@ impl<'tcx> Collector<'tcx> {
             import_name_type,
             calling_convention,
             span: item.span,
-            is_fn: self.tcx.def_kind(item.id.def_id).is_fn_like(),
+            is_fn: self.tcx.def_kind(item.id.owner_id).is_fn_like(),
         }
     }
 }
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 691e3d0f8f9..17a7532044a 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -15,7 +15,6 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
 use rustc_hir::diagnostic_items::DiagnosticItems;
-use rustc_hir::lang_items;
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_middle::metadata::ModChild;
 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
@@ -967,7 +966,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
     }
 
     /// Iterates over the language items in the given crate.
-    fn get_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] {
+    fn get_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, LangItem)] {
         tcx.arena.alloc_from_iter(
             self.root
                 .lang_items
@@ -1319,7 +1318,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         )
     }
 
-    fn get_missing_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] {
+    fn get_missing_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [LangItem] {
         tcx.arena.alloc_from_iter(self.root.lang_items_missing.decode(self))
     }
 
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 1743bbd6a21..87fa69e1639 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -17,7 +17,7 @@ use rustc_hir::def_id::{
 };
 use rustc_hir::definitions::DefPathData;
 use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::lang_items;
+use rustc_hir::lang_items::LangItem;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::dependency_format::Linkage;
 use rustc_middle::middle::exported_symbols::{
@@ -787,9 +787,8 @@ fn should_encode_attr(
     } else if attr.doc_str().is_some() {
         // We keep all public doc comments because they might be "imported" into downstream crates
         // if they use `#[doc(inline)]` to copy an item's documentation into their own.
-        *is_def_id_public.get_or_insert_with(|| {
-            tcx.privacy_access_levels(()).get_effective_vis(def_id).is_some()
-        })
+        *is_def_id_public
+            .get_or_insert_with(|| tcx.effective_visibilities(()).effective_vis(def_id).is_some())
     } else if attr.has_name(sym::doc) {
         // If this is a `doc` attribute, and it's marked `inline` (as in `#[doc(inline)]`), we can
         // remove it. It won't be inlinable in downstream crates.
@@ -1291,21 +1290,21 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                         // from name resolution point of view.
                         hir::ItemKind::ForeignMod { items, .. } => {
                             for foreign_item in items {
-                                yield foreign_item.id.def_id.def_id.local_def_index;
+                                yield foreign_item.id.owner_id.def_id.local_def_index;
                             }
                         }
                         // Only encode named non-reexport children, reexports are encoded
                         // separately and unnamed items are not used by name resolution.
                         hir::ItemKind::ExternCrate(..) => continue,
                         hir::ItemKind::Struct(ref vdata, _) => {
-                            yield item_id.def_id.def_id.local_def_index;
+                            yield item_id.owner_id.def_id.local_def_index;
                             // Encode constructors which take a separate slot in value namespace.
                             if let Some(ctor_hir_id) = vdata.ctor_hir_id() {
                                 yield tcx.hir().local_def_id(ctor_hir_id).local_def_index;
                             }
                         }
-                        _ if tcx.def_key(item_id.def_id.to_def_id()).get_opt_name().is_some() => {
-                            yield item_id.def_id.def_id.local_def_index;
+                        _ if tcx.def_key(item_id.owner_id.to_def_id()).get_opt_name().is_some() => {
+                            yield item_id.owner_id.def_id.local_def_index;
                         }
                         _ => continue,
                     }
@@ -1542,7 +1541,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 record!(self.tables.macro_definition[def_id] <- &*macro_def.body);
             }
             hir::ItemKind::Mod(ref m) => {
-                return self.encode_info_for_mod(item.def_id.def_id, m);
+                return self.encode_info_for_mod(item.owner_id.def_id, m);
             }
             hir::ItemKind::OpaqueTy(..) => {
                 self.encode_explicit_item_bounds(def_id);
@@ -1674,7 +1673,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         // normally in the visitor walk.
         match item.kind {
             hir::ItemKind::Enum(..) => {
-                let def = self.tcx.adt_def(item.def_id.to_def_id());
+                let def = self.tcx.adt_def(item.owner_id.to_def_id());
                 for (i, variant) in def.variants().iter_enumerated() {
                     self.encode_enum_variant_info(def, i);
 
@@ -1684,7 +1683,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 }
             }
             hir::ItemKind::Struct(ref struct_def, _) => {
-                let def = self.tcx.adt_def(item.def_id.to_def_id());
+                let def = self.tcx.adt_def(item.owner_id.to_def_id());
                 // If the struct has a constructor, encode it.
                 if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
                     let ctor_def_id = self.tcx.hir().local_def_id(ctor_hir_id);
@@ -1693,13 +1692,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             }
             hir::ItemKind::Impl { .. } => {
                 for &trait_item_def_id in
-                    self.tcx.associated_item_def_ids(item.def_id.to_def_id()).iter()
+                    self.tcx.associated_item_def_ids(item.owner_id.to_def_id()).iter()
                 {
                     self.encode_info_for_impl_item(trait_item_def_id);
                 }
             }
             hir::ItemKind::Trait(..) => {
-                for &item_def_id in self.tcx.associated_item_def_ids(item.def_id.to_def_id()).iter()
+                for &item_def_id in
+                    self.tcx.associated_item_def_ids(item.owner_id.to_def_id()).iter()
                 {
                     self.encode_info_for_trait_item(item_def_id);
                 }
@@ -1905,22 +1905,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         self.lazy_array(diagnostic_items.iter().map(|(&name, def_id)| (name, def_id.index)))
     }
 
-    fn encode_lang_items(&mut self) -> LazyArray<(DefIndex, usize)> {
+    fn encode_lang_items(&mut self) -> LazyArray<(DefIndex, LangItem)> {
         empty_proc_macro!(self);
-        let tcx = self.tcx;
-        let lang_items = tcx.lang_items();
-        let lang_items = lang_items.items().iter();
-        self.lazy_array(lang_items.enumerate().filter_map(|(i, &opt_def_id)| {
-            if let Some(def_id) = opt_def_id {
-                if def_id.is_local() {
-                    return Some((def_id.index, i));
-                }
-            }
-            None
+        let lang_items = self.tcx.lang_items().iter();
+        self.lazy_array(lang_items.filter_map(|(lang_item, def_id)| {
+            def_id.as_local().map(|id| (id.local_def_index, lang_item))
         }))
     }
 
-    fn encode_lang_items_missing(&mut self) -> LazyArray<lang_items::LangItem> {
+    fn encode_lang_items_missing(&mut self) -> LazyArray<LangItem> {
         empty_proc_macro!(self);
         let tcx = self.tcx;
         self.lazy_array(&tcx.lang_items().missing)
@@ -1940,8 +1933,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             FxHashMap::default();
 
         for id in tcx.hir().items() {
-            if matches!(tcx.def_kind(id.def_id), DefKind::Impl) {
-                if let Some(trait_ref) = tcx.impl_trait_ref(id.def_id) {
+            if matches!(tcx.def_kind(id.owner_id), DefKind::Impl) {
+                if let Some(trait_ref) = tcx.impl_trait_ref(id.owner_id) {
                     let simplified_self_ty = fast_reject::simplify_type(
                         self.tcx,
                         trait_ref.self_ty(),
@@ -1951,7 +1944,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     fx_hash_map
                         .entry(trait_ref.def_id)
                         .or_default()
-                        .push((id.def_id.def_id.local_def_index, simplified_self_ty));
+                        .push((id.owner_id.def_id.local_def_index, simplified_self_ty));
                 }
             }
         }
@@ -2092,12 +2085,12 @@ impl<'a, 'tcx> Visitor<'tcx> for EncodeContext<'a, 'tcx> {
         intravisit::walk_item(self, item);
         match item.kind {
             hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => {} // ignore these
-            _ => self.encode_info_for_item(item.def_id.to_def_id(), item),
+            _ => self.encode_info_for_item(item.owner_id.to_def_id(), item),
         }
     }
     fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem<'tcx>) {
         intravisit::walk_foreign_item(self, ni);
-        self.encode_info_for_foreign_item(ni.def_id.to_def_id(), ni);
+        self.encode_info_for_foreign_item(ni.owner_id.to_def_id(), ni);
     }
     fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
         intravisit::walk_generics(self, generics);
@@ -2316,8 +2309,8 @@ pub fn provide(providers: &mut Providers) {
 
             let mut traits = Vec::new();
             for id in tcx.hir().items() {
-                if matches!(tcx.def_kind(id.def_id), DefKind::Trait | DefKind::TraitAlias) {
-                    traits.push(id.def_id.to_def_id())
+                if matches!(tcx.def_kind(id.owner_id), DefKind::Trait | DefKind::TraitAlias) {
+                    traits.push(id.owner_id.to_def_id())
                 }
             }
 
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 27dc8ff16ac..774cff2075d 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -12,7 +12,7 @@ use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind};
 use rustc_hir::def_id::{CrateNum, DefId, DefIndex, DefPathHash, StableCrateId};
 use rustc_hir::definitions::DefKey;
-use rustc_hir::lang_items;
+use rustc_hir::lang_items::LangItem;
 use rustc_index::bit_set::{BitSet, FiniteBitSet};
 use rustc_index::vec::IndexVec;
 use rustc_middle::metadata::ModChild;
@@ -230,8 +230,8 @@ pub(crate) struct CrateRoot {
     dylib_dependency_formats: LazyArray<Option<LinkagePreference>>,
     lib_features: LazyArray<(Symbol, Option<Symbol>)>,
     stability_implications: LazyArray<(Symbol, Symbol)>,
-    lang_items: LazyArray<(DefIndex, usize)>,
-    lang_items_missing: LazyArray<lang_items::LangItem>,
+    lang_items: LazyArray<(DefIndex, LangItem)>,
+    lang_items_missing: LazyArray<LangItem>,
     diagnostic_items: LazyArray<(Symbol, DefIndex)>,
     native_libraries: LazyArray<NativeLib>,
     foreign_modules: LazyArray<ForeignModule>,
diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs
index d2847e4bc12..f8aae86fe3d 100644
--- a/compiler/rustc_middle/src/arena.rs
+++ b/compiler/rustc_middle/src/arena.rs
@@ -77,7 +77,7 @@ macro_rules! arena_types {
                     rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Ty<'tcx>>
                 >,
             [] all_traits: Vec<rustc_hir::def_id::DefId>,
-            [] privacy_access_levels: rustc_middle::middle::privacy::AccessLevels,
+            [] effective_visibilities: rustc_middle::middle::privacy::EffectiveVisibilities,
             [] foreign_module: rustc_session::cstore::ForeignModule,
             [] foreign_modules: Vec<rustc_session::cstore::ForeignModule>,
             [] upvars_mentioned: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>,
@@ -96,7 +96,7 @@ macro_rules! arena_types {
             // since we need to allocate this type on both the `rustc_hir` arena
             // (during lowering) and the `librustc_middle` arena (for decoding MIR)
             [decode] asm_template: rustc_ast::InlineAsmTemplatePiece,
-            [decode] used_trait_imports: rustc_data_structures::fx::FxHashSet<rustc_hir::def_id::LocalDefId>,
+            [decode] used_trait_imports: rustc_data_structures::unord::UnordSet<rustc_hir::def_id::LocalDefId>,
             [decode] is_late_bound_map: rustc_data_structures::fx::FxIndexSet<rustc_hir::def_id::LocalDefId>,
             [decode] impl_source: rustc_middle::traits::ImplSource<'tcx, ()>,
 
diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs
index a7a7ac0599d..43903e6739f 100644
--- a/compiler/rustc_middle/src/error.rs
+++ b/compiler/rustc_middle/src/error.rs
@@ -55,3 +55,12 @@ pub struct ConstEvalNonIntError {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(middle_strict_coherence_needs_negative_coherence)]
+pub(crate) struct StrictCoherenceNeedsNegativeCoherence {
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub attr_span: Option<Span>,
+}
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 302f12a6f7d..83a4d16d7a9 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -354,19 +354,19 @@ impl<'hir> Map<'hir> {
     }
 
     pub fn item(self, id: ItemId) -> &'hir Item<'hir> {
-        self.tcx.hir_owner(id.def_id).unwrap().node.expect_item()
+        self.tcx.hir_owner(id.owner_id).unwrap().node.expect_item()
     }
 
     pub fn trait_item(self, id: TraitItemId) -> &'hir TraitItem<'hir> {
-        self.tcx.hir_owner(id.def_id).unwrap().node.expect_trait_item()
+        self.tcx.hir_owner(id.owner_id).unwrap().node.expect_trait_item()
     }
 
     pub fn impl_item(self, id: ImplItemId) -> &'hir ImplItem<'hir> {
-        self.tcx.hir_owner(id.def_id).unwrap().node.expect_impl_item()
+        self.tcx.hir_owner(id.owner_id).unwrap().node.expect_impl_item()
     }
 
     pub fn foreign_item(self, id: ForeignItemId) -> &'hir ForeignItem<'hir> {
-        self.tcx.hir_owner(id.def_id).unwrap().node.expect_foreign_item()
+        self.tcx.hir_owner(id.owner_id).unwrap().node.expect_foreign_item()
     }
 
     pub fn body(self, id: BodyId) -> &'hir Body<'hir> {
@@ -1377,14 +1377,14 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
 
     fn visit_item(&mut self, item: &'hir Item<'hir>) {
         if associated_body(Node::Item(item)).is_some() {
-            self.body_owners.push(item.def_id.def_id);
+            self.body_owners.push(item.owner_id.def_id);
         }
 
         self.items.push(item.item_id());
 
         // Items that are modules are handled here instead of in visit_mod.
         if let ItemKind::Mod(module) = &item.kind {
-            self.submodules.push(item.def_id);
+            self.submodules.push(item.owner_id);
             // A module collector does not recurse inside nested modules.
             if self.crate_collector {
                 intravisit::walk_mod(self, module, item.hir_id());
@@ -1413,7 +1413,7 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
 
     fn visit_trait_item(&mut self, item: &'hir TraitItem<'hir>) {
         if associated_body(Node::TraitItem(item)).is_some() {
-            self.body_owners.push(item.def_id.def_id);
+            self.body_owners.push(item.owner_id.def_id);
         }
 
         self.trait_items.push(item.trait_item_id());
@@ -1422,7 +1422,7 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
 
     fn visit_impl_item(&mut self, item: &'hir ImplItem<'hir>) {
         if associated_body(Node::ImplItem(item)).is_some() {
-            self.body_owners.push(item.def_id.def_id);
+            self.body_owners.push(item.owner_id.def_id);
         }
 
         self.impl_items.push(item.impl_item_id());
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index 1ce98a03c8a..1c6264ad036 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -67,10 +67,10 @@ impl ModuleItems {
     pub fn definitions(&self) -> impl Iterator<Item = LocalDefId> + '_ {
         self.items
             .iter()
-            .map(|id| id.def_id.def_id)
-            .chain(self.trait_items.iter().map(|id| id.def_id.def_id))
-            .chain(self.impl_items.iter().map(|id| id.def_id.def_id))
-            .chain(self.foreign_items.iter().map(|id| id.def_id.def_id))
+            .map(|id| id.owner_id.def_id)
+            .chain(self.trait_items.iter().map(|id| id.owner_id.def_id))
+            .chain(self.impl_items.iter().map(|id| id.owner_id.def_id))
+            .chain(self.foreign_items.iter().map(|id| id.owner_id.def_id))
     }
 
     pub fn par_items(&self, f: impl Fn(ItemId) + Send + Sync) {
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index f4f1d82c3b8..d3cf519b633 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -302,8 +302,10 @@ impl<'tcx, V> Canonical<'tcx, V> {
     }
 }
 
-pub type QueryOutlivesConstraint<'tcx> =
-    (ty::Binder<'tcx, ty::OutlivesPredicate<GenericArg<'tcx>, Region<'tcx>>>, ConstraintCategory);
+pub type QueryOutlivesConstraint<'tcx> = (
+    ty::Binder<'tcx, ty::OutlivesPredicate<GenericArg<'tcx>, Region<'tcx>>>,
+    ConstraintCategory<'tcx>,
+);
 
 TrivialTypeTraversalAndLiftImpls! {
     for <'tcx> {
diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs
index 31c20fa14aa..dd4332d0db6 100644
--- a/compiler/rustc_middle/src/middle/lang_items.rs
+++ b/compiler/rustc_middle/src/middle/lang_items.rs
@@ -36,10 +36,6 @@ impl<'tcx> TyCtxt<'tcx> {
             _ => None,
         }
     }
-
-    pub fn is_weak_lang_item(self, item_def_id: DefId) -> bool {
-        self.lang_items().is_weak_lang_item(item_def_id)
-    }
 }
 
 /// Returns `true` if the specified `lang_item` must be present for this
diff --git a/compiler/rustc_middle/src/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs
index 5687e5bdc43..ffbd6d10da6 100644
--- a/compiler/rustc_middle/src/middle/privacy.rs
+++ b/compiler/rustc_middle/src/middle/privacy.rs
@@ -6,109 +6,103 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_macros::HashStable;
 use rustc_query_system::ich::StableHashingContext;
-use rustc_span::def_id::{DefId, LocalDefId};
-use std::hash::Hash;
+use rustc_span::def_id::LocalDefId;
 
-/// Represents the levels of accessibility an item can have.
+/// Represents the levels of effective visibility an item can have.
 ///
-/// The variants are sorted in ascending order of accessibility.
+/// The variants are sorted in ascending order of directness.
 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, HashStable)]
-pub enum AccessLevel {
-    /// Superset of `AccessLevel::Reachable` used to mark impl Trait items.
-    ReachableFromImplTrait,
-    /// Exported items + items participating in various kinds of public interfaces,
-    /// but not directly nameable. For example, if function `fn f() -> T {...}` is
-    /// public, then type `T` is reachable. Its values can be obtained by other crates
-    /// even if the type itself is not nameable.
+pub enum Level {
+    /// Superset of `Reachable` including items leaked through return position `impl Trait`.
+    ReachableThroughImplTrait,
+    /// Item is either reexported, or leaked through any kind of interface.
+    /// For example, if function `fn f() -> T {...}` is directly public, then type `T` is publicly
+    /// reachable and its values can be obtained by other crates even if the type itself is not
+    /// nameable.
     Reachable,
-    /// Public items + items accessible to other crates with the help of `pub use` re-exports.
-    Exported,
-    /// Items accessible to other crates directly, without the help of re-exports.
-    Public,
+    /// Item is accessible either directly, or with help of `use` reexports.
+    Reexported,
+    /// Item is directly accessible, without help of reexports.
+    Direct,
 }
 
-impl AccessLevel {
-    pub fn all_levels() -> [AccessLevel; 4] {
-        [
-            AccessLevel::Public,
-            AccessLevel::Exported,
-            AccessLevel::Reachable,
-            AccessLevel::ReachableFromImplTrait,
-        ]
+impl Level {
+    pub fn all_levels() -> [Level; 4] {
+        [Level::Direct, Level::Reexported, Level::Reachable, Level::ReachableThroughImplTrait]
     }
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable)]
 pub struct EffectiveVisibility {
-    public: Visibility,
-    exported: Visibility,
+    direct: Visibility,
+    reexported: Visibility,
     reachable: Visibility,
-    reachable_from_impl_trait: Visibility,
+    reachable_through_impl_trait: Visibility,
 }
 
 impl EffectiveVisibility {
-    pub fn get(&self, tag: AccessLevel) -> &Visibility {
-        match tag {
-            AccessLevel::Public => &self.public,
-            AccessLevel::Exported => &self.exported,
-            AccessLevel::Reachable => &self.reachable,
-            AccessLevel::ReachableFromImplTrait => &self.reachable_from_impl_trait,
+    pub fn at_level(&self, level: Level) -> &Visibility {
+        match level {
+            Level::Direct => &self.direct,
+            Level::Reexported => &self.reexported,
+            Level::Reachable => &self.reachable,
+            Level::ReachableThroughImplTrait => &self.reachable_through_impl_trait,
         }
     }
 
-    fn get_mut(&mut self, tag: AccessLevel) -> &mut Visibility {
-        match tag {
-            AccessLevel::Public => &mut self.public,
-            AccessLevel::Exported => &mut self.exported,
-            AccessLevel::Reachable => &mut self.reachable,
-            AccessLevel::ReachableFromImplTrait => &mut self.reachable_from_impl_trait,
+    fn at_level_mut(&mut self, level: Level) -> &mut Visibility {
+        match level {
+            Level::Direct => &mut self.direct,
+            Level::Reexported => &mut self.reexported,
+            Level::Reachable => &mut self.reachable,
+            Level::ReachableThroughImplTrait => &mut self.reachable_through_impl_trait,
         }
     }
 
-    pub fn is_public_at_level(&self, tag: AccessLevel) -> bool {
-        self.get(tag).is_public()
+    pub fn is_public_at_level(&self, level: Level) -> bool {
+        self.at_level(level).is_public()
     }
 
     pub fn from_vis(vis: Visibility) -> EffectiveVisibility {
         EffectiveVisibility {
-            public: vis,
-            exported: vis,
+            direct: vis,
+            reexported: vis,
             reachable: vis,
-            reachable_from_impl_trait: vis,
+            reachable_through_impl_trait: vis,
         }
     }
 }
 
-/// Holds a map of accessibility levels for reachable HIR nodes.
-#[derive(Debug, Clone)]
-pub struct AccessLevels<Id = LocalDefId> {
-    map: FxHashMap<Id, EffectiveVisibility>,
+/// Holds a map of effective visibilities for reachable HIR nodes.
+#[derive(Default, Clone, Debug)]
+pub struct EffectiveVisibilities {
+    map: FxHashMap<LocalDefId, EffectiveVisibility>,
 }
 
-impl<Id: Hash + Eq + Copy> AccessLevels<Id> {
-    pub fn is_public_at_level(&self, id: Id, tag: AccessLevel) -> bool {
-        self.get_effective_vis(id)
-            .map_or(false, |effective_vis| effective_vis.is_public_at_level(tag))
+impl EffectiveVisibilities {
+    pub fn is_public_at_level(&self, id: LocalDefId, level: Level) -> bool {
+        self.effective_vis(id)
+            .map_or(false, |effective_vis| effective_vis.is_public_at_level(level))
     }
 
-    /// See `AccessLevel::Reachable`.
-    pub fn is_reachable(&self, id: Id) -> bool {
-        self.is_public_at_level(id, AccessLevel::Reachable)
+    /// See `Level::Reachable`.
+    pub fn is_reachable(&self, id: LocalDefId) -> bool {
+        self.is_public_at_level(id, Level::Reachable)
     }
 
-    /// See `AccessLevel::Exported`.
-    pub fn is_exported(&self, id: Id) -> bool {
-        self.is_public_at_level(id, AccessLevel::Exported)
+    /// See `Level::Reexported`.
+    pub fn is_exported(&self, id: LocalDefId) -> bool {
+        self.is_public_at_level(id, Level::Reexported)
     }
 
-    /// See `AccessLevel::Public`.
-    pub fn is_public(&self, id: Id) -> bool {
-        self.is_public_at_level(id, AccessLevel::Public)
+    /// See `Level::Direct`.
+    pub fn is_directly_public(&self, id: LocalDefId) -> bool {
+        self.is_public_at_level(id, Level::Direct)
     }
 
-    pub fn get_access_level(&self, id: Id) -> Option<AccessLevel> {
-        self.get_effective_vis(id).and_then(|effective_vis| {
-            for level in AccessLevel::all_levels() {
+    pub fn public_at_level(&self, id: LocalDefId) -> Option<Level> {
+        self.effective_vis(id).and_then(|effective_vis| {
+            for level in Level::all_levels() {
                 if effective_vis.is_public_at_level(level) {
                     return Some(level);
                 }
@@ -117,68 +111,63 @@ impl<Id: Hash + Eq + Copy> AccessLevels<Id> {
         })
     }
 
-    pub fn get_effective_vis(&self, id: Id) -> Option<&EffectiveVisibility> {
+    pub fn effective_vis(&self, id: LocalDefId) -> Option<&EffectiveVisibility> {
         self.map.get(&id)
     }
 
-    pub fn iter(&self) -> impl Iterator<Item = (&Id, &EffectiveVisibility)> {
+    pub fn iter(&self) -> impl Iterator<Item = (&LocalDefId, &EffectiveVisibility)> {
         self.map.iter()
     }
 
-    pub fn map_id<OutId: Hash + Eq + Copy>(&self, f: impl Fn(Id) -> OutId) -> AccessLevels<OutId> {
-        AccessLevels { map: self.map.iter().map(|(k, v)| (f(*k), *v)).collect() }
-    }
-
-    pub fn set_access_level(
+    pub fn set_public_at_level(
         &mut self,
-        id: Id,
+        id: LocalDefId,
         default_vis: impl FnOnce() -> Visibility,
-        tag: AccessLevel,
+        level: Level,
     ) {
         let mut effective_vis = self
-            .get_effective_vis(id)
+            .effective_vis(id)
             .copied()
             .unwrap_or_else(|| EffectiveVisibility::from_vis(default_vis()));
-        for level in AccessLevel::all_levels() {
-            if level <= tag {
-                *effective_vis.get_mut(level) = Visibility::Public;
+        for l in Level::all_levels() {
+            if l <= level {
+                *effective_vis.at_level_mut(l) = Visibility::Public;
             }
         }
         self.map.insert(id, effective_vis);
     }
-}
 
-impl<Id: Hash + Eq + Copy + Into<DefId>> AccessLevels<Id> {
     // `parent_id` is not necessarily a parent in source code tree,
     // it is the node from which the maximum effective visibility is inherited.
     pub fn update(
         &mut self,
-        id: Id,
+        id: LocalDefId,
         nominal_vis: Visibility,
         default_vis: impl FnOnce() -> Visibility,
-        parent_id: Id,
-        tag: AccessLevel,
+        parent_id: LocalDefId,
+        level: Level,
         tree: impl DefIdTree,
     ) -> bool {
         let mut changed = false;
-        let mut current_effective_vis = self.get_effective_vis(id).copied().unwrap_or_else(|| {
-            if id.into().is_crate_root() {
+        let mut current_effective_vis = self.effective_vis(id).copied().unwrap_or_else(|| {
+            if id.is_top_level_module() {
                 EffectiveVisibility::from_vis(Visibility::Public)
             } else {
                 EffectiveVisibility::from_vis(default_vis())
             }
         });
-        if let Some(inherited_effective_vis) = self.get_effective_vis(parent_id) {
-            let mut inherited_effective_vis_at_prev_level = *inherited_effective_vis.get(tag);
+        if let Some(inherited_effective_vis) = self.effective_vis(parent_id) {
+            let mut inherited_effective_vis_at_prev_level =
+                *inherited_effective_vis.at_level(level);
             let mut calculated_effective_vis = inherited_effective_vis_at_prev_level;
-            for level in AccessLevel::all_levels() {
-                if tag >= level {
-                    let inherited_effective_vis_at_level = *inherited_effective_vis.get(level);
-                    let current_effective_vis_at_level = current_effective_vis.get_mut(level);
+            for l in Level::all_levels() {
+                if level >= l {
+                    let inherited_effective_vis_at_level = *inherited_effective_vis.at_level(l);
+                    let current_effective_vis_at_level = current_effective_vis.at_level_mut(l);
                     // effective visibility for id shouldn't be recalculated if
                     // inherited from parent_id effective visibility isn't changed at next level
                     if !(inherited_effective_vis_at_prev_level == inherited_effective_vis_at_level
-                        && tag != level)
+                        && level != l)
                     {
                         calculated_effective_vis =
                             if nominal_vis.is_at_least(inherited_effective_vis_at_level, tree) {
@@ -205,15 +194,9 @@ impl<Id: Hash + Eq + Copy + Into<DefId>> AccessLevels<Id> {
     }
 }
 
-impl<Id> Default for AccessLevels<Id> {
-    fn default() -> Self {
-        AccessLevels { map: Default::default() }
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for AccessLevels {
+impl<'a> HashStable<StableHashingContext<'a>> for EffectiveVisibilities {
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let AccessLevels { ref map } = *self;
+        let EffectiveVisibilities { ref map } = *self;
         map.hash_stable(hcx, hasher);
     }
 }
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 3b80af184be..068daaadbda 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1186,6 +1186,11 @@ impl<'tcx> BasicBlockData<'tcx> {
     pub fn visitable(&self, index: usize) -> &dyn MirVisitable<'tcx> {
         if index < self.statements.len() { &self.statements[index] } else { &self.terminator }
     }
+
+    /// Does the block have no statements and an unreachable terminator?
+    pub fn is_empty_unreachable(&self) -> bool {
+        self.statements.is_empty() && matches!(self.terminator().kind, TerminatorKind::Unreachable)
+    }
 }
 
 impl<O> AssertKind<O> {
@@ -2904,7 +2909,7 @@ fn pretty_print_const_value<'tcx>(
 /// `Location` represents the position of the start of the statement; or, if
 /// `statement_index` equals the number of statements, then the start of the
 /// terminator.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, HashStable, TyEncodable, TyDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, HashStable)]
 pub struct Location {
     /// The block that the location is within.
     pub block: BasicBlock,
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index fdda62719ee..15a24aa4ace 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -81,7 +81,7 @@ impl<'tcx> MonoItem<'tcx> {
             MonoItem::Fn(instance) => tcx.symbol_name(instance),
             MonoItem::Static(def_id) => tcx.symbol_name(Instance::mono(tcx, def_id)),
             MonoItem::GlobalAsm(item_id) => {
-                SymbolName::new(tcx, &format!("global_asm_{:?}", item_id.def_id))
+                SymbolName::new(tcx, &format!("global_asm_{:?}", item_id.owner_id))
             }
         }
     }
@@ -182,7 +182,7 @@ impl<'tcx> MonoItem<'tcx> {
         match *self {
             MonoItem::Fn(Instance { def, .. }) => def.def_id().as_local(),
             MonoItem::Static(def_id) => def_id.as_local(),
-            MonoItem::GlobalAsm(item_id) => Some(item_id.def_id.def_id),
+            MonoItem::GlobalAsm(item_id) => Some(item_id.owner_id.def_id),
         }
         .map(|def_id| tcx.def_span(def_id))
     }
@@ -373,7 +373,7 @@ impl<'tcx> CodegenUnit<'tcx> {
                         }
                     }
                     MonoItem::Static(def_id) => def_id.as_local().map(Idx::index),
-                    MonoItem::GlobalAsm(item_id) => Some(item_id.def_id.def_id.index()),
+                    MonoItem::GlobalAsm(item_id) => Some(item_id.owner_id.def_id.index()),
                 },
                 item.symbol_name(tcx),
             )
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index 1d847d8f3d3..efd7357afc4 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -15,7 +15,7 @@ use smallvec::SmallVec;
 use std::cell::Cell;
 use std::fmt::{self, Debug};
 
-use super::{Field, Location, SourceInfo};
+use super::{Field, SourceInfo};
 
 #[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
 pub enum UnsafetyViolationKind {
@@ -314,12 +314,12 @@ pub struct ClosureOutlivesRequirement<'tcx> {
     pub blame_span: Span,
 
     // ... due to this reason.
-    pub category: ConstraintCategory,
+    pub category: ConstraintCategory<'tcx>,
 }
 
 // Make sure this enum doesn't unintentionally grow
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(ConstraintCategory, 16);
+rustc_data_structures::static_assert_size!(ConstraintCategory<'_>, 16);
 
 /// Outlives-constraints can be categorized to determine whether and why they
 /// are interesting (for error reporting). Order of variants indicates sort
@@ -327,8 +327,8 @@ rustc_data_structures::static_assert_size!(ConstraintCategory, 16);
 ///
 /// See also `rustc_const_eval::borrow_check::constraints`.
 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
-#[derive(TyEncodable, TyDecodable, HashStable)]
-pub enum ConstraintCategory {
+#[derive(TyEncodable, TyDecodable, HashStable, Lift, TypeVisitable, TypeFoldable)]
+pub enum ConstraintCategory<'tcx> {
     Return(ReturnConstraint),
     Yield,
     UseAsConst,
@@ -342,7 +342,7 @@ pub enum ConstraintCategory {
     ClosureBounds,
 
     /// Contains the function type if available.
-    CallArgument(Location),
+    CallArgument(Option<Ty<'tcx>>),
     CopyBound,
     SizedBound,
     Assignment,
@@ -368,10 +368,6 @@ pub enum ConstraintCategory {
     Internal,
 }
 
-TrivialTypeTraversalAndLiftImpls! {
-    ConstraintCategory,
-}
-
 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
 #[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)]
 pub enum ReturnConstraint {
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 67c85ef0d3b..a098e570305 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -912,7 +912,7 @@ rustc_queries! {
         cache_on_disk_if { true }
     }
 
-    query used_trait_imports(key: LocalDefId) -> &'tcx FxHashSet<LocalDefId> {
+    query used_trait_imports(key: LocalDefId) -> &'tcx UnordSet<LocalDefId> {
         desc { |tcx| "finding used_trait_imports `{}`", tcx.def_path_str(key.to_def_id()) }
         cache_on_disk_if { true }
     }
@@ -1065,10 +1065,10 @@ rustc_queries! {
         cache_on_disk_if { key.is_local() }
     }
 
-    /// Performs part of the privacy check and computes "access levels".
-    query privacy_access_levels(_: ()) -> &'tcx AccessLevels {
+    /// Performs part of the privacy check and computes effective visibilities.
+    query effective_visibilities(_: ()) -> &'tcx EffectiveVisibilities {
         eval_always
-        desc { "checking privacy access levels" }
+        desc { "checking effective visibilities" }
     }
     query check_private_in_public(_: ()) -> () {
         eval_always
@@ -1705,7 +1705,7 @@ rustc_queries! {
     }
 
     /// Returns the lang items defined in another crate by loading it from metadata.
-    query defined_lang_items(_: CrateNum) -> &'tcx [(DefId, usize)] {
+    query defined_lang_items(_: CrateNum) -> &'tcx [(DefId, LangItem)] {
         desc { "calculating the lang items defined in a crate" }
         separate_provide_extern
     }
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 3adc2e1b73e..e73d44bbb36 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -185,7 +185,7 @@ impl<'tcx> ObligationCause<'tcx> {
         self
     }
 
-    pub fn to_constraint_category(&self) -> ConstraintCategory {
+    pub fn to_constraint_category(&self) -> ConstraintCategory<'tcx> {
         match self.code() {
             MatchImpl(cause, _) => cause.to_constraint_category(),
             AscribeUserTypeProvePredicate(predicate_span) => {
diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs
index 0a2819feecf..f1c21588261 100644
--- a/compiler/rustc_middle/src/traits/specialization_graph.rs
+++ b/compiler/rustc_middle/src/traits/specialization_graph.rs
@@ -1,3 +1,4 @@
+use crate::error::StrictCoherenceNeedsNegativeCoherence;
 use crate::ty::fast_reject::SimplifiedType;
 use crate::ty::visit::TypeVisitable;
 use crate::ty::{self, TyCtxt};
@@ -65,9 +66,21 @@ impl OverlapMode {
 
         if with_negative_coherence {
             if strict_coherence { OverlapMode::Strict } else { OverlapMode::WithNegative }
-        } else if strict_coherence {
-            bug!("To use strict_coherence you need to set with_negative_coherence feature flag");
         } else {
+            if strict_coherence {
+                let attr_span = trait_id
+                    .as_local()
+                    .into_iter()
+                    .flat_map(|local_def_id| {
+                        tcx.hir().attrs(tcx.hir().local_def_id_to_hir_id(local_def_id))
+                    })
+                    .find(|attr| attr.has_name(sym::rustc_strict_coherence))
+                    .map(|attr| attr.span);
+                tcx.sess.emit_err(StrictCoherenceNeedsNegativeCoherence {
+                    span: tcx.def_span(trait_id),
+                    attr_span,
+                });
+            }
             OverlapMode::Stable
         }
     }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 94e3f3b63c8..8e24f4813a7 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -34,6 +34,7 @@ use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::steal::Steal;
 use rustc_data_structures::sync::{self, Lock, Lrc, ReadGuard, RwLock, WorkerLocal};
+use rustc_data_structures::unord::UnordSet;
 use rustc_data_structures::vec_map::VecMap;
 use rustc_errors::{
     DecorateLint, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, MultiSpan,
@@ -531,7 +532,7 @@ pub struct TypeckResults<'tcx> {
     /// This is used for warning unused imports. During type
     /// checking, this `Lrc` should not be cloned: it must have a ref-count
     /// of 1 so that we can insert things into the set mutably.
-    pub used_trait_imports: Lrc<FxHashSet<LocalDefId>>,
+    pub used_trait_imports: Lrc<UnordSet<LocalDefId>>,
 
     /// If any errors occurred while type-checking this body,
     /// this field will be set to `Some(ErrorGuaranteed)`.
@@ -2455,7 +2456,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     #[inline]
     pub fn mk_lang_item(self, ty: Ty<'tcx>, item: LangItem) -> Option<Ty<'tcx>> {
-        let def_id = self.lang_items().require(item).ok()?;
+        let def_id = self.lang_items().get(item)?;
         Some(self.mk_generic_adt(def_id, ty))
     }
 
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 52f16ad88f6..4e6cdb78602 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -872,9 +872,9 @@ fn foo(&self) -> Self::T { String::new() }
                             // FIXME: account for returning some type in a trait fn impl that has
                             // an assoc type as a return type (#72076).
                             if let hir::Defaultness::Default { has_value: true } =
-                                self.impl_defaultness(item.id.def_id)
+                                self.impl_defaultness(item.id.owner_id)
                             {
-                                if self.type_of(item.id.def_id) == found {
+                                if self.type_of(item.id.owner_id) == found {
                                     diag.span_label(
                                         item.span,
                                         "associated type defaults can't be assumed inside the \
@@ -894,7 +894,7 @@ fn foo(&self) -> Self::T { String::new() }
             })) => {
                 for item in &items[..] {
                     if let hir::AssocItemKind::Type = item.kind {
-                        if self.type_of(item.id.def_id) == found {
+                        if self.type_of(item.id.owner_id) == found {
                             diag.span_label(item.span, "expected this associated type");
                             return true;
                         }
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 0a109fd8f44..3312f44c67b 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -830,7 +830,7 @@ where
                 } else {
                     match mt {
                         hir::Mutability::Not => {
-                            if ty.is_freeze(tcx.at(DUMMY_SP), cx.param_env()) {
+                            if ty.is_freeze(tcx, cx.param_env()) {
                                 PointerKind::Frozen
                             } else {
                                 PointerKind::SharedMutable
@@ -841,7 +841,7 @@ where
                             // noalias, as another pointer to the structure can be obtained, that
                             // is not based-on the original reference. We consider all !Unpin
                             // types to be potentially self-referential here.
-                            if ty.is_unpin(tcx.at(DUMMY_SP), cx.param_env()) {
+                            if ty.is_unpin(tcx, cx.param_env()) {
                                 PointerKind::UniqueBorrowed
                             } else {
                                 PointerKind::UniqueBorrowedPinned
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 9671d3a32f9..a42d0570613 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -17,7 +17,7 @@ pub use self::IntVarValue::*;
 pub use self::Variance::*;
 use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason};
 use crate::metadata::ModChild;
-use crate::middle::privacy::AccessLevels;
+use crate::middle::privacy::EffectiveVisibilities;
 use crate::mir::{Body, GeneratorLayout};
 use crate::traits::{self, Reveal};
 use crate::ty;
@@ -160,7 +160,7 @@ pub struct ResolverGlobalCtxt {
     pub expn_that_defined: FxHashMap<LocalDefId, ExpnId>,
     /// Reference span for definitions.
     pub source_span: IndexVec<LocalDefId, Span>,
-    pub access_levels: AccessLevels,
+    pub effective_visibilities: EffectiveVisibilities,
     pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
     pub maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
     pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
@@ -2604,7 +2604,9 @@ impl<'tcx> TyCtxt<'tcx> {
             && if self.features().collapse_debuginfo {
                 span.in_macro_expansion_with_collapse_debuginfo()
             } else {
-                span.from_expansion()
+                // Inlined spans should not be collapsed as that leads to all of the
+                // inlined code being attributed to the inline callsite.
+                span.from_expansion() && !span.is_inlined()
             }
     }
 
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index c1c2e162f28..f07c60af248 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -63,7 +63,6 @@ thread_local! {
     static NO_TRIMMED_PATH: Cell<bool> = const { Cell::new(false) };
     static NO_QUERIES: Cell<bool> = const { Cell::new(false) };
     static NO_VISIBLE_PATH: Cell<bool> = const { Cell::new(false) };
-    static NO_VERBOSE_CONSTANTS: Cell<bool> = const { Cell::new(false) };
 }
 
 macro_rules! define_helper {
@@ -118,9 +117,6 @@ define_helper!(
     /// Prevent selection of visible paths. `Display` impl of DefId will prefer
     /// visible (public) reexports of types as paths.
     fn with_no_visible_paths(NoVisibleGuard, NO_VISIBLE_PATH);
-    /// Prevent verbose printing of constants. Verbose printing of constants is
-    /// never desirable in some contexts like `std::any::type_name`.
-    fn with_no_verbose_constants(NoVerboseConstantsGuard, NO_VERBOSE_CONSTANTS);
 );
 
 /// The "region highlights" are used to control region printing during
@@ -600,7 +596,7 @@ pub trait PrettyPrinter<'tcx>:
             }
             ty::FnPtr(ref bare_fn) => p!(print(bare_fn)),
             ty::Infer(infer_ty) => {
-                let verbose = self.tcx().sess.verbose();
+                let verbose = self.should_print_verbose();
                 if let ty::TyVar(ty_vid) = infer_ty {
                     if let Some(name) = self.ty_infer_name(ty_vid) {
                         p!(write("{}", name))
@@ -642,7 +638,7 @@ pub trait PrettyPrinter<'tcx>:
                 p!(print_def_path(def_id, &[]));
             }
             ty::Projection(ref data) => {
-                if !(self.tcx().sess.verbose() || NO_QUERIES.with(|q| q.get()))
+                if !(self.should_print_verbose() || NO_QUERIES.with(|q| q.get()))
                     && self.tcx().def_kind(data.item_def_id) == DefKind::ImplTraitPlaceholder
                 {
                     return self.pretty_print_opaque_impl_type(data.item_def_id, data.substs);
@@ -658,7 +654,7 @@ pub trait PrettyPrinter<'tcx>:
                 // only affect certain debug messages (e.g. messages printed
                 // from `rustc_middle::ty` during the computation of `tcx.predicates_of`),
                 // and should have no effect on any compiler output.
-                if self.tcx().sess.verbose() || NO_QUERIES.with(|q| q.get()) {
+                if self.should_print_verbose() || NO_QUERIES.with(|q| q.get()) {
                     p!(write("Opaque({:?}, {:?})", def_id, substs));
                     return Ok(self);
                 }
@@ -689,7 +685,7 @@ pub trait PrettyPrinter<'tcx>:
                     hir::Movability::Static => p!("static "),
                 }
 
-                if !self.tcx().sess.verbose() {
+                if !self.should_print_verbose() {
                     p!("generator");
                     // FIXME(eddyb) should use `def_span`.
                     if let Some(did) = did.as_local() {
@@ -725,7 +721,7 @@ pub trait PrettyPrinter<'tcx>:
             }
             ty::Closure(did, substs) => {
                 p!(write("["));
-                if !self.tcx().sess.verbose() {
+                if !self.should_print_verbose() {
                     p!(write("closure"));
                     // FIXME(eddyb) should use `def_span`.
                     if let Some(did) = did.as_local() {
@@ -763,7 +759,7 @@ pub trait PrettyPrinter<'tcx>:
             }
             ty::Array(ty, sz) => {
                 p!("[", print(ty), "; ");
-                if !NO_VERBOSE_CONSTANTS.with(|flag| flag.get()) && self.tcx().sess.verbose() {
+                if self.should_print_verbose() {
                     p!(write("{:?}", sz));
                 } else if let ty::ConstKind::Unevaluated(..) = sz.kind() {
                     // Do not try to evaluate unevaluated constants. If we are const evaluating an
@@ -1077,7 +1073,7 @@ pub trait PrettyPrinter<'tcx>:
 
                 // Special-case `Fn(...) -> ...` and re-sugar it.
                 let fn_trait_kind = cx.tcx().fn_trait_kind_from_lang_item(principal.def_id);
-                if !cx.tcx().sess.verbose() && fn_trait_kind.is_some() {
+                if !cx.should_print_verbose() && fn_trait_kind.is_some() {
                     if let ty::Tuple(tys) = principal.substs.type_at(0).kind() {
                         let mut projections = predicates.projection_bounds();
                         if let (Some(proj), None) = (projections.next(), projections.next()) {
@@ -1185,7 +1181,7 @@ pub trait PrettyPrinter<'tcx>:
     ) -> Result<Self::Const, Self::Error> {
         define_scoped_cx!(self);
 
-        if !NO_VERBOSE_CONSTANTS.with(|flag| flag.get()) && self.tcx().sess.verbose() {
+        if self.should_print_verbose() {
             p!(write("Const({:?}: {:?})", ct.kind(), ct.ty()));
             return Ok(self);
         }
@@ -1420,7 +1416,7 @@ pub trait PrettyPrinter<'tcx>:
     ) -> Result<Self::Const, Self::Error> {
         define_scoped_cx!(self);
 
-        if !NO_VERBOSE_CONSTANTS.with(|flag| flag.get()) && self.tcx().sess.verbose() {
+        if self.should_print_verbose() {
             p!(write("ValTree({:?}: ", valtree), print(ty), ")");
             return Ok(self);
         }
@@ -1564,6 +1560,10 @@ pub trait PrettyPrinter<'tcx>:
             Ok(cx)
         })
     }
+
+    fn should_print_verbose(&self) -> bool {
+        self.tcx().sess.verbose()
+    }
 }
 
 // HACK(eddyb) boxed to avoid moving around a large struct by-value.
@@ -1839,7 +1839,7 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
             }
         }
 
-        let verbose = self.tcx.sess.verbose();
+        let verbose = self.should_print_verbose();
         disambiguated_data.fmt_maybe_verbose(&mut self, verbose)?;
 
         self.empty_path = false;
@@ -1940,7 +1940,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
             return true;
         }
 
-        if self.tcx.sess.verbose() {
+        if self.should_print_verbose() {
             return true;
         }
 
@@ -2012,7 +2012,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
             return Ok(self);
         }
 
-        if self.tcx.sess.verbose() {
+        if self.should_print_verbose() {
             p!(write("{:?}", region));
             return Ok(self);
         }
@@ -2218,7 +2218,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
         // aren't named. Eventually, we might just want this as the default, but
         // this is not *quite* right and changes the ordering of some output
         // anyways.
-        let (new_value, map) = if self.tcx().sess.verbose() {
+        let (new_value, map) = if self.should_print_verbose() {
             let regions: Vec<_> = value
                 .bound_vars()
                 .into_iter()
@@ -2740,7 +2740,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N
     // Iterate all local crate items no matter where they are defined.
     let hir = tcx.hir();
     for id in hir.items() {
-        if matches!(tcx.def_kind(id.def_id), DefKind::Use) {
+        if matches!(tcx.def_kind(id.owner_id), DefKind::Use) {
             continue;
         }
 
@@ -2749,7 +2749,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N
             continue;
         }
 
-        let def_id = item.def_id.to_def_id();
+        let def_id = item.owner_id.to_def_id();
         let ns = tcx.def_kind(def_id).ns().unwrap_or(Namespace::TypeNS);
         collect_fn(&item.ident, ns, def_id);
     }
diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs
index 9c97ce34f29..ec90590ada2 100644
--- a/compiler/rustc_middle/src/ty/query.rs
+++ b/compiler/rustc_middle/src/ty/query.rs
@@ -5,7 +5,7 @@ use crate::metadata::ModChild;
 use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
 use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
 use crate::middle::lib_features::LibFeatures;
-use crate::middle::privacy::AccessLevels;
+use crate::middle::privacy::EffectiveVisibilities;
 use crate::middle::resolve_lifetime::{ObjectLifetimeDefault, Region, ResolveLifetimes};
 use crate::middle::stability::{self, DeprecationEntry};
 use crate::mir;
@@ -40,6 +40,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_data_structures::steal::Steal;
 use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::Lrc;
+use rustc_data_structures::unord::UnordSet;
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index f73d062ba30..f72e236eda1 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -2,7 +2,6 @@
 
 use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use crate::ty::layout::IntegerExt;
-use crate::ty::query::TyCtxtAt;
 use crate::ty::{
     self, DefIdTree, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
     TypeVisitable,
@@ -821,12 +820,8 @@ impl<'tcx> Ty<'tcx> {
     /// does copies even when the type actually doesn't satisfy the
     /// full requirements for the `Copy` trait (cc #29149) -- this
     /// winds up being reported as an error during NLL borrow check.
-    pub fn is_copy_modulo_regions(
-        self,
-        tcx_at: TyCtxtAt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-    ) -> bool {
-        self.is_trivially_pure_clone_copy() || tcx_at.is_copy_raw(param_env.and(self))
+    pub fn is_copy_modulo_regions(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
+        self.is_trivially_pure_clone_copy() || tcx.is_copy_raw(param_env.and(self))
     }
 
     /// Checks whether values of this type `T` have a size known at
@@ -835,8 +830,8 @@ impl<'tcx> Ty<'tcx> {
     /// over-approximation in generic contexts, where one can have
     /// strange rules like `<T as Foo<'static>>::Bar: Sized` that
     /// actually carry lifetime requirements.
-    pub fn is_sized(self, tcx_at: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
-        self.is_trivially_sized(tcx_at.tcx) || tcx_at.is_sized_raw(param_env.and(self))
+    pub fn is_sized(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
+        self.is_trivially_sized(tcx) || tcx.is_sized_raw(param_env.and(self))
     }
 
     /// Checks whether values of this type `T` implement the `Freeze`
@@ -846,8 +841,8 @@ impl<'tcx> Ty<'tcx> {
     /// optimization as well as the rules around static values. Note
     /// that the `Freeze` trait is not exposed to end users and is
     /// effectively an implementation detail.
-    pub fn is_freeze(self, tcx_at: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
-        self.is_trivially_freeze() || tcx_at.is_freeze_raw(param_env.and(self))
+    pub fn is_freeze(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
+        self.is_trivially_freeze() || tcx.is_freeze_raw(param_env.and(self))
     }
 
     /// Fast path helper for testing if a type is `Freeze`.
@@ -886,8 +881,8 @@ impl<'tcx> Ty<'tcx> {
     }
 
     /// Checks whether values of this type `T` implement the `Unpin` trait.
-    pub fn is_unpin(self, tcx_at: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
-        self.is_trivially_unpin() || tcx_at.is_unpin_raw(param_env.and(self))
+    pub fn is_unpin(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
+        self.is_trivially_unpin() || tcx.is_unpin_raw(param_env.and(self))
     }
 
     /// Fast path helper for testing if a type is `Unpin`.
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 e707c373f0d..c8610af7038 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_operand.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs
@@ -153,12 +153,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
         if tcx.features().unsized_fn_params {
             let ty = expr.ty;
-            let span = expr.span;
             let param_env = this.param_env;
 
-            if !ty.is_sized(tcx.at(span), param_env) {
+            if !ty.is_sized(tcx, param_env) {
                 // !sized means !copy, so this is an unsized move
-                assert!(!ty.is_copy_modulo_regions(tcx.at(span), param_env));
+                assert!(!ty.is_copy_modulo_regions(tcx, param_env));
 
                 // As described above, detect the case where we are passing a value of unsized
                 // type, and that value is coming from the deref of a box.
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 5e8ce65daf0..fb1ea9ed300 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -260,7 +260,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                     };
                     match borrow_kind {
                         BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique => {
-                            if !ty.is_freeze(self.tcx.at(pat.span), self.param_env) {
+                            if !ty.is_freeze(self.tcx, self.param_env) {
                                 self.requires_unsafe(pat.span, BorrowOfLayoutConstrainedField);
                             }
                         }
@@ -457,9 +457,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                 if visitor.found {
                     match borrow_kind {
                         BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique
-                            if !self.thir[arg]
-                                .ty
-                                .is_freeze(self.tcx.at(self.thir[arg].span), self.param_env) =>
+                            if !self.thir[arg].ty.is_freeze(self.tcx, self.param_env) =>
                         {
                             self.requires_unsafe(expr.span, BorrowOfLayoutConstrainedField)
                         }
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index 5984c800d83..93a3dd8962a 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -79,7 +79,10 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, '_, 'tcx> {
         intravisit::walk_local(self, loc);
         let els = loc.els;
         if let Some(init) = loc.init && els.is_some() {
-            self.check_let(&loc.pat, init, loc.span);
+            // Build a span without the else { ... } as we don't want to underline
+            // the entire else block in the IDE setting.
+            let span = loc.span.with_hi(init.span.hi());
+            self.check_let(&loc.pat, init, span);
         }
 
         let (msg, sp) = match loc.source {
@@ -507,7 +510,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
                                 _ => "aren't",
                             },
                         ),
-                        " else { todo!() }".to_string(),
+                        " else { todo!() }",
                         Applicability::HasPlaceholders,
                     );
                 }
@@ -630,11 +633,6 @@ fn irrefutable_let_patterns(
     count: usize,
     span: Span,
 ) {
-    let span = match source {
-        LetSource::LetElse(span) => span,
-        _ => span,
-    };
-
     macro_rules! emit_diag {
         (
             $lint:expr,
@@ -680,7 +678,7 @@ fn irrefutable_let_patterns(
                 "removing the guard and adding a `let` inside the match arm"
             );
         }
-        LetSource::LetElse(..) => {
+        LetSource::LetElse => {
             emit_diag!(
                 lint,
                 "`let...else`",
@@ -1004,8 +1002,8 @@ fn maybe_point_at_variant<'a, 'p: 'a, 'tcx: 'a>(
 }
 
 /// Check if a by-value binding is by-value. That is, check if the binding's type is not `Copy`.
-fn is_binding_by_move(cx: &MatchVisitor<'_, '_, '_>, hir_id: HirId, span: Span) -> bool {
-    !cx.typeck_results.node_type(hir_id).is_copy_modulo_regions(cx.tcx.at(span), cx.param_env)
+fn is_binding_by_move(cx: &MatchVisitor<'_, '_, '_>, hir_id: HirId) -> bool {
+    !cx.typeck_results.node_type(hir_id).is_copy_modulo_regions(cx.tcx, cx.param_env)
 }
 
 /// Check that there are no borrow or move conflicts in `binding @ subpat` patterns.
@@ -1031,7 +1029,7 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
 
     // Get the binding move, extract the mutability if by-ref.
     let mut_outer = match typeck_results.extract_binding_mode(sess, pat.hir_id, pat.span) {
-        Some(ty::BindByValue(_)) if is_binding_by_move(cx, pat.hir_id, pat.span) => {
+        Some(ty::BindByValue(_)) if is_binding_by_move(cx, pat.hir_id) => {
             // We have `x @ pat` where `x` is by-move. Reject all borrows in `pat`.
             let mut conflicts_ref = Vec::new();
             sub.each_binding(|_, hir_id, span, _| {
@@ -1070,7 +1068,7 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
                 (Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push((span, name)), // 2x `ref mut`.
                 _ => conflicts_mut_ref.push((span, name)), // `ref` + `ref mut` in either direction.
             },
-            Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id, span) => {
+            Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id) => {
                 conflicts_move.push((span, name)) // `ref mut?` + by-move conflict.
             }
             Some(ty::BindByValue(_)) | None => {} // `ref mut?` + by-copy is fine.
@@ -1127,7 +1125,7 @@ pub enum LetSource {
     GenericLet,
     IfLet,
     IfLetGuard,
-    LetElse(Span),
+    LetElse,
     WhileLet,
 }
 
@@ -1156,8 +1154,8 @@ fn let_source_parent(tcx: TyCtxt<'_>, parent: HirId, pat_id: Option<HirId>) -> L
     let parent_parent = hir.get_parent_node(parent);
     let parent_parent_node = hir.get(parent_parent);
     match parent_parent_node {
-        hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(_), span, .. }) => {
-            return LetSource::LetElse(*span);
+        hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(_), .. }) => {
+            return LetSource::LetElse;
         }
         hir::Node::Arm(hir::Arm { guard: Some(hir::Guard::If(_)), .. }) => {
             return LetSource::IfLetGuard;
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index cf8ae776be9..ad12e011621 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -506,7 +506,7 @@ impl<'tcx> ConstToPat<'tcx> {
                 // convert the dereferenced constant to a pattern that is the sub-pattern of the
                 // deref pattern.
                 _ => {
-                    if !pointee_ty.is_sized(tcx.at(span), param_env) {
+                    if !pointee_ty.is_sized(tcx, param_env) {
                         // `tcx.deref_mir_constant()` below will ICE with an unsized type
                         // (except slices, which are handled in a separate arm above).
                         let msg = format!("cannot use unsized non-slice type `{}` in constant patterns", pointee_ty);
@@ -534,7 +534,7 @@ impl<'tcx> ConstToPat<'tcx> {
             ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::FnDef(..) => {
                 PatKind::Constant { value: cv }
             }
-            ty::RawPtr(pointee) if pointee.ty.is_sized(tcx.at(span), param_env) => {
+            ty::RawPtr(pointee) if pointee.ty.is_sized(tcx, param_env) => {
                 PatKind::Constant { value: cv }
             }
             // FIXME: these can have very surprising behaviour where optimization levels or other
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs
index 4730be1244b..f8f04214a2c 100644
--- a/compiler/rustc_mir_transform/src/check_unsafety.rs
+++ b/compiler/rustc_mir_transform/src/check_unsafety.rs
@@ -312,7 +312,7 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> {
                             } else if !place
                                 .ty(self.body, self.tcx)
                                 .ty
-                                .is_freeze(self.tcx.at(self.source_info.span), self.param_env)
+                                .is_freeze(self.tcx, self.param_env)
                             {
                                 UnsafetyViolationDetails::BorrowOfLayoutConstrainedField
                             } else {
diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs
index 4a9bd9df327..4e451588845 100644
--- a/compiler/rustc_mir_transform/src/const_prop.rs
+++ b/compiler/rustc_mir_transform/src/const_prop.rs
@@ -633,7 +633,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         }
         if !rvalue
             .ty(&self.ecx.frame().body.local_decls, *self.ecx.tcx)
-            .is_sized(self.ecx.tcx, self.param_env)
+            .is_sized(*self.ecx.tcx, self.param_env)
         {
             // the interpreter doesn't support unsized locals (only unsized arguments),
             // but rustc does (in a kinda broken way), so we have to skip them here
diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs
index 6bddbdb8e6a..479c4e577d4 100644
--- a/compiler/rustc_mir_transform/src/const_prop_lint.rs
+++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs
@@ -500,7 +500,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         }
         if !rvalue
             .ty(&self.ecx.frame().body.local_decls, *self.ecx.tcx)
-            .is_sized(self.ecx.tcx, self.param_env)
+            .is_sized(*self.ecx.tcx, self.param_env)
         {
             // the interpreter doesn't support unsized locals (only unsized arguments),
             // but rustc does (in a kinda broken way), so we have to skip them here
diff --git a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
index 18352fbf675..28b1c5a4809 100644
--- a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
+++ b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
@@ -11,7 +11,6 @@ use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::{Body, Local, Location, Operand, Terminator, TerminatorKind, RETURN_PLACE};
 use rustc_middle::ty::{self, DeducedParamAttrs, ParamEnv, Ty, TyCtxt};
 use rustc_session::config::OptLevel;
-use rustc_span::DUMMY_SP;
 
 /// A visitor that determines which arguments have been mutated. We can't use the mutability field
 /// on LocalDecl for this because it has no meaning post-optimization.
@@ -232,7 +231,7 @@ pub fn deduced_param_attrs<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx [Ded
         body.local_decls.iter().skip(1).take(body.arg_count).enumerate().map(
             |(arg_index, local_decl)| DeducedParamAttrs {
                 read_only: !deduce_read_only.mutable_args.contains(arg_index)
-                    && local_decl.ty.is_freeze(tcx.at(DUMMY_SP), ParamEnv::reveal_all()),
+                    && local_decl.ty.is_freeze(tcx, ParamEnv::reveal_all()),
             },
         ),
     );
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 5be2232547b..4791be1306c 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -288,7 +288,7 @@ fn mir_const<'tcx>(
 
     let mut body = tcx.mir_built(def).steal();
 
-    rustc_middle::mir::dump_mir(tcx, None, "mir_map", &0, &body, |_, _| Ok(()));
+    pass_manager::dump_mir_for_phase_change(tcx, &body);
 
     pm::run_passes(
         tcx,
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index c19380ef89c..bf590674144 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -312,7 +312,7 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -
     let param_env = tcx.param_env(def_id);
 
     let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty);
-    let is_copy = self_ty.is_copy_modulo_regions(tcx.at(builder.span), param_env);
+    let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env);
 
     let dest = Place::return_place();
     let src = tcx.mk_place_deref(Place::from(Local::new(1 + 0)));
@@ -845,7 +845,7 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> {
         span,
     );
 
-    rustc_middle::mir::dump_mir(tcx, None, "mir_map", &0, &body, |_, _| Ok(()));
+    crate::pass_manager::dump_mir_for_phase_change(tcx, &body);
 
     body
 }
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 5cd7a7f760f..3cfddd75462 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -201,7 +201,7 @@ use std::iter;
 use std::ops::Range;
 use std::path::PathBuf;
 
-use crate::errors::{LargeAssignmentsLint, RecursionLimit, RequiresLangItem, TypeLengthLimit};
+use crate::errors::{LargeAssignmentsLint, RecursionLimit, TypeLengthLimit};
 
 #[derive(PartialEq)]
 pub enum MonoItemCollectionMode {
@@ -1067,7 +1067,7 @@ fn find_vtable_types_for_unsizing<'tcx>(
     let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| {
         let param_env = ty::ParamEnv::reveal_all();
         let type_has_metadata = |ty: Ty<'tcx>| -> bool {
-            if ty.is_sized(tcx.at(DUMMY_SP), param_env) {
+            if ty.is_sized(tcx, param_env) {
                 return false;
             }
             let tail = tcx.struct_tail_erasing_lifetimes(ty, param_env);
@@ -1192,7 +1192,7 @@ struct RootCollector<'a, 'tcx> {
 
 impl<'v> RootCollector<'_, 'v> {
     fn process_item(&mut self, id: hir::ItemId) {
-        match self.tcx.def_kind(id.def_id) {
+        match self.tcx.def_kind(id.owner_id) {
             DefKind::Enum | DefKind::Struct | DefKind::Union => {
                 let item = self.tcx.hir().item(id);
                 match item.kind {
@@ -1203,12 +1203,14 @@ impl<'v> RootCollector<'_, 'v> {
                             if self.mode == MonoItemCollectionMode::Eager {
                                 debug!(
                                     "RootCollector: ADT drop-glue for {}",
-                                    self.tcx.def_path_str(item.def_id.to_def_id())
+                                    self.tcx.def_path_str(item.owner_id.to_def_id())
                                 );
 
-                                let ty =
-                                    Instance::new(item.def_id.to_def_id(), InternalSubsts::empty())
-                                        .ty(self.tcx, ty::ParamEnv::reveal_all());
+                                let ty = Instance::new(
+                                    item.owner_id.to_def_id(),
+                                    InternalSubsts::empty(),
+                                )
+                                .ty(self.tcx, ty::ParamEnv::reveal_all());
                                 visit_drop_use(self.tcx, ty, true, DUMMY_SP, self.output);
                             }
                         }
@@ -1219,23 +1221,23 @@ impl<'v> RootCollector<'_, 'v> {
             DefKind::GlobalAsm => {
                 debug!(
                     "RootCollector: ItemKind::GlobalAsm({})",
-                    self.tcx.def_path_str(id.def_id.to_def_id())
+                    self.tcx.def_path_str(id.owner_id.to_def_id())
                 );
                 self.output.push(dummy_spanned(MonoItem::GlobalAsm(id)));
             }
             DefKind::Static(..) => {
                 debug!(
                     "RootCollector: ItemKind::Static({})",
-                    self.tcx.def_path_str(id.def_id.to_def_id())
+                    self.tcx.def_path_str(id.owner_id.to_def_id())
                 );
-                self.output.push(dummy_spanned(MonoItem::Static(id.def_id.to_def_id())));
+                self.output.push(dummy_spanned(MonoItem::Static(id.owner_id.to_def_id())));
             }
             DefKind::Const => {
                 // const items only generate mono items if they are
                 // actually used somewhere. Just declaring them is insufficient.
 
                 // but even just declaring them must collect the items they refer to
-                if let Ok(val) = self.tcx.const_eval_poly(id.def_id.to_def_id()) {
+                if let Ok(val) = self.tcx.const_eval_poly(id.owner_id.to_def_id()) {
                     collect_const_value(self.tcx, val, &mut self.output);
                 }
             }
@@ -1246,15 +1248,15 @@ impl<'v> RootCollector<'_, 'v> {
                 }
             }
             DefKind::Fn => {
-                self.push_if_root(id.def_id.def_id);
+                self.push_if_root(id.owner_id.def_id);
             }
             _ => {}
         }
     }
 
     fn process_impl_item(&mut self, id: hir::ImplItemId) {
-        if matches!(self.tcx.def_kind(id.def_id), DefKind::AssocFn) {
-            self.push_if_root(id.def_id.def_id);
+        if matches!(self.tcx.def_kind(id.owner_id), DefKind::AssocFn) {
+            self.push_if_root(id.owner_id.def_id);
         }
     }
 
@@ -1296,14 +1298,7 @@ impl<'v> RootCollector<'_, 'v> {
             return;
         };
 
-        let start_def_id = match self.tcx.lang_items().require(LangItem::Start) {
-            Ok(s) => s,
-            Err(lang_item_err) => {
-                self.tcx
-                    .sess
-                    .emit_fatal(RequiresLangItem { lang_item: lang_item_err.0.name().to_string() });
-            }
-        };
+        let start_def_id = self.tcx.require_lang_item(LangItem::Start, None);
         let main_ret_ty = self.tcx.fn_sig(main_def_id).output();
 
         // Given that `main()` has no arguments,
@@ -1352,13 +1347,13 @@ fn create_mono_items_for_default_impls<'tcx>(
 
             debug!(
                 "create_mono_items_for_default_impls(item={})",
-                tcx.def_path_str(item.def_id.to_def_id())
+                tcx.def_path_str(item.owner_id.to_def_id())
             );
 
-            if let Some(trait_ref) = tcx.impl_trait_ref(item.def_id) {
+            if let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id) {
                 let param_env = ty::ParamEnv::reveal_all();
                 let trait_ref = tcx.normalize_erasing_regions(param_env, trait_ref);
-                let overridden_methods = tcx.impl_item_implementor_ids(item.def_id);
+                let overridden_methods = tcx.impl_item_implementor_ids(item.owner_id);
                 for method in tcx.provided_trait_methods(trait_ref.def_id) {
                     if overridden_methods.contains_key(&method.def_id) {
                         continue;
diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs
index ce097b8d846..870d50728bd 100644
--- a/compiler/rustc_monomorphize/src/errors.rs
+++ b/compiler/rustc_monomorphize/src/errors.rs
@@ -32,12 +32,6 @@ pub struct TypeLengthLimit {
     pub type_length: usize,
 }
 
-#[derive(Diagnostic)]
-#[diag(monomorphize_requires_lang_item)]
-pub struct RequiresLangItem {
-    pub lang_item: String,
-}
-
 pub struct UnusedGenericParams {
     pub span: Span,
     pub param_spans: Vec<Span>,
diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs
index 15276569c32..29009c48050 100644
--- a/compiler/rustc_monomorphize/src/partitioning/default.rs
+++ b/compiler/rustc_monomorphize/src/partitioning/default.rs
@@ -319,7 +319,7 @@ fn characteristic_def_id_of_mono_item<'tcx>(
             Some(def_id)
         }
         MonoItem::Static(def_id) => Some(def_id),
-        MonoItem::GlobalAsm(item_id) => Some(item_id.def_id.to_def_id()),
+        MonoItem::GlobalAsm(item_id) => Some(item_id.owner_id.to_def_id()),
     }
 }
 
@@ -411,9 +411,9 @@ fn mono_item_visibility<'tcx>(
             };
         }
         MonoItem::GlobalAsm(item_id) => {
-            return if tcx.is_reachable_non_generic(item_id.def_id) {
+            return if tcx.is_reachable_non_generic(item_id.owner_id) {
                 *can_be_internalized = false;
-                default_visibility(tcx, item_id.def_id.to_def_id(), false)
+                default_visibility(tcx, item_id.owner_id.to_def_id(), false)
             } else {
                 Visibility::Hidden
             };
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index b19e85427e7..27a57adf964 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -2062,7 +2062,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
         // so this lets us continue to run them while maintaining backwards compatibility.
         // In the long run, the checks should be harmonized.
         if let ItemKind::Macro(ref macro_def, _) = item.kind {
-            let def_id = item.def_id.to_def_id();
+            let def_id = item.owner_id.to_def_id();
             if macro_def.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) {
                 check_non_exported_macro_for_invalid_attrs(self.tcx, item);
             }
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 6a97ad3fe86..753d01f46ca 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -11,7 +11,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{Node, PatKind, TyKind};
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
-use rustc_middle::middle::privacy::AccessLevel;
+use rustc_middle::middle::privacy::Level;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, DefIdTree, TyCtxt};
 use rustc_session::lint;
@@ -280,8 +280,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
     }
 
     fn visit_node(&mut self, node: Node<'tcx>) {
-        if let Node::ImplItem(hir::ImplItem { def_id, .. }) = node
-            && self.should_ignore_item(def_id.to_def_id())
+        if let Node::ImplItem(hir::ImplItem { owner_id, .. }) = node
+            && self.should_ignore_item(owner_id.to_def_id())
         {
             return;
         }
@@ -293,7 +293,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
         match node {
             Node::Item(item) => match item.kind {
                 hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
-                    let def = self.tcx.adt_def(item.def_id);
+                    let def = self.tcx.adt_def(item.owner_id);
                     self.repr_has_repr_c = def.repr().c();
                     self.repr_has_repr_simd = def.repr().simd();
 
@@ -306,7 +306,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
                 intravisit::walk_trait_item(self, trait_item);
             }
             Node::ImplItem(impl_item) => {
-                let item = self.tcx.local_parent(impl_item.def_id.def_id);
+                let item = self.tcx.local_parent(impl_item.owner_id.def_id);
                 if self.tcx.impl_trait_ref(item).is_none() {
                     //// If it's a type whose items are live, then it's live, too.
                     //// This is done to handle the case where, for example, the static
@@ -517,10 +517,10 @@ fn check_item<'tcx>(
 ) {
     let allow_dead_code = has_allow_dead_code_or_lang_attr(tcx, id.hir_id());
     if allow_dead_code {
-        worklist.push(id.def_id.def_id);
+        worklist.push(id.owner_id.def_id);
     }
 
-    match tcx.def_kind(id.def_id) {
+    match tcx.def_kind(id.owner_id) {
         DefKind::Enum => {
             let item = tcx.hir().item(id);
             if let hir::ItemKind::Enum(ref enum_def, _) = item.kind {
@@ -540,15 +540,15 @@ fn check_item<'tcx>(
             }
         }
         DefKind::Impl => {
-            let of_trait = tcx.impl_trait_ref(id.def_id);
+            let of_trait = tcx.impl_trait_ref(id.owner_id);
 
             if of_trait.is_some() {
-                worklist.push(id.def_id.def_id);
+                worklist.push(id.owner_id.def_id);
             }
 
             // get DefIds from another query
             let local_def_ids = tcx
-                .associated_item_def_ids(id.def_id)
+                .associated_item_def_ids(id.owner_id)
                 .iter()
                 .filter_map(|def_id| def_id.as_local());
 
@@ -566,12 +566,12 @@ fn check_item<'tcx>(
             if let hir::ItemKind::Struct(ref variant_data, _) = item.kind
                 && let Some(ctor_hir_id) = variant_data.ctor_hir_id()
             {
-                struct_constructors.insert(tcx.hir().local_def_id(ctor_hir_id), item.def_id.def_id);
+                struct_constructors.insert(tcx.hir().local_def_id(ctor_hir_id), item.owner_id.def_id);
             }
         }
         DefKind::GlobalAsm => {
             // global_asm! is always live.
-            worklist.push(id.def_id.def_id);
+            worklist.push(id.owner_id.def_id);
         }
         _ => {}
     }
@@ -579,12 +579,12 @@ fn check_item<'tcx>(
 
 fn check_trait_item<'tcx>(tcx: TyCtxt<'tcx>, worklist: &mut Vec<LocalDefId>, id: hir::TraitItemId) {
     use hir::TraitItemKind::{Const, Fn};
-    if matches!(tcx.def_kind(id.def_id), DefKind::AssocConst | DefKind::AssocFn) {
+    if matches!(tcx.def_kind(id.owner_id), DefKind::AssocConst | DefKind::AssocFn) {
         let trait_item = tcx.hir().trait_item(id);
         if matches!(trait_item.kind, Const(_, Some(_)) | Fn(_, hir::TraitFn::Provided(_)))
             && has_allow_dead_code_or_lang_attr(tcx, trait_item.hir_id())
         {
-            worklist.push(trait_item.def_id.def_id);
+            worklist.push(trait_item.owner_id.def_id);
         }
     }
 }
@@ -594,23 +594,23 @@ fn check_foreign_item<'tcx>(
     worklist: &mut Vec<LocalDefId>,
     id: hir::ForeignItemId,
 ) {
-    if matches!(tcx.def_kind(id.def_id), DefKind::Static(_) | DefKind::Fn)
+    if matches!(tcx.def_kind(id.owner_id), DefKind::Static(_) | DefKind::Fn)
         && has_allow_dead_code_or_lang_attr(tcx, id.hir_id())
     {
-        worklist.push(id.def_id.def_id);
+        worklist.push(id.owner_id.def_id);
     }
 }
 
 fn create_and_seed_worklist<'tcx>(
     tcx: TyCtxt<'tcx>,
 ) -> (Vec<LocalDefId>, FxHashMap<LocalDefId, LocalDefId>) {
-    let access_levels = &tcx.privacy_access_levels(());
+    let effective_visibilities = &tcx.effective_visibilities(());
     // see `MarkSymbolVisitor::struct_constructors`
     let mut struct_constructors = Default::default();
-    let mut worklist = access_levels
+    let mut worklist = effective_visibilities
         .iter()
         .filter_map(|(&id, effective_vis)| {
-            effective_vis.is_public_at_level(AccessLevel::Reachable).then_some(id)
+            effective_vis.is_public_at_level(Level::Reachable).then_some(id)
         })
         // Seed entry point
         .chain(tcx.entry_fn(()).and_then(|(def_id, _)| def_id.as_local()))
@@ -861,19 +861,19 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) {
     let module_items = tcx.hir_module_items(module);
 
     for item in module_items.items() {
-        if !live_symbols.contains(&item.def_id.def_id) {
-            let parent = tcx.local_parent(item.def_id.def_id);
+        if !live_symbols.contains(&item.owner_id.def_id) {
+            let parent = tcx.local_parent(item.owner_id.def_id);
             if parent != module && !live_symbols.contains(&parent) {
                 // We already have diagnosed something.
                 continue;
             }
-            visitor.check_definition(item.def_id.def_id);
+            visitor.check_definition(item.owner_id.def_id);
             continue;
         }
 
-        let def_kind = tcx.def_kind(item.def_id);
+        let def_kind = tcx.def_kind(item.owner_id);
         if let DefKind::Struct | DefKind::Union | DefKind::Enum = def_kind {
-            let adt = tcx.adt_def(item.def_id);
+            let adt = tcx.adt_def(item.owner_id);
             let mut dead_variants = Vec::new();
 
             for variant in adt.variants() {
@@ -917,7 +917,7 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) {
             }
 
             visitor.warn_dead_fields_and_variants(
-                item.def_id.def_id,
+                item.owner_id.def_id,
                 "constructed",
                 dead_variants,
                 false,
@@ -926,11 +926,11 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) {
     }
 
     for impl_item in module_items.impl_items() {
-        visitor.check_definition(impl_item.def_id.def_id);
+        visitor.check_definition(impl_item.owner_id.def_id);
     }
 
     for foreign_item in module_items.foreign_items() {
-        visitor.check_definition(foreign_item.def_id.def_id);
+        visitor.check_definition(foreign_item.owner_id.def_id);
     }
 
     // We do not warn trait items.
diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs
index 3f991cf6572..a72056e00b1 100644
--- a/compiler/rustc_passes/src/diagnostic_items.rs
+++ b/compiler/rustc_passes/src/diagnostic_items.rs
@@ -73,19 +73,19 @@ fn diagnostic_items<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> DiagnosticItems
     let crate_items = tcx.hir_crate_items(());
 
     for id in crate_items.items() {
-        observe_item(tcx, &mut diagnostic_items, id.def_id.def_id);
+        observe_item(tcx, &mut diagnostic_items, id.owner_id.def_id);
     }
 
     for id in crate_items.trait_items() {
-        observe_item(tcx, &mut diagnostic_items, id.def_id.def_id);
+        observe_item(tcx, &mut diagnostic_items, id.owner_id.def_id);
     }
 
     for id in crate_items.impl_items() {
-        observe_item(tcx, &mut diagnostic_items, id.def_id.def_id);
+        observe_item(tcx, &mut diagnostic_items, id.owner_id.def_id);
     }
 
     for id in crate_items.foreign_items() {
-        observe_item(tcx, &mut diagnostic_items, id.def_id.def_id);
+        observe_item(tcx, &mut diagnostic_items, id.owner_id.def_id);
     }
 
     diagnostic_items
diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs
index 38a259ca884..5885f45ae45 100644
--- a/compiler/rustc_passes/src/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
@@ -62,7 +62,7 @@ fn entry_point_type(ctxt: &EntryContext<'_>, id: ItemId, at_root: bool) -> Entry
     } else if ctxt.tcx.sess.contains_name(attrs, sym::rustc_main) {
         EntryPointType::RustcMainAttr
     } else {
-        if let Some(name) = ctxt.tcx.opt_item_name(id.def_id.to_def_id())
+        if let Some(name) = ctxt.tcx.opt_item_name(id.owner_id.to_def_id())
             && name == sym::main {
             if at_root {
                 // This is a top-level function so can be `main`.
@@ -82,7 +82,7 @@ fn attr_span_by_symbol(ctxt: &EntryContext<'_>, id: ItemId, sym: Symbol) -> Opti
 }
 
 fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
-    let at_root = ctxt.tcx.opt_local_parent(id.def_id.def_id) == Some(CRATE_DEF_ID);
+    let at_root = ctxt.tcx.opt_local_parent(id.owner_id.def_id) == Some(CRATE_DEF_ID);
 
     match entry_point_type(ctxt, id, at_root) {
         EntryPointType::None => {
@@ -90,7 +90,7 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
                 ctxt.tcx.sess.emit_err(AttrOnlyOnMain { span, attr: sym::unix_sigpipe });
             }
         }
-        _ if !matches!(ctxt.tcx.def_kind(id.def_id), DefKind::Fn) => {
+        _ if !matches!(ctxt.tcx.def_kind(id.owner_id), DefKind::Fn) => {
             for attr in [sym::start, sym::rustc_main] {
                 if let Some(span) = attr_span_by_symbol(ctxt, id, attr) {
                     ctxt.tcx.sess.emit_err(AttrOnlyInFunctions { span, attr });
@@ -102,16 +102,16 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
             if let Some(span) = attr_span_by_symbol(ctxt, id, sym::unix_sigpipe) {
                 ctxt.tcx.sess.emit_err(AttrOnlyOnRootMain { span, attr: sym::unix_sigpipe });
             }
-            ctxt.non_main_fns.push(ctxt.tcx.def_span(id.def_id));
+            ctxt.non_main_fns.push(ctxt.tcx.def_span(id.owner_id));
         }
         EntryPointType::RustcMainAttr => {
             if ctxt.attr_main_fn.is_none() {
-                ctxt.attr_main_fn = Some((id.def_id.def_id, ctxt.tcx.def_span(id.def_id)));
+                ctxt.attr_main_fn = Some((id.owner_id.def_id, ctxt.tcx.def_span(id.owner_id)));
             } else {
                 ctxt.tcx.sess.emit_err(MultipleRustcMain {
-                    span: ctxt.tcx.def_span(id.def_id.to_def_id()),
+                    span: ctxt.tcx.def_span(id.owner_id.to_def_id()),
                     first: ctxt.attr_main_fn.unwrap().1,
-                    additional: ctxt.tcx.def_span(id.def_id.to_def_id()),
+                    additional: ctxt.tcx.def_span(id.owner_id.to_def_id()),
                 });
             }
         }
@@ -120,11 +120,11 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
                 ctxt.tcx.sess.emit_err(AttrOnlyOnMain { span, attr: sym::unix_sigpipe });
             }
             if ctxt.start_fn.is_none() {
-                ctxt.start_fn = Some((id.def_id.def_id, ctxt.tcx.def_span(id.def_id)));
+                ctxt.start_fn = Some((id.owner_id.def_id, ctxt.tcx.def_span(id.owner_id)));
             } else {
                 ctxt.tcx.sess.emit_err(MultipleStartFunctions {
-                    span: ctxt.tcx.def_span(id.def_id),
-                    labeled: ctxt.tcx.def_span(id.def_id.to_def_id()),
+                    span: ctxt.tcx.def_span(id.owner_id),
+                    labeled: ctxt.tcx.def_span(id.owner_id.to_def_id()),
                     previous: ctxt.start_fn.unwrap().1,
                 });
             }
diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs
index 3ee8c8bcb1d..88bb39debb1 100644
--- a/compiler/rustc_passes/src/hir_id_validator.rs
+++ b/compiler/rustc_passes/src/hir_id_validator.rs
@@ -126,7 +126,7 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> {
 
     fn visit_item(&mut self, i: &'hir hir::Item<'hir>) {
         let mut inner_visitor = self.new_visitor(self.hir_map);
-        inner_visitor.check(i.def_id, |this| intravisit::walk_item(this, i));
+        inner_visitor.check(i.owner_id, |this| intravisit::walk_item(this, i));
     }
 
     fn visit_id(&mut self, hir_id: HirId) {
@@ -148,16 +148,16 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> {
 
     fn visit_foreign_item(&mut self, i: &'hir hir::ForeignItem<'hir>) {
         let mut inner_visitor = self.new_visitor(self.hir_map);
-        inner_visitor.check(i.def_id, |this| intravisit::walk_foreign_item(this, i));
+        inner_visitor.check(i.owner_id, |this| intravisit::walk_foreign_item(this, i));
     }
 
     fn visit_trait_item(&mut self, i: &'hir hir::TraitItem<'hir>) {
         let mut inner_visitor = self.new_visitor(self.hir_map);
-        inner_visitor.check(i.def_id, |this| intravisit::walk_trait_item(this, i));
+        inner_visitor.check(i.owner_id, |this| intravisit::walk_trait_item(this, i));
     }
 
     fn visit_impl_item(&mut self, i: &'hir hir::ImplItem<'hir>) {
         let mut inner_visitor = self.new_visitor(self.hir_map);
-        inner_visitor.check(i.def_id, |this| intravisit::walk_impl_item(this, i));
+        inner_visitor.check(i.owner_id, |this| intravisit::walk_impl_item(this, i));
     }
 }
diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs
index 71b0735192a..188efc528ef 100644
--- a/compiler/rustc_passes/src/lang_items.rs
+++ b/compiler/rustc_passes/src/lang_items.rs
@@ -16,7 +16,7 @@ use crate::weak_lang_items;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
-use rustc_hir::lang_items::{extract, GenericRequirement, ITEM_REFS};
+use rustc_hir::lang_items::{extract, GenericRequirement};
 use rustc_hir::{HirId, LangItem, LanguageItems, Target};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::cstore::ExternCrate;
@@ -43,17 +43,17 @@ impl<'tcx> LanguageItemCollector<'tcx> {
     fn check_for_lang(&mut self, actual_target: Target, hir_id: HirId) {
         let attrs = self.tcx.hir().attrs(hir_id);
         if let Some((name, span)) = extract(&attrs) {
-            match ITEM_REFS.get(&name).cloned() {
+            match LangItem::from_name(name) {
                 // Known lang item with attribute on correct target.
-                Some((item_index, expected_target)) if actual_target == expected_target => {
-                    self.collect_item_extended(item_index, hir_id, span);
+                Some(lang_item) if actual_target == lang_item.target() => {
+                    self.collect_item_extended(lang_item, hir_id, span);
                 }
                 // Known lang item with attribute on incorrect target.
-                Some((_, expected_target)) => {
+                Some(lang_item) => {
                     self.tcx.sess.emit_err(LangItemOnIncorrectTarget {
                         span,
                         name,
-                        expected_target,
+                        expected_target: lang_item.target(),
                         actual_target,
                     });
                 }
@@ -65,12 +65,12 @@ impl<'tcx> LanguageItemCollector<'tcx> {
         }
     }
 
-    fn collect_item(&mut self, item_index: usize, item_def_id: DefId) {
+    fn collect_item(&mut self, lang_item: LangItem, item_def_id: DefId) {
         // Check for duplicates.
-        if let Some(original_def_id) = self.items.items[item_index] {
+        if let Some(original_def_id) = self.items.get(lang_item) {
             if original_def_id != item_def_id {
                 let local_span = self.tcx.hir().span_if_local(item_def_id);
-                let lang_item_name = LangItem::from_u32(item_index as u32).unwrap().name();
+                let lang_item_name = lang_item.name();
                 let crate_name = self.tcx.crate_name(item_def_id.krate);
                 let mut dependency_of = Empty;
                 let is_local = item_def_id.is_local();
@@ -139,17 +139,13 @@ impl<'tcx> LanguageItemCollector<'tcx> {
         }
 
         // Matched.
-        self.items.items[item_index] = Some(item_def_id);
-        if let Some(group) = LangItem::from_u32(item_index as u32).unwrap().group() {
-            self.items.groups[group as usize].push(item_def_id);
-        }
+        self.items.set(lang_item, item_def_id);
     }
 
     // Like collect_item() above, but also checks whether the lang item is declared
     // with the right number of generic arguments.
-    fn collect_item_extended(&mut self, item_index: usize, hir_id: HirId, span: Span) {
+    fn collect_item_extended(&mut self, lang_item: LangItem, hir_id: HirId, span: Span) {
         let item_def_id = self.tcx.hir().local_def_id(hir_id).to_def_id();
-        let lang_item = LangItem::from_u32(item_index as u32).unwrap();
         let name = lang_item.name();
 
         // Now check whether the lang_item has the expected number of generic
@@ -197,7 +193,7 @@ impl<'tcx> LanguageItemCollector<'tcx> {
             }
         }
 
-        self.collect_item(item_index, item_def_id);
+        self.collect_item(lang_item, item_def_id);
     }
 }
 
@@ -208,8 +204,8 @@ fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems {
 
     // Collect lang items in other crates.
     for &cnum in tcx.crates(()).iter() {
-        for &(def_id, item_index) in tcx.defined_lang_items(cnum).iter() {
-            collector.collect_item(item_index, def_id);
+        for &(def_id, lang_item) in tcx.defined_lang_items(cnum).iter() {
+            collector.collect_item(lang_item, def_id);
         }
     }
 
@@ -217,9 +213,9 @@ fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems {
     let crate_items = tcx.hir_crate_items(());
 
     for id in crate_items.items() {
-        collector.check_for_lang(Target::from_def_kind(tcx.def_kind(id.def_id)), id.hir_id());
+        collector.check_for_lang(Target::from_def_kind(tcx.def_kind(id.owner_id)), id.hir_id());
 
-        if matches!(tcx.def_kind(id.def_id), DefKind::Enum) {
+        if matches!(tcx.def_kind(id.owner_id), DefKind::Enum) {
             let item = tcx.hir().item(id);
             if let hir::ItemKind::Enum(def, ..) = &item.kind {
                 for variant in def.variants {
diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs
index c1085094962..5322baee747 100644
--- a/compiler/rustc_passes/src/layout_test.rs
+++ b/compiler/rustc_passes/src/layout_test.rs
@@ -15,11 +15,11 @@ pub fn test_layout(tcx: TyCtxt<'_>) {
         // if the `rustc_attrs` feature is not enabled, don't bother testing layout
         for id in tcx.hir().items() {
             if matches!(
-                tcx.def_kind(id.def_id),
+                tcx.def_kind(id.owner_id),
                 DefKind::TyAlias | DefKind::Enum | DefKind::Struct | DefKind::Union
             ) {
-                for attr in tcx.get_attrs(id.def_id.to_def_id(), sym::rustc_layout) {
-                    dump_layout_of(tcx, id.def_id.def_id, attr);
+                for attr in tcx.get_attrs(id.owner_id.to_def_id(), sym::rustc_layout) {
+                    dump_layout_of(tcx, id.owner_id.def_id, attr);
                 }
             }
         }
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index 0f2879c1eff..73ea06a6370 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -12,7 +12,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::Node;
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
-use rustc_middle::middle::privacy::{self, AccessLevel};
+use rustc_middle::middle::privacy::{self, Level};
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, DefIdTree, TyCtxt};
 use rustc_session::config::CrateType;
@@ -29,7 +29,7 @@ fn item_might_be_inlined(tcx: TyCtxt<'_>, item: &hir::Item<'_>, attrs: &CodegenF
     match item.kind {
         hir::ItemKind::Fn(ref sig, ..) if sig.header.is_const() => true,
         hir::ItemKind::Impl { .. } | hir::ItemKind::Fn(..) => {
-            let generics = tcx.generics_of(item.def_id);
+            let generics = tcx.generics_of(item.owner_id);
             generics.requires_monomorphization(tcx)
         }
         _ => false,
@@ -42,7 +42,7 @@ fn method_might_be_inlined(
     impl_src: LocalDefId,
 ) -> bool {
     let codegen_fn_attrs = tcx.codegen_fn_attrs(impl_item.hir_id().owner.to_def_id());
-    let generics = tcx.generics_of(impl_item.def_id);
+    let generics = tcx.generics_of(impl_item.owner_id);
     if codegen_fn_attrs.requests_inline() || generics.requires_monomorphization(tcx) {
         return true;
     }
@@ -216,7 +216,7 @@ impl<'tcx> ReachableContext<'tcx> {
                         if item_might_be_inlined(
                             self.tcx,
                             &item,
-                            self.tcx.codegen_fn_attrs(item.def_id),
+                            self.tcx.codegen_fn_attrs(item.owner_id),
                         ) {
                             self.visit_nested_body(body);
                         }
@@ -303,13 +303,13 @@ fn check_item<'tcx>(
     tcx: TyCtxt<'tcx>,
     id: hir::ItemId,
     worklist: &mut Vec<LocalDefId>,
-    access_levels: &privacy::AccessLevels,
+    effective_visibilities: &privacy::EffectiveVisibilities,
 ) {
-    if has_custom_linkage(tcx, id.def_id.def_id) {
-        worklist.push(id.def_id.def_id);
+    if has_custom_linkage(tcx, id.owner_id.def_id) {
+        worklist.push(id.owner_id.def_id);
     }
 
-    if !matches!(tcx.def_kind(id.def_id), DefKind::Impl) {
+    if !matches!(tcx.def_kind(id.owner_id), DefKind::Impl) {
         return;
     }
 
@@ -318,8 +318,8 @@ fn check_item<'tcx>(
     if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref trait_ref), ref items, .. }) =
         item.kind
     {
-        if !access_levels.is_reachable(item.def_id.def_id) {
-            worklist.extend(items.iter().map(|ii_ref| ii_ref.id.def_id.def_id));
+        if !effective_visibilities.is_reachable(item.owner_id.def_id) {
+            worklist.extend(items.iter().map(|ii_ref| ii_ref.id.owner_id.def_id));
 
             let Res::Def(DefKind::Trait, trait_def_id) = trait_ref.path.res else {
                 unreachable!();
@@ -354,7 +354,7 @@ fn has_custom_linkage<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
 }
 
 fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> FxHashSet<LocalDefId> {
-    let access_levels = &tcx.privacy_access_levels(());
+    let effective_visibilities = &tcx.effective_visibilities(());
 
     let any_library =
         tcx.sess.crate_types().iter().any(|ty| {
@@ -373,18 +373,16 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> FxHashSet<LocalDefId> {
     //         If other crates link to us, they're going to expect to be able to
     //         use the lang items, so we need to be sure to mark them as
     //         exported.
-    reachable_context.worklist = access_levels
+    reachable_context.worklist = effective_visibilities
         .iter()
         .filter_map(|(&id, effective_vis)| {
-            effective_vis.is_public_at_level(AccessLevel::ReachableFromImplTrait).then_some(id)
+            effective_vis.is_public_at_level(Level::ReachableThroughImplTrait).then_some(id)
         })
         .collect::<Vec<_>>();
 
-    for item in tcx.lang_items().items().iter() {
-        if let Some(def_id) = *item {
-            if let Some(def_id) = def_id.as_local() {
-                reachable_context.worklist.push(def_id);
-            }
+    for (_, def_id) in tcx.lang_items().iter() {
+        if let Some(def_id) = def_id.as_local() {
+            reachable_context.worklist.push(def_id);
         }
     }
     {
@@ -399,12 +397,12 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> FxHashSet<LocalDefId> {
         let crate_items = tcx.hir_crate_items(());
 
         for id in crate_items.items() {
-            check_item(tcx, id, &mut reachable_context.worklist, access_levels);
+            check_item(tcx, id, &mut reachable_context.worklist, effective_visibilities);
         }
 
         for id in crate_items.impl_items() {
-            if has_custom_linkage(tcx, id.def_id.def_id) {
-                reachable_context.worklist.push(id.def_id.def_id);
+            if has_custom_linkage(tcx, id.owner_id.def_id) {
+                reachable_context.worklist.push(id.owner_id.def_id);
             }
         }
     }
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 9591aeb881f..78afa2f25f8 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -20,7 +20,7 @@ use rustc_hir::hir_id::CRATE_HIR_ID;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{FieldDef, Item, ItemKind, TraitRef, Ty, TyKind, Variant};
 use rustc_middle::hir::nested_filter;
-use rustc_middle::middle::privacy::AccessLevels;
+use rustc_middle::middle::privacy::EffectiveVisibilities;
 use rustc_middle::middle::stability::{AllowUnstable, DeprecationEntry, Index};
 use rustc_middle::ty::{query::Providers, TyCtxt};
 use rustc_session::lint;
@@ -378,7 +378,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
         }
 
         self.annotate(
-            i.def_id.def_id,
+            i.owner_id.def_id,
             i.span,
             fn_sig,
             kind,
@@ -397,7 +397,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
         };
 
         self.annotate(
-            ti.def_id.def_id,
+            ti.owner_id.def_id,
             ti.span,
             fn_sig,
             AnnotationKind::Required,
@@ -420,7 +420,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
         };
 
         self.annotate(
-            ii.def_id.def_id,
+            ii.owner_id.def_id,
             ii.span,
             fn_sig,
             kind,
@@ -478,7 +478,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
 
     fn visit_foreign_item(&mut self, i: &'tcx hir::ForeignItem<'tcx>) {
         self.annotate(
-            i.def_id.def_id,
+            i.owner_id.def_id,
             i.span,
             None,
             AnnotationKind::Required,
@@ -516,13 +516,16 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
 
 struct MissingStabilityAnnotations<'tcx> {
     tcx: TyCtxt<'tcx>,
-    access_levels: &'tcx AccessLevels,
+    effective_visibilities: &'tcx EffectiveVisibilities,
 }
 
 impl<'tcx> MissingStabilityAnnotations<'tcx> {
     fn check_missing_stability(&self, def_id: LocalDefId, span: Span) {
         let stab = self.tcx.stability().local_stability(def_id);
-        if !self.tcx.sess.opts.test && stab.is_none() && self.access_levels.is_reachable(def_id) {
+        if !self.tcx.sess.opts.test
+            && stab.is_none()
+            && self.effective_visibilities.is_reachable(def_id)
+        {
             let descr = self.tcx.def_kind(def_id).descr(def_id.to_def_id());
             self.tcx.sess.emit_err(MissingStabilityAttr { span, descr });
         }
@@ -540,7 +543,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
             .lookup_stability(def_id)
             .map_or(false, |stability| stability.level.is_stable());
         let missing_const_stability_attribute = self.tcx.lookup_const_stability(def_id).is_none();
-        let is_reachable = self.access_levels.is_reachable(def_id);
+        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());
@@ -566,25 +569,25 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
             hir::ItemKind::Impl(hir::Impl { of_trait: None, .. })
                 | hir::ItemKind::ForeignMod { .. }
         ) {
-            self.check_missing_stability(i.def_id.def_id, i.span);
+            self.check_missing_stability(i.owner_id.def_id, i.span);
         }
 
         // Ensure stable `const fn` have a const stability attribute.
-        self.check_missing_const_stability(i.def_id.def_id, i.span);
+        self.check_missing_const_stability(i.owner_id.def_id, i.span);
 
         intravisit::walk_item(self, i)
     }
 
     fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem<'tcx>) {
-        self.check_missing_stability(ti.def_id.def_id, ti.span);
+        self.check_missing_stability(ti.owner_id.def_id, ti.span);
         intravisit::walk_trait_item(self, ti);
     }
 
     fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) {
         let impl_def_id = self.tcx.hir().get_parent_item(ii.hir_id());
         if self.tcx.impl_trait_ref(impl_def_id).is_none() {
-            self.check_missing_stability(ii.def_id.def_id, ii.span);
-            self.check_missing_const_stability(ii.def_id.def_id, ii.span);
+            self.check_missing_stability(ii.owner_id.def_id, ii.span);
+            self.check_missing_const_stability(ii.owner_id.def_id, ii.span);
         }
         intravisit::walk_impl_item(self, ii);
     }
@@ -603,7 +606,7 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
     }
 
     fn visit_foreign_item(&mut self, i: &'tcx hir::ForeignItem<'tcx>) {
-        self.check_missing_stability(i.def_id.def_id, i.span);
+        self.check_missing_stability(i.owner_id.def_id, i.span);
         intravisit::walk_foreign_item(self, i);
     }
     // Note that we don't need to `check_missing_stability` for default generic parameters,
@@ -709,7 +712,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
                     return;
                 }
 
-                let Some(cnum) = self.tcx.extern_mod_stmt_cnum(item.def_id.def_id) else {
+                let Some(cnum) = self.tcx.extern_mod_stmt_cnum(item.owner_id.def_id) else {
                     return;
                 };
                 let def_id = cnum.as_def_id();
@@ -762,7 +765,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
                 }
 
                 for impl_item_ref in *items {
-                    let impl_item = self.tcx.associated_item(impl_item_ref.id.def_id);
+                    let impl_item = self.tcx.associated_item(impl_item_ref.id.owner_id);
 
                     if let Some(def_id) = impl_item.trait_item_def_id {
                         // Pass `None` to skip deprecation warnings.
@@ -919,8 +922,8 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
     let is_staged_api =
         tcx.sess.opts.unstable_opts.force_unstable_if_unmarked || tcx.features().staged_api;
     if is_staged_api {
-        let access_levels = &tcx.privacy_access_levels(());
-        let mut missing = MissingStabilityAnnotations { tcx, access_levels };
+        let effective_visibilities = &tcx.effective_visibilities(());
+        let mut missing = MissingStabilityAnnotations { tcx, effective_visibilities };
         missing.check_missing_stability(CRATE_DEF_ID, tcx.hir().span(CRATE_HIR_ID));
         tcx.hir().walk_toplevel_module(&mut missing);
         tcx.hir().visit_all_item_likes_in_crate(&mut missing);
diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs
index 92024989a75..94d6a405b53 100644
--- a/compiler/rustc_passes/src/weak_lang_items.rs
+++ b/compiler/rustc_passes/src/weak_lang_items.rs
@@ -2,7 +2,7 @@
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::lang_items::{self, LangItem};
-use rustc_hir::weak_lang_items::WEAK_ITEMS_REFS;
+use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
 use rustc_middle::middle::lang_items::required;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::CrateType;
@@ -29,12 +29,12 @@ pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>, items: &mut lang_items::LanguageItem
     for id in crate_items.foreign_items() {
         let attrs = tcx.hir().attrs(id.hir_id());
         if let Some((lang_item, _)) = lang_items::extract(attrs) {
-            if let Some(&item) = WEAK_ITEMS_REFS.get(&lang_item) {
-                if items.require(item).is_err() {
+            if let Some(item) = LangItem::from_name(lang_item) && item.is_weak() {
+                if items.get(item).is_none() {
                     items.missing.push(item);
                 }
             } else {
-                let span = tcx.def_span(id.def_id);
+                let span = tcx.def_span(id.owner_id);
                 tcx.sess.emit_err(UnknownExternLangItem { span, lang_item });
             }
         }
@@ -65,8 +65,8 @@ fn verify<'tcx>(tcx: TyCtxt<'tcx>, items: &lang_items::LanguageItems) {
         }
     }
 
-    for (name, &item) in WEAK_ITEMS_REFS.iter() {
-        if missing.contains(&item) && required(tcx, item) && items.require(item).is_err() {
+    for &item in WEAK_LANG_ITEMS.iter() {
+        if missing.contains(&item) && required(tcx, item) && items.get(item).is_none() {
             if item == LangItem::PanicImpl {
                 tcx.sess.emit_err(MissingPanicHandler);
             } else if item == LangItem::Oom {
@@ -75,7 +75,7 @@ fn verify<'tcx>(tcx: TyCtxt<'tcx>, items: &lang_items::LanguageItems) {
                     tcx.sess.emit_note(MissingAllocErrorHandler);
                 }
             } else {
-                tcx.sess.emit_err(MissingLangItem { name: *name });
+                tcx.sess.emit_err(MissingLangItem { name: item.name() });
             }
         }
     }
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 4db58d92bd5..865d6306bd3 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -23,7 +23,7 @@ use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{AssocItemKind, HirIdSet, ItemId, Node, PatKind};
 use rustc_middle::bug;
 use rustc_middle::hir::nested_filter;
-use rustc_middle::middle::privacy::{AccessLevel, AccessLevels};
+use rustc_middle::middle::privacy::{EffectiveVisibilities, Level};
 use rustc_middle::span_bug;
 use rustc_middle::ty::abstract_const::{walk_abstract_const, AbstractConst, Node as ACNode};
 use rustc_middle::ty::query::Providers;
@@ -310,7 +310,7 @@ fn min(vis1: ty::Visibility, vis2: ty::Visibility, tcx: TyCtxt<'_>) -> ty::Visib
 
 struct FindMin<'a, 'tcx, VL: VisibilityLike> {
     tcx: TyCtxt<'tcx>,
-    access_levels: &'a AccessLevels,
+    effective_visibilities: &'a EffectiveVisibilities,
     min: VL,
 }
 
@@ -344,8 +344,12 @@ trait VisibilityLike: Sized {
 
     // Returns an over-approximation (`skip_assoc_tys` = true) of visibility due to
     // associated types for which we can't determine visibility precisely.
-    fn of_impl(def_id: LocalDefId, tcx: TyCtxt<'_>, access_levels: &AccessLevels) -> Self {
-        let mut find = FindMin { tcx, access_levels, min: Self::MAX };
+    fn of_impl(
+        def_id: LocalDefId,
+        tcx: TyCtxt<'_>,
+        effective_visibilities: &EffectiveVisibilities,
+    ) -> Self {
+        let mut find = FindMin { tcx, effective_visibilities, min: Self::MAX };
         find.visit(tcx.type_of(def_id));
         if let Some(trait_ref) = tcx.impl_trait_ref(def_id) {
             find.visit_trait(trait_ref);
@@ -359,8 +363,8 @@ impl VisibilityLike for ty::Visibility {
         min(find.tcx.local_visibility(def_id), find.min, find.tcx)
     }
 }
-impl VisibilityLike for Option<AccessLevel> {
-    const MAX: Self = Some(AccessLevel::Public);
+impl VisibilityLike for Option<Level> {
+    const MAX: Self = Some(Level::Direct);
     // Type inference is very smart sometimes.
     // It can make an impl reachable even some components of its type or trait are unreachable.
     // E.g. methods of `impl ReachableTrait<UnreachableTy> for ReachableTy<UnreachableTy> { ... }`
@@ -372,7 +376,7 @@ impl VisibilityLike for Option<AccessLevel> {
     // (which require reaching the `DefId`s in them).
     const SHALLOW: bool = true;
     fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self {
-        cmp::min(find.access_levels.get_access_level(def_id), find.min)
+        cmp::min(find.effective_visibilities.public_at_level(def_id), find.min)
     }
 }
 
@@ -383,8 +387,8 @@ impl VisibilityLike for Option<AccessLevel> {
 struct EmbargoVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
 
-    /// Accessibility levels for reachable nodes.
-    access_levels: AccessLevels,
+    /// Effective visibilities for reachable nodes.
+    effective_visibilities: EffectiveVisibilities,
     /// A set of pairs corresponding to modules, where the first module is
     /// reachable via a macro that's defined in the second module. This cannot
     /// be represented as reachable because it can't handle the following case:
@@ -398,38 +402,34 @@ struct EmbargoVisitor<'tcx> {
     ///     n::p::f()
     /// }
     macro_reachable: FxHashSet<(LocalDefId, LocalDefId)>,
-    /// Previous accessibility level; `None` means unreachable.
-    prev_level: Option<AccessLevel>,
+    /// Previous visibility level; `None` means unreachable.
+    prev_level: Option<Level>,
     /// Has something changed in the level map?
     changed: bool,
 }
 
 struct ReachEverythingInTheInterfaceVisitor<'a, 'tcx> {
-    access_level: Option<AccessLevel>,
+    level: Option<Level>,
     item_def_id: LocalDefId,
     ev: &'a mut EmbargoVisitor<'tcx>,
 }
 
 impl<'tcx> EmbargoVisitor<'tcx> {
-    fn get(&self, def_id: LocalDefId) -> Option<AccessLevel> {
-        self.access_levels.get_access_level(def_id)
+    fn get(&self, def_id: LocalDefId) -> Option<Level> {
+        self.effective_visibilities.public_at_level(def_id)
     }
 
-    fn update_with_hir_id(
-        &mut self,
-        hir_id: hir::HirId,
-        level: Option<AccessLevel>,
-    ) -> Option<AccessLevel> {
+    fn update_with_hir_id(&mut self, hir_id: hir::HirId, level: Option<Level>) -> Option<Level> {
         let def_id = self.tcx.hir().local_def_id(hir_id);
         self.update(def_id, level)
     }
 
     /// Updates node level and returns the updated level.
-    fn update(&mut self, def_id: LocalDefId, level: Option<AccessLevel>) -> Option<AccessLevel> {
+    fn update(&mut self, def_id: LocalDefId, level: Option<Level>) -> Option<Level> {
         let old_level = self.get(def_id);
-        // Accessibility levels can only grow.
+        // Visibility levels can only grow.
         if level > old_level {
-            self.access_levels.set_access_level(
+            self.effective_visibilities.set_public_at_level(
                 def_id,
                 || ty::Visibility::Restricted(self.tcx.parent_module_from_def_id(def_id)),
                 level.unwrap(),
@@ -444,10 +444,10 @@ impl<'tcx> EmbargoVisitor<'tcx> {
     fn reach(
         &mut self,
         def_id: LocalDefId,
-        access_level: Option<AccessLevel>,
+        level: Option<Level>,
     ) -> ReachEverythingInTheInterfaceVisitor<'_, 'tcx> {
         ReachEverythingInTheInterfaceVisitor {
-            access_level: cmp::min(access_level, Some(AccessLevel::Reachable)),
+            level: cmp::min(level, Some(Level::Reachable)),
             item_def_id: def_id,
             ev: self,
         }
@@ -505,9 +505,9 @@ impl<'tcx> EmbargoVisitor<'tcx> {
     fn update_macro_reachable_mod(&mut self, module_def_id: LocalDefId, defining_mod: LocalDefId) {
         let module = self.tcx.hir().get_module(module_def_id).0;
         for item_id in module.item_ids {
-            let def_kind = self.tcx.def_kind(item_id.def_id);
-            let vis = self.tcx.local_visibility(item_id.def_id.def_id);
-            self.update_macro_reachable_def(item_id.def_id.def_id, def_kind, vis, defining_mod);
+            let def_kind = self.tcx.def_kind(item_id.owner_id);
+            let vis = self.tcx.local_visibility(item_id.owner_id.def_id);
+            self.update_macro_reachable_def(item_id.owner_id.def_id, def_kind, vis, defining_mod);
         }
         if let Some(exports) = self.tcx.module_reexports(module_def_id) {
             for export in exports {
@@ -530,7 +530,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
         vis: ty::Visibility,
         module: LocalDefId,
     ) {
-        let level = Some(AccessLevel::Reachable);
+        let level = Some(Level::Reachable);
         if vis.is_public() {
             self.update(def_id, level);
         }
@@ -627,14 +627,14 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
         let item_level = match item.kind {
             hir::ItemKind::Impl { .. } => {
-                let impl_level = Option::<AccessLevel>::of_impl(
-                    item.def_id.def_id,
+                let impl_level = Option::<Level>::of_impl(
+                    item.owner_id.def_id,
                     self.tcx,
-                    &self.access_levels,
+                    &self.effective_visibilities,
                 );
-                self.update(item.def_id.def_id, impl_level)
+                self.update(item.owner_id.def_id, impl_level)
             }
-            _ => self.get(item.def_id.def_id),
+            _ => self.get(item.owner_id.def_id),
         };
 
         // Update levels of nested things.
@@ -653,15 +653,15 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
             hir::ItemKind::Impl(ref impl_) => {
                 for impl_item_ref in impl_.items {
                     if impl_.of_trait.is_some()
-                        || self.tcx.visibility(impl_item_ref.id.def_id).is_public()
+                        || self.tcx.visibility(impl_item_ref.id.owner_id).is_public()
                     {
-                        self.update(impl_item_ref.id.def_id.def_id, item_level);
+                        self.update(impl_item_ref.id.owner_id.def_id, item_level);
                     }
                 }
             }
             hir::ItemKind::Trait(.., trait_item_refs) => {
                 for trait_item_ref in trait_item_refs {
-                    self.update(trait_item_ref.id.def_id.def_id, item_level);
+                    self.update(trait_item_ref.id.owner_id.def_id, item_level);
                 }
             }
             hir::ItemKind::Struct(ref def, _) | hir::ItemKind::Union(ref def, _) => {
@@ -677,12 +677,12 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
                 }
             }
             hir::ItemKind::Macro(ref macro_def, _) => {
-                self.update_reachability_from_macro(item.def_id.def_id, macro_def);
+                self.update_reachability_from_macro(item.owner_id.def_id, macro_def);
             }
             hir::ItemKind::ForeignMod { items, .. } => {
                 for foreign_item in items {
-                    if self.tcx.visibility(foreign_item.id.def_id).is_public() {
-                        self.update(foreign_item.id.def_id.def_id, item_level);
+                    if self.tcx.visibility(foreign_item.id.owner_id).is_public() {
+                        self.update(foreign_item.id.owner_id.def_id, item_level);
                     }
                 }
             }
@@ -705,7 +705,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
             hir::ItemKind::Macro(..) | hir::ItemKind::ExternCrate(..) => {}
             // All nested items are checked by `visit_item`.
             hir::ItemKind::Mod(..) => {}
-            // Handled in the access level of in rustc_resolve
+            // Handled in `rustc_resolve`.
             hir::ItemKind::Use(..) => {}
             // The interface is empty.
             hir::ItemKind::GlobalAsm(..) => {}
@@ -718,9 +718,8 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
                     // FIXME: This is some serious pessimization intended to workaround deficiencies
                     // in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
                     // reachable if they are returned via `impl Trait`, even from private functions.
-                    let exist_level =
-                        cmp::max(item_level, Some(AccessLevel::ReachableFromImplTrait));
-                    self.reach(item.def_id.def_id, exist_level).generics().predicates().ty();
+                    let exist_level = cmp::max(item_level, Some(Level::ReachableThroughImplTrait));
+                    self.reach(item.owner_id.def_id, exist_level).generics().predicates().ty();
                 }
             }
             // Visit everything.
@@ -729,20 +728,20 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
             | hir::ItemKind::Fn(..)
             | hir::ItemKind::TyAlias(..) => {
                 if item_level.is_some() {
-                    self.reach(item.def_id.def_id, item_level).generics().predicates().ty();
+                    self.reach(item.owner_id.def_id, item_level).generics().predicates().ty();
                 }
             }
             hir::ItemKind::Trait(.., trait_item_refs) => {
                 if item_level.is_some() {
-                    self.reach(item.def_id.def_id, item_level).generics().predicates();
+                    self.reach(item.owner_id.def_id, item_level).generics().predicates();
 
                     for trait_item_ref in trait_item_refs {
                         let tcx = self.tcx;
-                        let mut reach = self.reach(trait_item_ref.id.def_id.def_id, item_level);
+                        let mut reach = self.reach(trait_item_ref.id.owner_id.def_id, item_level);
                         reach.generics().predicates();
 
                         if trait_item_ref.kind == AssocItemKind::Type
-                            && !tcx.impl_defaultness(trait_item_ref.id.def_id).has_value()
+                            && !tcx.impl_defaultness(trait_item_ref.id.owner_id).has_value()
                         {
                             // No type to visit.
                         } else {
@@ -753,22 +752,22 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
             }
             hir::ItemKind::TraitAlias(..) => {
                 if item_level.is_some() {
-                    self.reach(item.def_id.def_id, item_level).generics().predicates();
+                    self.reach(item.owner_id.def_id, item_level).generics().predicates();
                 }
             }
             // Visit everything except for private impl items.
             hir::ItemKind::Impl(ref impl_) => {
                 if item_level.is_some() {
-                    self.reach(item.def_id.def_id, item_level)
+                    self.reach(item.owner_id.def_id, item_level)
                         .generics()
                         .predicates()
                         .ty()
                         .trait_ref();
 
                     for impl_item_ref in impl_.items {
-                        let impl_item_level = self.get(impl_item_ref.id.def_id.def_id);
+                        let impl_item_level = self.get(impl_item_ref.id.owner_id.def_id);
                         if impl_item_level.is_some() {
-                            self.reach(impl_item_ref.id.def_id.def_id, impl_item_level)
+                            self.reach(impl_item_ref.id.owner_id.def_id, impl_item_level)
                                 .generics()
                                 .predicates()
                                 .ty();
@@ -780,7 +779,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
             // Visit everything, but enum variants have their own levels.
             hir::ItemKind::Enum(ref def, _) => {
                 if item_level.is_some() {
-                    self.reach(item.def_id.def_id, item_level).generics().predicates();
+                    self.reach(item.owner_id.def_id, item_level).generics().predicates();
                 }
                 for variant in def.variants {
                     let variant_level = self.get(self.tcx.hir().local_def_id(variant.id));
@@ -791,13 +790,13 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
                         }
                         // Corner case: if the variant is reachable, but its
                         // enum is not, make the enum reachable as well.
-                        self.reach(item.def_id.def_id, variant_level).ty();
+                        self.reach(item.owner_id.def_id, variant_level).ty();
                     }
                     if let Some(hir_id) = variant.data.ctor_hir_id() {
                         let ctor_def_id = self.tcx.hir().local_def_id(hir_id);
                         let ctor_level = self.get(ctor_def_id);
                         if ctor_level.is_some() {
-                            self.reach(item.def_id.def_id, ctor_level).ty();
+                            self.reach(item.owner_id.def_id, ctor_level).ty();
                         }
                     }
                 }
@@ -805,9 +804,9 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
             // Visit everything, but foreign items have their own levels.
             hir::ItemKind::ForeignMod { items, .. } => {
                 for foreign_item in items {
-                    let foreign_item_level = self.get(foreign_item.id.def_id.def_id);
+                    let foreign_item_level = self.get(foreign_item.id.owner_id.def_id);
                     if foreign_item_level.is_some() {
-                        self.reach(foreign_item.id.def_id.def_id, foreign_item_level)
+                        self.reach(foreign_item.id.owner_id.def_id, foreign_item_level)
                             .generics()
                             .predicates()
                             .ty();
@@ -817,7 +816,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
             // Visit everything except for private fields.
             hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => {
                 if item_level.is_some() {
-                    self.reach(item.def_id.def_id, item_level).generics().predicates();
+                    self.reach(item.owner_id.def_id, item_level).generics().predicates();
                     for field in struct_def.fields() {
                         let def_id = self.tcx.hir().local_def_id(field.hir_id);
                         let field_level = self.get(def_id);
@@ -830,7 +829,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
                     let ctor_def_id = self.tcx.hir().local_def_id(hir_id);
                     let ctor_level = self.get(ctor_def_id);
                     if ctor_level.is_some() {
-                        self.reach(item.def_id.def_id, ctor_level).ty();
+                        self.reach(item.owner_id.def_id, ctor_level).ty();
                     }
                 }
             }
@@ -901,10 +900,10 @@ impl<'tcx> DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx>
         _descr: &dyn fmt::Display,
     ) -> ControlFlow<Self::BreakTy> {
         if let Some(def_id) = def_id.as_local() {
-            if let (ty::Visibility::Public, _) | (_, Some(AccessLevel::ReachableFromImplTrait)) =
-                (self.tcx().visibility(def_id.to_def_id()), self.access_level)
+            if let (ty::Visibility::Public, _) | (_, Some(Level::ReachableThroughImplTrait)) =
+                (self.tcx().visibility(def_id.to_def_id()), self.level)
             {
-                self.ev.update(def_id, self.access_level);
+                self.ev.update(def_id, self.level);
             }
         }
         ControlFlow::CONTINUE
@@ -912,21 +911,21 @@ impl<'tcx> DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx>
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-/// Visitor, used for AccessLevels table checking
+/// Visitor, used for EffectiveVisibilities table checking
 ////////////////////////////////////////////////////////////////////////////////
 pub struct TestReachabilityVisitor<'tcx, 'a> {
     tcx: TyCtxt<'tcx>,
-    access_levels: &'a AccessLevels,
+    effective_visibilities: &'a EffectiveVisibilities,
 }
 
 impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
-    fn access_level_diagnostic(&mut self, def_id: LocalDefId) {
+    fn effective_visibility_diagnostic(&mut self, def_id: LocalDefId) {
         if self.tcx.has_attr(def_id.to_def_id(), sym::rustc_effective_visibility) {
             let mut error_msg = String::new();
             let span = self.tcx.def_span(def_id.to_def_id());
-            if let Some(effective_vis) = self.access_levels.get_effective_vis(def_id) {
-                for level in AccessLevel::all_levels() {
-                    let vis_str = match effective_vis.get(level) {
+            if let Some(effective_vis) = self.effective_visibilities.effective_vis(def_id) {
+                for level in Level::all_levels() {
+                    let vis_str = match effective_vis.at_level(level) {
                         ty::Visibility::Restricted(restricted_id) => {
                             if restricted_id.is_top_level_module() {
                                 "pub(crate)".to_string()
@@ -938,7 +937,7 @@ impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
                         }
                         ty::Visibility::Public => "pub".to_string(),
                     };
-                    if level != AccessLevel::Public {
+                    if level != Level::Direct {
                         error_msg.push_str(", ");
                     }
                     error_msg.push_str(&format!("{:?}: {}", level, vis_str));
@@ -953,23 +952,23 @@ impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
 
 impl<'tcx, 'a> Visitor<'tcx> for TestReachabilityVisitor<'tcx, 'a> {
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
-        self.access_level_diagnostic(item.def_id.def_id);
+        self.effective_visibility_diagnostic(item.owner_id.def_id);
 
         match item.kind {
             hir::ItemKind::Enum(ref def, _) => {
                 for variant in def.variants.iter() {
                     let variant_id = self.tcx.hir().local_def_id(variant.id);
-                    self.access_level_diagnostic(variant_id);
+                    self.effective_visibility_diagnostic(variant_id);
                     for field in variant.data.fields() {
                         let def_id = self.tcx.hir().local_def_id(field.hir_id);
-                        self.access_level_diagnostic(def_id);
+                        self.effective_visibility_diagnostic(def_id);
                     }
                 }
             }
             hir::ItemKind::Struct(ref def, _) | hir::ItemKind::Union(ref def, _) => {
                 for field in def.fields() {
                     let def_id = self.tcx.hir().local_def_id(field.hir_id);
-                    self.access_level_diagnostic(def_id);
+                    self.effective_visibility_diagnostic(def_id);
                 }
             }
             _ => {}
@@ -977,13 +976,13 @@ impl<'tcx, 'a> Visitor<'tcx> for TestReachabilityVisitor<'tcx, 'a> {
     }
 
     fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem<'tcx>) {
-        self.access_level_diagnostic(item.def_id.def_id);
+        self.effective_visibility_diagnostic(item.owner_id.def_id);
     }
     fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem<'tcx>) {
-        self.access_level_diagnostic(item.def_id.def_id);
+        self.effective_visibility_diagnostic(item.owner_id.def_id);
     }
     fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
-        self.access_level_diagnostic(item.def_id.def_id);
+        self.effective_visibility_diagnostic(item.owner_id.def_id);
     }
 }
 
@@ -1054,7 +1053,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
 
     fn visit_mod(&mut self, _m: &'tcx hir::Mod<'tcx>, _s: Span, _n: hir::HirId) {
         // Don't visit nested modules, since we run a separate visitor walk
-        // for each module in `privacy_access_levels`
+        // for each module in `effective_visibilities`
     }
 
     fn visit_nested_body(&mut self, body: hir::BodyId) {
@@ -1066,7 +1065,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
     }
 
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
-        let orig_current_item = mem::replace(&mut self.current_item, item.def_id.def_id);
+        let orig_current_item = mem::replace(&mut self.current_item, item.owner_id.def_id);
         intravisit::walk_item(self, item);
         self.current_item = orig_current_item;
     }
@@ -1179,7 +1178,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
 
     fn visit_mod(&mut self, _m: &'tcx hir::Mod<'tcx>, _s: Span, _n: hir::HirId) {
         // Don't visit nested modules, since we run a separate visitor walk
-        // for each module in `privacy_access_levels`
+        // for each module in `effective_visibilities`
     }
 
     fn visit_nested_body(&mut self, body: hir::BodyId) {
@@ -1369,7 +1368,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
 
     // Check types in item interfaces.
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
-        let orig_current_item = mem::replace(&mut self.current_item, item.def_id.def_id);
+        let orig_current_item = mem::replace(&mut self.current_item, item.owner_id.def_id);
         let old_maybe_typeck_results = self.maybe_typeck_results.take();
         intravisit::walk_item(self, item);
         self.maybe_typeck_results = old_maybe_typeck_results;
@@ -1404,7 +1403,7 @@ impl<'tcx> DefIdVisitor<'tcx> for TypePrivacyVisitor<'tcx> {
 
 struct ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
-    access_levels: &'a AccessLevels,
+    effective_visibilities: &'a EffectiveVisibilities,
     in_variant: bool,
     // Set of errors produced by this obsolete visitor.
     old_error_set: HirIdSet,
@@ -1447,7 +1446,7 @@ impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
     fn trait_is_public(&self, trait_id: LocalDefId) -> bool {
         // FIXME: this would preferably be using `exported_items`, but all
         // traits are exported currently (see `EmbargoVisitor.exported_trait`).
-        self.access_levels.is_public(trait_id)
+        self.effective_visibilities.is_directly_public(trait_id)
     }
 
     fn check_generic_bound(&mut self, bound: &hir::GenericBound<'_>) {
@@ -1459,7 +1458,7 @@ impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
     }
 
     fn item_is_public(&self, def_id: LocalDefId) -> bool {
-        self.access_levels.is_reachable(def_id) || self.tcx.visibility(def_id).is_public()
+        self.effective_visibilities.is_reachable(def_id) || self.tcx.visibility(def_id).is_public()
     }
 }
 
@@ -1513,7 +1512,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
             hir::ItemKind::ForeignMod { .. } => {}
 
             hir::ItemKind::Trait(.., bounds, _) => {
-                if !self.trait_is_public(item.def_id.def_id) {
+                if !self.trait_is_public(item.owner_id.def_id) {
                     return;
                 }
 
@@ -1573,9 +1572,9 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
                     || impl_.items.iter().any(|impl_item_ref| {
                         let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
                         match impl_item.kind {
-                            hir::ImplItemKind::Const(..) | hir::ImplItemKind::Fn(..) => {
-                                self.access_levels.is_reachable(impl_item_ref.id.def_id.def_id)
-                            }
+                            hir::ImplItemKind::Const(..) | hir::ImplItemKind::Fn(..) => self
+                                .effective_visibilities
+                                .is_reachable(impl_item_ref.id.owner_id.def_id),
                             hir::ImplItemKind::Type(_) => false,
                         }
                     });
@@ -1594,7 +1593,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
                                 let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
                                 match impl_item.kind {
                                     hir::ImplItemKind::Const(..) | hir::ImplItemKind::Fn(..)
-                                        if self.item_is_public(impl_item.def_id.def_id) =>
+                                        if self.item_is_public(impl_item.owner_id.def_id) =>
                                     {
                                         intravisit::walk_impl_item(self, impl_item)
                                     }
@@ -1635,8 +1634,10 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
                     // methods will be visible as `Public::foo`.
                     let mut found_pub_static = false;
                     for impl_item_ref in impl_.items {
-                        if self.access_levels.is_reachable(impl_item_ref.id.def_id.def_id)
-                            || self.tcx.visibility(impl_item_ref.id.def_id).is_public()
+                        if self
+                            .effective_visibilities
+                            .is_reachable(impl_item_ref.id.owner_id.def_id)
+                            || self.tcx.visibility(impl_item_ref.id.owner_id).is_public()
                         {
                             let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
                             match impl_item_ref.kind {
@@ -1664,7 +1665,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
             hir::ItemKind::TyAlias(..) => return,
 
             // Not at all public, so we don't care.
-            _ if !self.item_is_public(item.def_id.def_id) => {
+            _ if !self.item_is_public(item.owner_id.def_id) => {
                 return;
             }
 
@@ -1695,7 +1696,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
     }
 
     fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
-        if self.access_levels.is_reachable(item.def_id.def_id) {
+        if self.effective_visibilities.is_reachable(item.owner_id.def_id) {
             intravisit::walk_foreign_item(self, item)
         }
     }
@@ -1710,7 +1711,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
     }
 
     fn visit_variant(&mut self, v: &'tcx hir::Variant<'tcx>) {
-        if self.access_levels.is_reachable(self.tcx.hir().local_def_id(v.id)) {
+        if self.effective_visibilities.is_reachable(self.tcx.hir().local_def_id(v.id)) {
             self.in_variant = true;
             intravisit::walk_variant(self, v);
             self.in_variant = false;
@@ -1932,7 +1933,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
 
     pub fn check_item(&mut self, id: ItemId) {
         let tcx = self.tcx;
-        let def_id = id.def_id.def_id;
+        let def_id = id.owner_id.def_id;
         let item_visibility = tcx.local_visibility(def_id);
         let def_kind = tcx.def_kind(def_id);
 
@@ -1948,17 +1949,17 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
             DefKind::Trait => {
                 let item = tcx.hir().item(id);
                 if let hir::ItemKind::Trait(.., trait_item_refs) = item.kind {
-                    self.check(item.def_id.def_id, item_visibility).generics().predicates();
+                    self.check(item.owner_id.def_id, item_visibility).generics().predicates();
 
                     for trait_item_ref in trait_item_refs {
                         self.check_assoc_item(
-                            trait_item_ref.id.def_id.def_id,
+                            trait_item_ref.id.owner_id.def_id,
                             trait_item_ref.kind,
                             item_visibility,
                         );
 
                         if let AssocItemKind::Type = trait_item_ref.kind {
-                            self.check(trait_item_ref.id.def_id.def_id, item_visibility).bounds();
+                            self.check(trait_item_ref.id.owner_id.def_id, item_visibility).bounds();
                         }
                     }
                 }
@@ -1969,7 +1970,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
             DefKind::Enum => {
                 let item = tcx.hir().item(id);
                 if let hir::ItemKind::Enum(ref def, _) = item.kind {
-                    self.check(item.def_id.def_id, item_visibility).generics().predicates();
+                    self.check(item.owner_id.def_id, item_visibility).generics().predicates();
 
                     for variant in def.variants {
                         for field in variant.data.fields() {
@@ -1984,8 +1985,11 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
                 let item = tcx.hir().item(id);
                 if let hir::ItemKind::ForeignMod { items, .. } = item.kind {
                     for foreign_item in items {
-                        let vis = tcx.local_visibility(foreign_item.id.def_id.def_id);
-                        self.check(foreign_item.id.def_id.def_id, vis).generics().predicates().ty();
+                        let vis = tcx.local_visibility(foreign_item.id.owner_id.def_id);
+                        self.check(foreign_item.id.owner_id.def_id, vis)
+                            .generics()
+                            .predicates()
+                            .ty();
                     }
                 }
             }
@@ -1995,7 +1999,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
                 if let hir::ItemKind::Struct(ref struct_def, _)
                 | hir::ItemKind::Union(ref struct_def, _) = item.kind
                 {
-                    self.check(item.def_id.def_id, item_visibility).generics().predicates();
+                    self.check(item.owner_id.def_id, item_visibility).generics().predicates();
 
                     for field in struct_def.fields() {
                         let def_id = tcx.hir().local_def_id(field.hir_id);
@@ -2012,20 +2016,24 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
                 let item = tcx.hir().item(id);
                 if let hir::ItemKind::Impl(ref impl_) = item.kind {
                     let impl_vis =
-                        ty::Visibility::of_impl(item.def_id.def_id, tcx, &Default::default());
+                        ty::Visibility::of_impl(item.owner_id.def_id, tcx, &Default::default());
                     // check that private components do not appear in the generics or predicates of inherent impls
                     // this check is intentionally NOT performed for impls of traits, per #90586
                     if impl_.of_trait.is_none() {
-                        self.check(item.def_id.def_id, impl_vis).generics().predicates();
+                        self.check(item.owner_id.def_id, impl_vis).generics().predicates();
                     }
                     for impl_item_ref in impl_.items {
                         let impl_item_vis = if impl_.of_trait.is_none() {
-                            min(tcx.local_visibility(impl_item_ref.id.def_id.def_id), impl_vis, tcx)
+                            min(
+                                tcx.local_visibility(impl_item_ref.id.owner_id.def_id),
+                                impl_vis,
+                                tcx,
+                            )
                         } else {
                             impl_vis
                         };
                         self.check_assoc_item(
-                            impl_item_ref.id.def_id.def_id,
+                            impl_item_ref.id.owner_id.def_id,
                             impl_item_ref.kind,
                             impl_item_vis,
                         );
@@ -2040,7 +2048,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
 pub fn provide(providers: &mut Providers) {
     *providers = Providers {
         visibility,
-        privacy_access_levels,
+        effective_visibilities,
         check_private_in_public,
         check_mod_privacy,
         ..*providers
@@ -2112,14 +2120,14 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
     intravisit::walk_mod(&mut visitor, module, hir_id);
 }
 
-fn privacy_access_levels(tcx: TyCtxt<'_>, (): ()) -> &AccessLevels {
+fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
     // Build up a set of all exported items in the AST. This is a set of all
     // items which are reachable from external crates based on visibility.
     let mut visitor = EmbargoVisitor {
         tcx,
-        access_levels: tcx.resolutions(()).access_levels.clone(),
+        effective_visibilities: tcx.resolutions(()).effective_visibilities.clone(),
         macro_reachable: Default::default(),
-        prev_level: Some(AccessLevel::Public),
+        prev_level: Some(Level::Direct),
         changed: false,
     };
 
@@ -2132,18 +2140,19 @@ fn privacy_access_levels(tcx: TyCtxt<'_>, (): ()) -> &AccessLevels {
         }
     }
 
-    let mut check_visitor = TestReachabilityVisitor { tcx, access_levels: &visitor.access_levels };
+    let mut check_visitor =
+        TestReachabilityVisitor { tcx, effective_visibilities: &visitor.effective_visibilities };
     tcx.hir().visit_all_item_likes_in_crate(&mut check_visitor);
 
-    tcx.arena.alloc(visitor.access_levels)
+    tcx.arena.alloc(visitor.effective_visibilities)
 }
 
 fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
-    let access_levels = tcx.privacy_access_levels(());
+    let effective_visibilities = tcx.effective_visibilities(());
 
     let mut visitor = ObsoleteVisiblePrivateTypesVisitor {
         tcx,
-        access_levels,
+        effective_visibilities,
         in_variant: false,
         old_error_set: Default::default(),
     };
diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs
index a5921650112..8b14ce210a2 100644
--- a/compiler/rustc_query_impl/src/on_disk_cache.rs
+++ b/compiler/rustc_query_impl/src/on_disk_cache.rs
@@ -1,8 +1,9 @@
 use crate::QueryCtxt;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
+use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
 use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, RwLock};
 use rustc_data_structures::unhash::UnhashMap;
+use rustc_data_structures::unord::UnordSet;
 use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, StableCrateId, LOCAL_CRATE};
 use rustc_hir::definitions::DefPathHash;
 use rustc_index::vec::{Idx, IndexVec};
@@ -792,7 +793,7 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for DefId {
     }
 }
 
-impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx FxHashSet<LocalDefId> {
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx UnordSet<LocalDefId> {
     fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
         RefDecodable::decode(d)
     }
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 5d868ebec94..5029c339963 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -58,16 +58,32 @@ pub(crate) enum SuggestionTarget {
 #[derive(Debug)]
 pub(crate) struct TypoSuggestion {
     pub candidate: Symbol,
+    /// The source location where the name is defined; None if the name is not defined
+    /// in source e.g. primitives
+    pub span: Option<Span>,
     pub res: Res,
     pub target: SuggestionTarget,
 }
 
 impl TypoSuggestion {
-    pub(crate) fn typo_from_res(candidate: Symbol, res: Res) -> TypoSuggestion {
-        Self { candidate, res, target: SuggestionTarget::SimilarlyNamed }
+    pub(crate) fn typo_from_ident(ident: Ident, res: Res) -> TypoSuggestion {
+        Self {
+            candidate: ident.name,
+            span: Some(ident.span),
+            res,
+            target: SuggestionTarget::SimilarlyNamed,
+        }
+    }
+    pub(crate) fn typo_from_name(candidate: Symbol, res: Res) -> TypoSuggestion {
+        Self { candidate, span: None, res, target: SuggestionTarget::SimilarlyNamed }
     }
-    pub(crate) fn single_item_from_res(candidate: Symbol, res: Res) -> TypoSuggestion {
-        Self { candidate, res, target: SuggestionTarget::SingleItem }
+    pub(crate) fn single_item_from_ident(ident: Ident, res: Res) -> TypoSuggestion {
+        Self {
+            candidate: ident.name,
+            span: Some(ident.span),
+            res,
+            target: SuggestionTarget::SingleItem,
+        }
     }
 }
 
@@ -490,7 +506,7 @@ impl<'a> Resolver<'a> {
             if let Some(binding) = resolution.borrow().binding {
                 let res = binding.res();
                 if filter_fn(res) && ctxt.map_or(true, |ctxt| ctxt == key.ident.span.ctxt()) {
-                    names.push(TypoSuggestion::typo_from_res(key.ident.name, res));
+                    names.push(TypoSuggestion::typo_from_ident(key.ident, res));
                 }
             }
         }
@@ -1145,7 +1161,7 @@ impl<'a> Resolver<'a> {
                                 .get(&expn_id)
                                 .into_iter()
                                 .flatten()
-                                .map(|ident| TypoSuggestion::typo_from_res(ident.name, res)),
+                                .map(|ident| TypoSuggestion::typo_from_ident(*ident, res)),
                         );
                     }
                 }
@@ -1164,7 +1180,7 @@ impl<'a> Resolver<'a> {
                                 suggestions.extend(
                                     ext.helper_attrs
                                         .iter()
-                                        .map(|name| TypoSuggestion::typo_from_res(*name, res)),
+                                        .map(|name| TypoSuggestion::typo_from_name(*name, res)),
                                 );
                             }
                         }
@@ -1174,8 +1190,8 @@ impl<'a> Resolver<'a> {
                     if let MacroRulesScope::Binding(macro_rules_binding) = macro_rules_scope.get() {
                         let res = macro_rules_binding.binding.res();
                         if filter_fn(res) {
-                            suggestions.push(TypoSuggestion::typo_from_res(
-                                macro_rules_binding.ident.name,
+                            suggestions.push(TypoSuggestion::typo_from_ident(
+                                macro_rules_binding.ident,
                                 res,
                             ))
                         }
@@ -1193,7 +1209,7 @@ impl<'a> Resolver<'a> {
                     suggestions.extend(this.macro_use_prelude.iter().filter_map(
                         |(name, binding)| {
                             let res = binding.res();
-                            filter_fn(res).then_some(TypoSuggestion::typo_from_res(*name, res))
+                            filter_fn(res).then_some(TypoSuggestion::typo_from_name(*name, res))
                         },
                     ));
                 }
@@ -1203,14 +1219,14 @@ impl<'a> Resolver<'a> {
                         suggestions.extend(
                             BUILTIN_ATTRIBUTES
                                 .iter()
-                                .map(|attr| TypoSuggestion::typo_from_res(attr.name, res)),
+                                .map(|attr| TypoSuggestion::typo_from_name(attr.name, res)),
                         );
                     }
                 }
                 Scope::ExternPrelude => {
                     suggestions.extend(this.extern_prelude.iter().filter_map(|(ident, _)| {
                         let res = Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id());
-                        filter_fn(res).then_some(TypoSuggestion::typo_from_res(ident.name, res))
+                        filter_fn(res).then_some(TypoSuggestion::typo_from_ident(*ident, res))
                     }));
                 }
                 Scope::ToolPrelude => {
@@ -1218,7 +1234,7 @@ impl<'a> Resolver<'a> {
                     suggestions.extend(
                         this.registered_tools
                             .iter()
-                            .map(|ident| TypoSuggestion::typo_from_res(ident.name, res)),
+                            .map(|ident| TypoSuggestion::typo_from_ident(*ident, res)),
                     );
                 }
                 Scope::StdLibPrelude => {
@@ -1235,7 +1251,8 @@ impl<'a> Resolver<'a> {
                 Scope::BuiltinTypes => {
                     suggestions.extend(PrimTy::ALL.iter().filter_map(|prim_ty| {
                         let res = Res::PrimTy(*prim_ty);
-                        filter_fn(res).then_some(TypoSuggestion::typo_from_res(prim_ty.name(), res))
+                        filter_fn(res)
+                            .then_some(TypoSuggestion::typo_from_name(prim_ty.name(), res))
                     }))
                 }
             }
diff --git a/compiler/rustc_resolve/src/access_levels.rs b/compiler/rustc_resolve/src/effective_visibilities.rs
index c27b5b0c420..c40669ac95b 100644
--- a/compiler/rustc_resolve/src/access_levels.rs
+++ b/compiler/rustc_resolve/src/effective_visibilities.rs
@@ -6,55 +6,54 @@ use rustc_ast::Crate;
 use rustc_ast::EnumDef;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::def_id::CRATE_DEF_ID;
-use rustc_middle::middle::privacy::AccessLevel;
+use rustc_middle::middle::privacy::Level;
 use rustc_middle::ty::{DefIdTree, Visibility};
 
-pub struct AccessLevelsVisitor<'r, 'a> {
+pub struct EffectiveVisibilitiesVisitor<'r, 'a> {
     r: &'r mut Resolver<'a>,
     changed: bool,
 }
 
-impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
-    /// Fills the `Resolver::access_levels` table with public & exported items
+impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
+    /// Fills the `Resolver::effective_visibilities` table with public & exported items
     /// For now, this doesn't resolve macros (FIXME) and cannot resolve Impl, as we
     /// need access to a TyCtxt for that.
-    pub fn compute_access_levels<'c>(r: &'r mut Resolver<'a>, krate: &'c Crate) {
-        let mut visitor = AccessLevelsVisitor { r, changed: false };
+    pub fn compute_effective_visibilities<'c>(r: &'r mut Resolver<'a>, krate: &'c Crate) {
+        let mut visitor = EffectiveVisibilitiesVisitor { r, changed: false };
 
-        visitor.update(CRATE_DEF_ID, Visibility::Public, CRATE_DEF_ID, AccessLevel::Public);
-        visitor.set_bindings_access_level(CRATE_DEF_ID);
+        visitor.update(CRATE_DEF_ID, Visibility::Public, CRATE_DEF_ID, Level::Direct);
+        visitor.set_bindings_effective_visibilities(CRATE_DEF_ID);
 
         while visitor.changed {
             visitor.reset();
             visit::walk_crate(&mut visitor, krate);
         }
 
-        info!("resolve::access_levels: {:#?}", r.access_levels);
+        info!("resolve::effective_visibilities: {:#?}", r.effective_visibilities);
     }
 
     fn reset(&mut self) {
         self.changed = false;
     }
 
-    /// Update the access level of the bindings in the given module accordingly. The module access
-    /// level has to be Exported or Public.
-    /// This will also follow `use` chains (see PrivacyVisitor::set_import_binding_access_level).
-    fn set_bindings_access_level(&mut self, module_id: LocalDefId) {
+    /// Update effective visibilities of bindings in the given module,
+    /// including their whole reexport chains.
+    fn set_bindings_effective_visibilities(&mut self, module_id: LocalDefId) {
         assert!(self.r.module_map.contains_key(&&module_id.to_def_id()));
         let module = self.r.get_module(module_id.to_def_id()).unwrap();
         let resolutions = self.r.resolutions(module);
 
         for (_, name_resolution) in resolutions.borrow().iter() {
             if let Some(mut binding) = name_resolution.borrow().binding() && !binding.is_ambiguity() {
-                // Set the given binding access level to `AccessLevel::Public` and
-                // sets the rest of the `use` chain to `AccessLevel::Exported` until
+                // Set the given effective visibility level to `Level::Direct` and
+                // sets the rest of the `use` chain to `Level::Reexported` until
                 // we hit the actual exported item.
 
                 // FIXME: tag and is_public() condition should be removed, but assertions occur.
-                let tag = if binding.is_import() { AccessLevel::Exported } else { AccessLevel::Public };
+                let tag = if binding.is_import() { Level::Reexported } else { Level::Direct };
                 if binding.vis.is_public() {
                     let mut prev_parent_id = module_id;
-                    let mut level = AccessLevel::Public;
+                    let mut level = Level::Direct;
                     while let NameBindingKind::Import { binding: nested_binding, import, .. } =
                         binding.kind
                     {
@@ -76,7 +75,7 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
                             update(additional_ids.1);
                         }
 
-                        level = AccessLevel::Exported;
+                        level = Level::Reexported;
                         prev_parent_id = self.r.local_def_id(import.id);
                         binding = nested_binding;
                     }
@@ -94,7 +93,7 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
         def_id: LocalDefId,
         nominal_vis: Visibility,
         parent_id: LocalDefId,
-        tag: AccessLevel,
+        tag: Level,
     ) {
         let module_id = self
             .r
@@ -106,8 +105,8 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
         {
             return;
         }
-        let mut access_levels = std::mem::take(&mut self.r.access_levels);
-        self.changed |= access_levels.update(
+        let mut effective_visibilities = std::mem::take(&mut self.r.effective_visibilities);
+        self.changed |= effective_visibilities.update(
             def_id,
             nominal_vis,
             || Visibility::Restricted(module_id),
@@ -115,14 +114,14 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
             tag,
             &*self.r,
         );
-        self.r.access_levels = access_levels;
+        self.r.effective_visibilities = effective_visibilities;
     }
 }
 
-impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> {
+impl<'r, 'ast> Visitor<'ast> for EffectiveVisibilitiesVisitor<'ast, 'r> {
     fn visit_item(&mut self, item: &'ast ast::Item) {
         let def_id = self.r.local_def_id(item.id);
-        // Set access level of nested items.
+        // Update effective visibilities of nested items.
         // If it's a mod, also make the visitor walk all of its items
         match item.kind {
             // Resolved in rustc_privacy when types are available
@@ -136,29 +135,29 @@ impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> {
             // Foreign modules inherit level from parents.
             ast::ItemKind::ForeignMod(..) => {
                 let parent_id = self.r.local_parent(def_id);
-                self.update(def_id, Visibility::Public, parent_id, AccessLevel::Public);
+                self.update(def_id, Visibility::Public, parent_id, Level::Direct);
             }
 
             // Only exported `macro_rules!` items are public, but they always are
             ast::ItemKind::MacroDef(ref macro_def) if macro_def.macro_rules => {
                 let parent_id = self.r.local_parent(def_id);
                 let vis = self.r.visibilities[&def_id];
-                self.update(def_id, vis, parent_id, AccessLevel::Public);
+                self.update(def_id, vis, parent_id, Level::Direct);
             }
 
             ast::ItemKind::Mod(..) => {
-                self.set_bindings_access_level(def_id);
+                self.set_bindings_effective_visibilities(def_id);
                 visit::walk_item(self, item);
             }
 
             ast::ItemKind::Enum(EnumDef { ref variants }, _) => {
-                self.set_bindings_access_level(def_id);
+                self.set_bindings_effective_visibilities(def_id);
                 for variant in variants {
                     let variant_def_id = self.r.local_def_id(variant.id);
                     for field in variant.data.fields() {
                         let field_def_id = self.r.local_def_id(field.id);
                         let vis = self.r.visibilities[&field_def_id];
-                        self.update(field_def_id, vis, variant_def_id, AccessLevel::Public);
+                        self.update(field_def_id, vis, variant_def_id, Level::Direct);
                     }
                 }
             }
@@ -167,12 +166,12 @@ impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> {
                 for field in def.fields() {
                     let field_def_id = self.r.local_def_id(field.id);
                     let vis = self.r.visibilities[&field_def_id];
-                    self.update(field_def_id, vis, def_id, AccessLevel::Public);
+                    self.update(field_def_id, vis, def_id, Level::Direct);
                 }
             }
 
             ast::ItemKind::Trait(..) => {
-                self.set_bindings_access_level(def_id);
+                self.set_bindings_effective_visibilities(def_id);
             }
 
             ast::ItemKind::ExternCrate(..)
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 58853346a92..00eb768ad18 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -30,6 +30,7 @@ use rustc_span::{BytePos, Span};
 use smallvec::{smallvec, SmallVec};
 
 use rustc_span::source_map::{respan, Spanned};
+use std::assert_matches::debug_assert_matches;
 use std::collections::{hash_map::Entry, BTreeSet};
 use std::mem::{replace, take};
 
@@ -568,7 +569,7 @@ struct LateResolutionVisitor<'a, 'b, 'ast> {
     /// They will be used to determine the correct lifetime for the fn return type.
     /// The `LifetimeElisionCandidate` is used for diagnostics, to suggest introducing named
     /// lifetimes.
-    lifetime_elision_candidates: Option<FxIndexMap<LifetimeRes, LifetimeElisionCandidate>>,
+    lifetime_elision_candidates: Option<Vec<(LifetimeRes, LifetimeElisionCandidate)>>,
 
     /// The trait that the current context can refer to.
     current_trait_ref: Option<(Module<'a>, TraitRef)>,
@@ -1802,7 +1803,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         match res {
             LifetimeRes::Param { .. } | LifetimeRes::Fresh { .. } | LifetimeRes::Static => {
                 if let Some(ref mut candidates) = self.lifetime_elision_candidates {
-                    candidates.insert(res, candidate);
+                    candidates.push((res, candidate));
                 }
             }
             LifetimeRes::Infer | LifetimeRes::Error | LifetimeRes::ElidedAnchor { .. } => {}
@@ -1855,12 +1856,25 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         has_self: bool,
         inputs: impl Iterator<Item = (Option<&'ast Pat>, &'ast Ty)>,
     ) -> Result<LifetimeRes, (Vec<MissingLifetime>, Vec<ElisionFnParameter>)> {
-        let outer_candidates =
-            replace(&mut self.lifetime_elision_candidates, Some(Default::default()));
+        enum Elision {
+            /// We have not found any candidate.
+            None,
+            /// We have a candidate bound to `self`.
+            Self_(LifetimeRes),
+            /// We have a candidate bound to a parameter.
+            Param(LifetimeRes),
+            /// We failed elision.
+            Err,
+        }
 
-        let mut elision_lifetime = None;
-        let mut lifetime_count = 0;
+        // Save elision state to reinstate it later.
+        let outer_candidates = self.lifetime_elision_candidates.take();
+
+        // Result of elision.
+        let mut elision_lifetime = Elision::None;
+        // Information for diagnostics.
         let mut parameter_info = Vec::new();
+        let mut all_candidates = Vec::new();
 
         let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
         for (index, (pat, ty)) in inputs.enumerate() {
@@ -1870,12 +1884,17 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     this.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
                 }
             });
+
+            // Record elision candidates only for this parameter.
+            debug_assert_matches!(self.lifetime_elision_candidates, None);
+            self.lifetime_elision_candidates = Some(Default::default());
             self.visit_ty(ty);
+            let local_candidates = self.lifetime_elision_candidates.take();
 
-            if let Some(ref candidates) = self.lifetime_elision_candidates {
-                let new_count = candidates.len();
-                let local_count = new_count - lifetime_count;
-                if local_count != 0 {
+            if let Some(candidates) = local_candidates {
+                let distinct: FxHashSet<_> = candidates.iter().map(|(res, _)| *res).collect();
+                let lifetime_count = distinct.len();
+                if lifetime_count != 0 {
                     parameter_info.push(ElisionFnParameter {
                         index,
                         ident: if let Some(pat) = pat && let PatKind::Ident(_, ident, _) = pat.kind {
@@ -1883,48 +1902,64 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                         } else {
                             None
                         },
-                        lifetime_count: local_count,
+                        lifetime_count,
                         span: ty.span,
                     });
+                    all_candidates.extend(candidates.into_iter().filter_map(|(_, candidate)| {
+                        match candidate {
+                            LifetimeElisionCandidate::Ignore | LifetimeElisionCandidate::Named => {
+                                None
+                            }
+                            LifetimeElisionCandidate::Missing(missing) => Some(missing),
+                        }
+                    }));
+                }
+                let mut distinct_iter = distinct.into_iter();
+                if let Some(res) = distinct_iter.next() {
+                    match elision_lifetime {
+                        // We are the first parameter to bind lifetimes.
+                        Elision::None => {
+                            if distinct_iter.next().is_none() {
+                                // We have a single lifetime => success.
+                                elision_lifetime = Elision::Param(res)
+                            } else {
+                                // We have have multiple lifetimes => error.
+                                elision_lifetime = Elision::Err;
+                            }
+                        }
+                        // We have 2 parameters that bind lifetimes => error.
+                        Elision::Param(_) => elision_lifetime = Elision::Err,
+                        // `self` elision takes precedence over everything else.
+                        Elision::Self_(_) | Elision::Err => {}
+                    }
                 }
-                lifetime_count = new_count;
             }
 
             // Handle `self` specially.
             if index == 0 && has_self {
                 let self_lifetime = self.find_lifetime_for_self(ty);
                 if let Set1::One(lifetime) = self_lifetime {
-                    elision_lifetime = Some(lifetime);
-                    self.lifetime_elision_candidates = None;
+                    // We found `self` elision.
+                    elision_lifetime = Elision::Self_(lifetime);
                 } else {
-                    self.lifetime_elision_candidates = Some(Default::default());
-                    lifetime_count = 0;
+                    // We do not have `self` elision: disregard the `Elision::Param` that we may
+                    // have found.
+                    elision_lifetime = Elision::None;
                 }
             }
             debug!("(resolving function / closure) recorded parameter");
         }
 
-        let all_candidates = replace(&mut self.lifetime_elision_candidates, outer_candidates);
-        debug!(?all_candidates);
+        // Reinstate elision state.
+        debug_assert_matches!(self.lifetime_elision_candidates, None);
+        self.lifetime_elision_candidates = outer_candidates;
 
-        if let Some(res) = elision_lifetime {
+        if let Elision::Param(res) | Elision::Self_(res) = elision_lifetime {
             return Ok(res);
         }
 
-        // We do not have a `self` candidate, look at the full list.
-        let all_candidates = all_candidates.unwrap();
-        if all_candidates.len() == 1 {
-            Ok(*all_candidates.first().unwrap().0)
-        } else {
-            let all_candidates = all_candidates
-                .into_iter()
-                .filter_map(|(_, candidate)| match candidate {
-                    LifetimeElisionCandidate::Ignore | LifetimeElisionCandidate::Named => None,
-                    LifetimeElisionCandidate::Missing(missing) => Some(missing),
-                })
-                .collect();
-            Err((all_candidates, parameter_info))
-        }
+        // We do not have a candidate.
+        Err((all_candidates, parameter_info))
     }
 
     /// List all the lifetimes that appear in the provided type.
@@ -2394,7 +2429,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         // Do not account for the parameters we just bound for function lifetime elision.
         if let Some(ref mut candidates) = self.lifetime_elision_candidates {
             for (_, res) in function_lifetime_rib.bindings.values() {
-                candidates.remove(res);
+                candidates.retain(|(r, _)| r != res);
             }
         }
 
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 850f023b1c1..103187b00d1 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -150,7 +150,7 @@ struct BaseError {
 #[derive(Debug)]
 enum TypoCandidate {
     Typo(TypoSuggestion),
-    Shadowed(Res),
+    Shadowed(Res, Option<Span>),
     None,
 }
 
@@ -158,7 +158,7 @@ impl TypoCandidate {
     fn to_opt_suggestion(self) -> Option<TypoSuggestion> {
         match self {
             TypoCandidate::Typo(sugg) => Some(sugg),
-            TypoCandidate::Shadowed(_) | TypoCandidate::None => None,
+            TypoCandidate::Shadowed(_, _) | TypoCandidate::None => None,
         }
     }
 }
@@ -691,9 +691,20 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
         let is_expected = &|res| source.is_expected(res);
         let ident_span = path.last().map_or(span, |ident| ident.ident.span);
         let typo_sugg = self.lookup_typo_candidate(path, source.namespace(), is_expected);
-        if let TypoCandidate::Shadowed(res) = typo_sugg
-            && let Some(id) = res.opt_def_id()
-            && let Some(sugg_span) = self.r.opt_span(id)
+        let is_in_same_file = &|sp1, sp2| {
+            let source_map = self.r.session.source_map();
+            let file1 = source_map.span_to_filename(sp1);
+            let file2 = source_map.span_to_filename(sp2);
+            file1 == file2
+        };
+        // print 'you might have meant' if the candidate is (1) is a shadowed name with
+        // accessible definition and (2) either defined in the same crate as the typo
+        // (could be in a different file) or introduced in the same file as the typo
+        // (could belong to a different crate)
+        if let TypoCandidate::Shadowed(res, Some(sugg_span)) = typo_sugg
+            && res
+                .opt_def_id()
+                .map_or(false, |id| id.is_local() || is_in_same_file(span, sugg_span))
         {
             err.span_label(
                 sugg_span,
@@ -784,10 +795,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
             return false;
         }
         err.code(rustc_errors::error_code!(E0411));
-        err.span_label(
-            span,
-            "`Self` is only available in impls, traits, and type definitions".to_string(),
-        );
+        err.span_label(span, "`Self` is only available in impls, traits, and type definitions");
         if let Some(item_kind) = self.diagnostic_metadata.current_item {
             err.span_label(
                 item_kind.ident.span,
@@ -973,10 +981,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                         .collect();
                 if targets.len() == 1 {
                     let target = targets[0];
-                    return Some(TypoSuggestion::single_item_from_res(
-                        target.0.ident.name,
-                        target.1,
-                    ));
+                    return Some(TypoSuggestion::single_item_from_ident(target.0.ident, target.1));
                 }
             }
         }
@@ -1618,7 +1623,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                 // Locals and type parameters
                 for (ident, &res) in &rib.bindings {
                     if filter_fn(res) && ident.span.ctxt() == rib_ctxt {
-                        names.push(TypoSuggestion::typo_from_res(ident.name, res));
+                        names.push(TypoSuggestion::typo_from_ident(*ident, res));
                     }
                 }
 
@@ -1647,9 +1652,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                                             Res::Def(DefKind::Mod, crate_id.as_def_id());
 
                                         if filter_fn(crate_mod) {
-                                            Some(TypoSuggestion::typo_from_res(
-                                                ident.name, crate_mod,
-                                            ))
+                                            Some(TypoSuggestion::typo_from_ident(*ident, crate_mod))
                                         } else {
                                             None
                                         }
@@ -1668,7 +1671,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
             // Add primitive types to the mix
             if filter_fn(Res::PrimTy(PrimTy::Bool)) {
                 names.extend(PrimTy::ALL.iter().map(|prim_ty| {
-                    TypoSuggestion::typo_from_res(prim_ty.name(), Res::PrimTy(*prim_ty))
+                    TypoSuggestion::typo_from_name(prim_ty.name(), Res::PrimTy(*prim_ty))
                 }))
             }
         } else {
@@ -1695,7 +1698,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                     return TypoCandidate::None;
                 };
                 if found == name {
-                    TypoCandidate::Shadowed(sugg.res)
+                    TypoCandidate::Shadowed(sugg.res, sugg.span)
                 } else {
                     TypoCandidate::Typo(sugg)
                 }
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index c2213e8d1e2..11b70a38da5 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -7,6 +7,7 @@
 //! Type-relative name resolution (methods, fields, associated items) happens in `rustc_hir_analysis`.
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
+#![feature(assert_matches)]
 #![feature(box_patterns)]
 #![feature(drain_filter)]
 #![feature(if_let_guard)]
@@ -40,7 +41,7 @@ use rustc_hir::TraitCandidate;
 use rustc_index::vec::IndexVec;
 use rustc_metadata::creader::{CStore, CrateLoader};
 use rustc_middle::metadata::ModChild;
-use rustc_middle::middle::privacy::AccessLevels;
+use rustc_middle::middle::privacy::EffectiveVisibilities;
 use rustc_middle::span_bug;
 use rustc_middle::ty::{self, DefIdTree, MainDefinition, RegisteredTools};
 use rustc_middle::ty::{ResolverGlobalCtxt, ResolverOutputs};
@@ -63,15 +64,15 @@ use imports::{Import, ImportKind, ImportResolver, NameResolution};
 use late::{HasGenericParams, PathSource, PatternSource};
 use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
 
-use crate::access_levels::AccessLevelsVisitor;
+use crate::effective_visibilities::EffectiveVisibilitiesVisitor;
 
 type Res = def::Res<NodeId>;
 
-mod access_levels;
 mod build_reduced_graph;
 mod check_unused;
 mod def_collector;
 mod diagnostics;
+mod effective_visibilities;
 mod ident;
 mod imports;
 mod late;
@@ -1030,7 +1031,7 @@ pub struct Resolver<'a> {
     proc_macros: Vec<NodeId>,
     confused_type_with_std_module: FxHashMap<Span, Span>,
 
-    access_levels: AccessLevels,
+    effective_visibilities: EffectiveVisibilities,
 }
 
 /// Nothing really interesting here; it just provides memory for the rest of the crate.
@@ -1334,7 +1335,7 @@ impl<'a> Resolver<'a> {
             trait_impls: Default::default(),
             proc_macros: Default::default(),
             confused_type_with_std_module: Default::default(),
-            access_levels: Default::default(),
+            effective_visibilities: Default::default(),
         };
 
         let root_parent_scope = ParentScope::module(graph_root, &resolver);
@@ -1392,14 +1393,14 @@ impl<'a> Resolver<'a> {
         let glob_map = self.glob_map;
         let main_def = self.main_def;
         let confused_type_with_std_module = self.confused_type_with_std_module;
-        let access_levels = self.access_levels;
+        let effective_visibilities = self.effective_visibilities;
         let global_ctxt = ResolverGlobalCtxt {
             cstore,
             source_span,
             expn_that_defined,
             visibilities,
             has_pub_restricted,
-            access_levels,
+            effective_visibilities,
             extern_crate_map,
             reexport_map,
             glob_map,
@@ -1457,7 +1458,7 @@ impl<'a> Resolver<'a> {
             proc_macros,
             confused_type_with_std_module: self.confused_type_with_std_module.clone(),
             registered_tools: self.registered_tools.clone(),
-            access_levels: self.access_levels.clone(),
+            effective_visibilities: self.effective_visibilities.clone(),
         };
         let ast_lowering = ty::ResolverAstLowering {
             legacy_const_generic_args: self.legacy_const_generic_args.clone(),
@@ -1520,8 +1521,8 @@ impl<'a> Resolver<'a> {
     pub fn resolve_crate(&mut self, krate: &Crate) {
         self.session.time("resolve_crate", || {
             self.session.time("finalize_imports", || ImportResolver { r: self }.finalize_imports());
-            self.session.time("resolve_access_levels", || {
-                AccessLevelsVisitor::compute_access_levels(self, krate)
+            self.session.time("compute_effective_visibilities", || {
+                EffectiveVisibilitiesVisitor::compute_effective_visibilities(self, krate)
             });
             self.session.time("finalize_macro_resolutions", || self.finalize_macro_resolutions());
             self.session.time("late_resolve_crate", || self.late_resolve_crate(krate));
diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs
index 23d06d8e516..df5d992f663 100644
--- a/compiler/rustc_save_analysis/src/dump_visitor.rs
+++ b/compiler/rustc_save_analysis/src/dump_visitor.rs
@@ -57,7 +57,7 @@ macro_rules! access_from {
     ($save_ctxt:expr, $id:expr) => {
         Access {
             public: $save_ctxt.tcx.visibility($id).is_public(),
-            reachable: $save_ctxt.access_levels.is_reachable($id),
+            reachable: $save_ctxt.effective_visibilities.is_reachable($id),
         }
     };
 }
@@ -345,14 +345,14 @@ impl<'tcx> DumpVisitor<'tcx> {
         body: hir::BodyId,
     ) {
         let map = self.tcx.hir();
-        self.nest_typeck_results(item.def_id.def_id, |v| {
+        self.nest_typeck_results(item.owner_id.def_id, |v| {
             let body = map.body(body);
             if let Some(fn_data) = v.save_ctxt.get_item_data(item) {
                 down_cast_data!(fn_data, DefData, item.span);
                 v.process_formals(body.params, &fn_data.qualname);
                 v.process_generic_params(ty_params, &fn_data.qualname, item.hir_id());
 
-                v.dumper.dump_def(&access_from!(v.save_ctxt, item.def_id.def_id), fn_data);
+                v.dumper.dump_def(&access_from!(v.save_ctxt, item.owner_id.def_id), fn_data);
             }
 
             for arg in decl.inputs {
@@ -373,10 +373,10 @@ impl<'tcx> DumpVisitor<'tcx> {
         typ: &'tcx hir::Ty<'tcx>,
         expr: &'tcx hir::Expr<'tcx>,
     ) {
-        self.nest_typeck_results(item.def_id.def_id, |v| {
+        self.nest_typeck_results(item.owner_id.def_id, |v| {
             if let Some(var_data) = v.save_ctxt.get_item_data(item) {
                 down_cast_data!(var_data, DefData, item.span);
-                v.dumper.dump_def(&access_from!(v.save_ctxt, item.def_id.def_id), var_data);
+                v.dumper.dump_def(&access_from!(v.save_ctxt, item.owner_id.def_id), var_data);
             }
             v.visit_ty(&typ);
             v.visit_expr(expr);
@@ -436,7 +436,7 @@ impl<'tcx> DumpVisitor<'tcx> {
     ) {
         debug!("process_struct {:?} {:?}", item, item.span);
         let name = item.ident.to_string();
-        let qualname = format!("::{}", self.tcx.def_path_str(item.def_id.to_def_id()));
+        let qualname = format!("::{}", self.tcx.def_path_str(item.owner_id.to_def_id()));
 
         let kind = match item.kind {
             hir::ItemKind::Struct(_, _) => DefKind::Struct,
@@ -473,10 +473,10 @@ impl<'tcx> DumpVisitor<'tcx> {
             let span = self.span_from_span(item.ident.span);
             let attrs = self.tcx.hir().attrs(item.hir_id());
             self.dumper.dump_def(
-                &access_from!(self.save_ctxt, item.def_id.def_id),
+                &access_from!(self.save_ctxt, item.owner_id.def_id),
                 Def {
                     kind,
-                    id: id_from_def_id(item.def_id.to_def_id()),
+                    id: id_from_def_id(item.owner_id.to_def_id()),
                     span,
                     name,
                     qualname: qualname.clone(),
@@ -491,7 +491,7 @@ impl<'tcx> DumpVisitor<'tcx> {
             );
         }
 
-        self.nest_typeck_results(item.def_id.def_id, |v| {
+        self.nest_typeck_results(item.owner_id.def_id, |v| {
             for field in def.fields() {
                 v.process_struct_field_def(field, item.hir_id());
                 v.visit_ty(&field.ty);
@@ -513,7 +513,7 @@ impl<'tcx> DumpVisitor<'tcx> {
         };
         down_cast_data!(enum_data, DefData, item.span);
 
-        let access = access_from!(self.save_ctxt, item.def_id.def_id);
+        let access = access_from!(self.save_ctxt, item.owner_id.def_id);
 
         for variant in enum_definition.variants {
             let name = variant.ident.name.to_string();
@@ -528,7 +528,7 @@ impl<'tcx> DumpVisitor<'tcx> {
                     if !self.span.filter_generated(name_span) {
                         let span = self.span_from_span(name_span);
                         let id = id_from_hir_id(variant.id, &self.save_ctxt);
-                        let parent = Some(id_from_def_id(item.def_id.to_def_id()));
+                        let parent = Some(id_from_def_id(item.owner_id.to_def_id()));
                         let attrs = self.tcx.hir().attrs(variant.id);
 
                         self.dumper.dump_def(
@@ -566,7 +566,7 @@ impl<'tcx> DumpVisitor<'tcx> {
                     if !self.span.filter_generated(name_span) {
                         let span = self.span_from_span(name_span);
                         let id = id_from_hir_id(variant.id, &self.save_ctxt);
-                        let parent = Some(id_from_def_id(item.def_id.to_def_id()));
+                        let parent = Some(id_from_def_id(item.owner_id.to_def_id()));
                         let attrs = self.tcx.hir().attrs(variant.id);
 
                         self.dumper.dump_def(
@@ -612,14 +612,14 @@ impl<'tcx> DumpVisitor<'tcx> {
         }
 
         let map = self.tcx.hir();
-        self.nest_typeck_results(item.def_id.def_id, |v| {
+        self.nest_typeck_results(item.owner_id.def_id, |v| {
             v.visit_ty(&impl_.self_ty);
             if let Some(trait_ref) = &impl_.of_trait {
                 v.process_path(trait_ref.hir_ref_id, &hir::QPath::Resolved(None, &trait_ref.path));
             }
             v.process_generic_params(&impl_.generics, "", item.hir_id());
             for impl_item in impl_.items {
-                v.process_impl_item(map.impl_item(impl_item.id), item.def_id.to_def_id());
+                v.process_impl_item(map.impl_item(impl_item.id), item.owner_id.to_def_id());
             }
         });
     }
@@ -632,7 +632,7 @@ impl<'tcx> DumpVisitor<'tcx> {
         methods: &'tcx [hir::TraitItemRef],
     ) {
         let name = item.ident.to_string();
-        let qualname = format!("::{}", self.tcx.def_path_str(item.def_id.to_def_id()));
+        let qualname = format!("::{}", self.tcx.def_path_str(item.owner_id.to_def_id()));
         let mut val = name.clone();
         if !generics.params.is_empty() {
             val.push_str(&generic_params_to_string(generics.params));
@@ -642,13 +642,13 @@ impl<'tcx> DumpVisitor<'tcx> {
             val.push_str(&bounds_to_string(trait_refs));
         }
         if !self.span.filter_generated(item.ident.span) {
-            let id = id_from_def_id(item.def_id.to_def_id());
+            let id = id_from_def_id(item.owner_id.to_def_id());
             let span = self.span_from_span(item.ident.span);
             let children =
-                methods.iter().map(|i| id_from_def_id(i.id.def_id.to_def_id())).collect();
+                methods.iter().map(|i| id_from_def_id(i.id.owner_id.to_def_id())).collect();
             let attrs = self.tcx.hir().attrs(item.hir_id());
             self.dumper.dump_def(
-                &access_from!(self.save_ctxt, item.def_id.def_id),
+                &access_from!(self.save_ctxt, item.owner_id.def_id),
                 Def {
                     kind: DefKind::Trait,
                     id,
@@ -692,7 +692,7 @@ impl<'tcx> DumpVisitor<'tcx> {
                         kind: RelationKind::SuperTrait,
                         span,
                         from: id_from_def_id(id),
-                        to: id_from_def_id(item.def_id.to_def_id()),
+                        to: id_from_def_id(item.owner_id.to_def_id()),
                     });
                 }
             }
@@ -702,7 +702,7 @@ impl<'tcx> DumpVisitor<'tcx> {
         self.process_generic_params(generics, &qualname, item.hir_id());
         for method in methods {
             let map = self.tcx.hir();
-            self.process_trait_item(map.trait_item(method.id), item.def_id.to_def_id())
+            self.process_trait_item(map.trait_item(method.id), item.owner_id.to_def_id())
         }
     }
 
@@ -710,7 +710,7 @@ impl<'tcx> DumpVisitor<'tcx> {
     fn process_mod(&mut self, item: &'tcx hir::Item<'tcx>) {
         if let Some(mod_data) = self.save_ctxt.get_item_data(item) {
             down_cast_data!(mod_data, DefData, item.span);
-            self.dumper.dump_def(&access_from!(self.save_ctxt, item.def_id.def_id), mod_data);
+            self.dumper.dump_def(&access_from!(self.save_ctxt, item.owner_id.def_id), mod_data);
         }
     }
 
@@ -981,7 +981,7 @@ impl<'tcx> DumpVisitor<'tcx> {
                 let body = body.map(|b| self.tcx.hir().body(b).value);
                 let attrs = self.tcx.hir().attrs(trait_item.hir_id());
                 self.process_assoc_const(
-                    trait_item.def_id.def_id,
+                    trait_item.owner_id.def_id,
                     trait_item.ident,
                     &ty,
                     body,
@@ -995,7 +995,7 @@ impl<'tcx> DumpVisitor<'tcx> {
                 self.process_method(
                     sig,
                     body,
-                    trait_item.def_id.def_id,
+                    trait_item.owner_id.def_id,
                     trait_item.ident,
                     &trait_item.generics,
                     trait_item.span,
@@ -1005,11 +1005,11 @@ impl<'tcx> DumpVisitor<'tcx> {
                 // FIXME do something with _bounds (for type refs)
                 let name = trait_item.ident.name.to_string();
                 let qualname =
-                    format!("::{}", self.tcx.def_path_str(trait_item.def_id.to_def_id()));
+                    format!("::{}", self.tcx.def_path_str(trait_item.owner_id.to_def_id()));
 
                 if !self.span.filter_generated(trait_item.ident.span) {
                     let span = self.span_from_span(trait_item.ident.span);
-                    let id = id_from_def_id(trait_item.def_id.to_def_id());
+                    let id = id_from_def_id(trait_item.owner_id.to_def_id());
                     let attrs = self.tcx.hir().attrs(trait_item.hir_id());
 
                     self.dumper.dump_def(
@@ -1051,7 +1051,7 @@ impl<'tcx> DumpVisitor<'tcx> {
                 let body = self.tcx.hir().body(body);
                 let attrs = self.tcx.hir().attrs(impl_item.hir_id());
                 self.process_assoc_const(
-                    impl_item.def_id.def_id,
+                    impl_item.owner_id.def_id,
                     impl_item.ident,
                     &ty,
                     Some(&body.value),
@@ -1063,7 +1063,7 @@ impl<'tcx> DumpVisitor<'tcx> {
                 self.process_method(
                     sig,
                     Some(body),
-                    impl_item.def_id.def_id,
+                    impl_item.owner_id.def_id,
                     impl_item.ident,
                     &impl_item.generics,
                     impl_item.span,
@@ -1088,7 +1088,7 @@ impl<'tcx> DumpVisitor<'tcx> {
         let filename = sm.span_to_filename(krate_mod.spans.inner_span);
         let data_id = id_from_hir_id(id, &self.save_ctxt);
         let children =
-            krate_mod.item_ids.iter().map(|i| id_from_def_id(i.def_id.to_def_id())).collect();
+            krate_mod.item_ids.iter().map(|i| id_from_def_id(i.owner_id.to_def_id())).collect();
         let span = self.span_from_span(krate_mod.spans.inner_span);
         let attrs = self.tcx.hir().attrs(id);
 
@@ -1137,10 +1137,10 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
             hir::ItemKind::Use(path, hir::UseKind::Single) => {
                 let sub_span = path.segments.last().unwrap().ident.span;
                 if !self.span.filter_generated(sub_span) {
-                    let access = access_from!(self.save_ctxt, item.def_id.def_id);
+                    let access = access_from!(self.save_ctxt, item.owner_id.def_id);
                     let ref_id = self.lookup_def_id(item.hir_id()).map(id_from_def_id);
                     let span = self.span_from_span(sub_span);
-                    let parent = self.save_ctxt.tcx.local_parent(item.def_id.def_id);
+                    let parent = self.save_ctxt.tcx.local_parent(item.owner_id.def_id);
                     self.dumper.import(
                         &access,
                         Import {
@@ -1158,16 +1158,16 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
             }
             hir::ItemKind::Use(path, hir::UseKind::Glob) => {
                 // Make a comma-separated list of names of imported modules.
-                let names = self.tcx.names_imported_by_glob_use(item.def_id.def_id);
+                let names = self.tcx.names_imported_by_glob_use(item.owner_id.def_id);
                 let names: Vec<_> = names.iter().map(|n| n.to_string()).collect();
 
                 // Otherwise it's a span with wrong macro expansion info, which
                 // we don't want to track anyway, since it's probably macro-internal `use`
                 if let Some(sub_span) = self.span.sub_span_of_star(item.span) {
                     if !self.span.filter_generated(item.span) {
-                        let access = access_from!(self.save_ctxt, item.def_id.def_id);
+                        let access = access_from!(self.save_ctxt, item.owner_id.def_id);
                         let span = self.span_from_span(sub_span);
-                        let parent = self.save_ctxt.tcx.local_parent(item.def_id.def_id);
+                        let parent = self.save_ctxt.tcx.local_parent(item.owner_id.def_id);
                         self.dumper.import(
                             &access,
                             Import {
@@ -1188,7 +1188,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
                 let name_span = item.ident.span;
                 if !self.span.filter_generated(name_span) {
                     let span = self.span_from_span(name_span);
-                    let parent = self.save_ctxt.tcx.local_parent(item.def_id.def_id);
+                    let parent = self.save_ctxt.tcx.local_parent(item.owner_id.def_id);
                     self.dumper.import(
                         &Access { public: false, reachable: false },
                         Import {
@@ -1228,15 +1228,15 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
                 intravisit::walk_mod(self, m, item.hir_id());
             }
             hir::ItemKind::TyAlias(ty, ref generics) => {
-                let qualname = format!("::{}", self.tcx.def_path_str(item.def_id.to_def_id()));
+                let qualname = format!("::{}", self.tcx.def_path_str(item.owner_id.to_def_id()));
                 let value = ty_to_string(&ty);
                 if !self.span.filter_generated(item.ident.span) {
                     let span = self.span_from_span(item.ident.span);
-                    let id = id_from_def_id(item.def_id.to_def_id());
+                    let id = id_from_def_id(item.owner_id.to_def_id());
                     let attrs = self.tcx.hir().attrs(item.hir_id());
 
                     self.dumper.dump_def(
-                        &access_from!(self.save_ctxt, item.def_id.def_id),
+                        &access_from!(self.save_ctxt, item.owner_id.def_id),
                         Def {
                             kind: DefKind::Type,
                             id,
@@ -1324,7 +1324,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
             }
             hir::TyKind::OpaqueDef(item_id, _, _) => {
                 let item = self.tcx.hir().item(item_id);
-                self.nest_typeck_results(item_id.def_id.def_id, |v| v.visit_item(item));
+                self.nest_typeck_results(item_id.owner_id.def_id, |v| v.visit_item(item));
             }
             _ => intravisit::walk_ty(self, t),
         }
@@ -1431,7 +1431,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
     }
 
     fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
-        let access = access_from!(self.save_ctxt, item.def_id.def_id);
+        let access = access_from!(self.save_ctxt, item.owner_id.def_id);
 
         match item.kind {
             hir::ForeignItemKind::Fn(decl, _, ref generics) => {
diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs
index aa000b7067b..d0155c908a2 100644
--- a/compiler/rustc_save_analysis/src/lib.rs
+++ b/compiler/rustc_save_analysis/src/lib.rs
@@ -26,7 +26,7 @@ use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::Node;
 use rustc_hir_pretty::{enum_def_to_string, fn_to_string, ty_to_string};
 use rustc_middle::hir::nested_filter;
-use rustc_middle::middle::privacy::AccessLevels;
+use rustc_middle::middle::privacy::EffectiveVisibilities;
 use rustc_middle::ty::{self, print::with_no_trimmed_paths, DefIdTree, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_session::config::{CrateType, Input, OutputType};
@@ -54,7 +54,7 @@ use rls_data::{
 pub struct SaveContext<'tcx> {
     tcx: TyCtxt<'tcx>,
     maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
-    access_levels: &'tcx AccessLevels,
+    effective_visibilities: &'tcx EffectiveVisibilities,
     span_utils: SpanUtils<'tcx>,
     config: Config,
     impl_counter: Cell<u32>,
@@ -141,7 +141,7 @@ impl<'tcx> SaveContext<'tcx> {
     }
 
     pub fn get_extern_item_data(&self, item: &hir::ForeignItem<'_>) -> Option<Data> {
-        let def_id = item.def_id.to_def_id();
+        let def_id = item.owner_id.to_def_id();
         let qualname = format!("::{}", self.tcx.def_path_str(def_id));
         let attrs = self.tcx.hir().attrs(item.hir_id());
         match item.kind {
@@ -205,7 +205,7 @@ impl<'tcx> SaveContext<'tcx> {
     }
 
     pub fn get_item_data(&self, item: &hir::Item<'_>) -> Option<Data> {
-        let def_id = item.def_id.to_def_id();
+        let def_id = item.owner_id.to_def_id();
         let attrs = self.tcx.hir().attrs(item.hir_id());
         match item.kind {
             hir::ItemKind::Fn(ref sig, ref generics, _) => {
@@ -297,7 +297,7 @@ impl<'tcx> SaveContext<'tcx> {
                     children: m
                         .item_ids
                         .iter()
-                        .map(|i| id_from_def_id(i.def_id.to_def_id()))
+                        .map(|i| id_from_def_id(i.owner_id.to_def_id()))
                         .collect(),
                     decl_id: None,
                     docs: self.docs_for_attrs(attrs),
@@ -363,7 +363,7 @@ impl<'tcx> SaveContext<'tcx> {
                             parent: None,
                             children: items
                                 .iter()
-                                .map(|i| id_from_def_id(i.id.def_id.to_def_id()))
+                                .map(|i| id_from_def_id(i.id.owner_id.to_def_id()))
                                 .collect(),
                             docs: String::new(),
                             sig: None,
@@ -968,16 +968,16 @@ pub fn process_crate<'l, 'tcx, H: SaveHandler>(
             info!("Dumping crate {}", cratename);
 
             // Privacy checking must be done outside of type inference; use a
-            // fallback in case the access levels couldn't have been correctly computed.
-            let access_levels = match tcx.sess.compile_status() {
-                Ok(..) => tcx.privacy_access_levels(()),
-                Err(..) => tcx.arena.alloc(AccessLevels::default()),
+            // fallback in case effective visibilities couldn't have been correctly computed.
+            let effective_visibilities = match tcx.sess.compile_status() {
+                Ok(..) => tcx.effective_visibilities(()),
+                Err(..) => tcx.arena.alloc(EffectiveVisibilities::default()),
             };
 
             let save_ctxt = SaveContext {
                 tcx,
                 maybe_typeck_results: None,
-                access_levels: &access_levels,
+                effective_visibilities: &effective_visibilities,
                 span_utils: SpanUtils::new(&tcx.sess),
                 config: find_config(config),
                 impl_counter: Cell::new(0),
diff --git a/compiler/rustc_save_analysis/src/sig.rs b/compiler/rustc_save_analysis/src/sig.rs
index 62e9f6520fb..83c51d213be 100644
--- a/compiler/rustc_save_analysis/src/sig.rs
+++ b/compiler/rustc_save_analysis/src/sig.rs
@@ -337,7 +337,7 @@ impl<'hir> Sig for hir::Item<'hir> {
                 }
                 let name = self.ident.to_string();
                 let defs = vec![SigElement {
-                    id: id_from_def_id(self.def_id.to_def_id()),
+                    id: id_from_def_id(self.owner_id.to_def_id()),
                     start: offset + text.len(),
                     end: offset + text.len() + name.len(),
                 }];
@@ -359,7 +359,7 @@ impl<'hir> Sig for hir::Item<'hir> {
                 let mut text = "const ".to_owned();
                 let name = self.ident.to_string();
                 let defs = vec![SigElement {
-                    id: id_from_def_id(self.def_id.to_def_id()),
+                    id: id_from_def_id(self.owner_id.to_def_id()),
                     start: offset + text.len(),
                     end: offset + text.len() + name.len(),
                 }];
@@ -428,7 +428,7 @@ impl<'hir> Sig for hir::Item<'hir> {
                 let mut text = "mod ".to_owned();
                 let name = self.ident.to_string();
                 let defs = vec![SigElement {
-                    id: id_from_def_id(self.def_id.to_def_id()),
+                    id: id_from_def_id(self.owner_id.to_def_id()),
                     start: offset + text.len(),
                     end: offset + text.len() + name.len(),
                 }];
@@ -764,7 +764,7 @@ impl<'hir> Sig for hir::ForeignItem<'hir> {
                 }
                 let name = self.ident.to_string();
                 let defs = vec![SigElement {
-                    id: id_from_def_id(self.def_id.to_def_id()),
+                    id: id_from_def_id(self.owner_id.to_def_id()),
                     start: offset + text.len(),
                     end: offset + text.len() + name.len(),
                 }];
@@ -780,7 +780,7 @@ impl<'hir> Sig for hir::ForeignItem<'hir> {
                 let mut text = "type ".to_owned();
                 let name = self.ident.to_string();
                 let defs = vec![SigElement {
-                    id: id_from_def_id(self.def_id.to_def_id()),
+                    id: id_from_def_id(self.owner_id.to_def_id()),
                     start: offset + text.len(),
                     end: offset + text.len() + name.len(),
                 }];
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 842aa98bc9e..322c7104be4 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -558,7 +558,7 @@ impl Span {
         self.data_untracked().is_dummy()
     }
 
-    /// Returns `true` if this span comes from a macro or desugaring.
+    /// Returns `true` if this span comes from any kind of macro, desugaring or inlining.
     #[inline]
     pub fn from_expansion(self) -> bool {
         self.ctxt() != SyntaxContext::root()
@@ -571,6 +571,12 @@ impl Span {
         matches!(outer_expn.kind, ExpnKind::Macro(..)) && outer_expn.collapse_debuginfo
     }
 
+    /// Returns `true` if this span comes from MIR inlining.
+    pub fn is_inlined(self) -> bool {
+        let outer_expn = self.ctxt().outer_expn_data();
+        matches!(outer_expn.kind, ExpnKind::Inlined)
+    }
+
     /// Returns `true` if `span` originates in a derive-macro's expansion.
     pub fn in_derive_expansion(self) -> bool {
         matches!(self.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Derive, _))
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 3fe79370c37..cccc4897ecc 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -694,6 +694,7 @@ symbols! {
         export_name,
         expr,
         extended_key_value_attributes,
+        extended_varargs_abi_support,
         extern_absolute_paths,
         extern_crate_item_prelude,
         extern_crate_self,
@@ -813,6 +814,7 @@ symbols! {
         impl_lint_pass,
         impl_macros,
         impl_trait_in_bindings,
+        impl_trait_in_fn_trait_return,
         implied_by,
         import,
         import_name_type,
@@ -1901,6 +1903,13 @@ impl fmt::Display for Symbol {
     }
 }
 
+// takes advantage of `str::to_string` specialization
+impl ToString for Symbol {
+    fn to_string(&self) -> String {
+        self.as_str().to_string()
+    }
+}
+
 impl<S: Encoder> Encodable<S> for Symbol {
     default fn encode(&self, s: &mut S) {
         s.emit_str(self.as_str());
diff --git a/compiler/rustc_symbol_mangling/src/test.rs b/compiler/rustc_symbol_mangling/src/test.rs
index c8c6fe2bf85..150459ce0f5 100644
--- a/compiler/rustc_symbol_mangling/src/test.rs
+++ b/compiler/rustc_symbol_mangling/src/test.rs
@@ -26,19 +26,19 @@ pub fn report_symbol_names(tcx: TyCtxt<'_>) {
         let crate_items = tcx.hir_crate_items(());
 
         for id in crate_items.items() {
-            symbol_names.process_attrs(id.def_id.def_id);
+            symbol_names.process_attrs(id.owner_id.def_id);
         }
 
         for id in crate_items.trait_items() {
-            symbol_names.process_attrs(id.def_id.def_id);
+            symbol_names.process_attrs(id.owner_id.def_id);
         }
 
         for id in crate_items.impl_items() {
-            symbol_names.process_attrs(id.def_id.def_id);
+            symbol_names.process_attrs(id.owner_id.def_id);
         }
 
         for id in crate_items.foreign_items() {
-            symbol_names.process_attrs(id.def_id.def_id);
+            symbol_names.process_attrs(id.owner_id.def_id);
         }
     })
 }
diff --git a/compiler/rustc_target/src/spec/abi.rs b/compiler/rustc_target/src/spec/abi.rs
index ce45fa13970..cb2a0c04c6a 100644
--- a/compiler/rustc_target/src/spec/abi.rs
+++ b/compiler/rustc_target/src/spec/abi.rs
@@ -40,6 +40,28 @@ pub enum Abi {
     RustCold,
 }
 
+impl Abi {
+    pub fn supports_varargs(self) -> bool {
+        // * C and Cdecl obviously support varargs.
+        // * C can be based on SysV64 or Win64, so they must support varargs.
+        // * EfiApi is based on Win64 or C, so it also supports it.
+        //
+        // * Stdcall does not, because it would be impossible for the callee to clean
+        //   up the arguments. (callee doesn't know how many arguments are there)
+        // * Same for Fastcall, Vectorcall and Thiscall.
+        // * System can become Stdcall, so is also a no-no.
+        // * Other calling conventions are related to hardware or the compiler itself.
+        match self {
+            Self::C { .. }
+            | Self::Cdecl { .. }
+            | Self::Win64 { .. }
+            | Self::SysV64 { .. }
+            | Self::EfiApi => true,
+            _ => false,
+        }
+    }
+}
+
 #[derive(Copy, Clone)]
 pub struct AbiData {
     abi: Abi,
diff --git a/compiler/rustc_target/src/spec/mipsel_sony_psx.rs b/compiler/rustc_target/src/spec/mipsel_sony_psx.rs
new file mode 100644
index 00000000000..12a66efdd46
--- /dev/null
+++ b/compiler/rustc_target/src/spec/mipsel_sony_psx.rs
@@ -0,0 +1,37 @@
+use crate::spec::{cvs, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
+
+pub fn target() -> Target {
+    Target {
+        llvm_target: "mipsel-sony-psx".into(),
+        pointer_width: 32,
+        data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".into(),
+        arch: "mips".into(),
+
+        options: TargetOptions {
+            os: "none".into(),
+            env: "psx".into(),
+            vendor: "sony".into(),
+            linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
+            cpu: "mips1".into(),
+            executables: true,
+            linker: Some("rust-lld".into()),
+            relocation_model: RelocModel::Static,
+            exe_suffix: ".exe".into(),
+
+            // PSX doesn't natively support floats.
+            features: "+soft-float".into(),
+
+            // This should be 16 bits, but LLVM incorrectly tries emitting MIPS-II SYNC instructions
+            // for atomic loads and stores. This crashes rustc so we have to disable the Atomic* API
+            // until this is fixed upstream. See https://reviews.llvm.org/D122427#3420144 for more
+            // info.
+            max_atomic_width: Some(0),
+
+            // PSX does not support trap-on-condition instructions.
+            llvm_args: cvs!["-mno-check-zero-division"],
+            llvm_abiname: "o32".into(),
+            panic_strategy: PanicStrategy::Abort,
+            ..Default::default()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 8909cf33af9..72b088d663b 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1222,6 +1222,7 @@ supported_targets! {
     ("armv7a-kmc-solid_asp3-eabihf", armv7a_kmc_solid_asp3_eabihf),
 
     ("mipsel-sony-psp", mipsel_sony_psp),
+    ("mipsel-sony-psx", mipsel_sony_psx),
     ("mipsel-unknown-none", mipsel_unknown_none),
     ("thumbv4t-none-eabi", thumbv4t_none_eabi),
     ("armv4t-none-eabi", armv4t_none_eabi),
diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs
index 1b58c9b864e..a335f8e06bc 100644
--- a/compiler/rustc_trait_selection/src/infer.rs
+++ b/compiler/rustc_trait_selection/src/infer.rs
@@ -69,7 +69,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
         let ty = self.resolve_vars_if_possible(ty);
 
         if !(param_env, ty).needs_infer() {
-            return ty.is_copy_modulo_regions(self.tcx.at(span), param_env);
+            return ty.is_copy_modulo_regions(self.tcx, param_env);
         }
 
         let copy_def_id = self.tcx.require_lang_item(LangItem::Copy, None);
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 84038625fb2..1de85e2f288 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -192,12 +192,12 @@ pub fn is_const_evaluatable<'tcx>(
         }
         let concrete = infcx.const_eval_resolve(param_env, uv, Some(span));
         match concrete {
-            Err(ErrorHandled::TooGeneric) => {
-                Err(NotConstEvaluatable::Error(infcx.tcx.sess.delay_span_bug(
-                    span,
-                    format!("Missing value for constant, but no error reported?"),
-                )))
-            }
+            Err(ErrorHandled::TooGeneric) => Err(NotConstEvaluatable::Error(
+                infcx
+                    .tcx
+                    .sess
+                    .delay_span_bug(span, "Missing value for constant, but no error reported?"),
+            )),
             Err(ErrorHandled::Linted) => {
                 let reported = infcx
                     .tcx
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 1217d264a9c..dacce5cd2f6 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -974,7 +974,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                 // useful for less general traits.
                                 if peeled
                                     && !self.tcx.trait_is_auto(def_id)
-                                    && !self.tcx.lang_items().items().contains(&Some(def_id))
+                                    && !self.tcx.lang_items().iter().any(|(_, id)| id == def_id)
                                 {
                                     let trait_ref = trait_pred.to_poly_trait_ref();
                                     let impl_candidates =
@@ -1898,7 +1898,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         let def_id = trait_ref.def_id();
         if impl_candidates.is_empty() {
             if self.tcx.trait_is_auto(def_id)
-                || self.tcx.lang_items().items().contains(&Some(def_id))
+                || self.tcx.lang_items().iter().any(|(_, id)| id == def_id)
                 || self.tcx.get_diagnostic_name(def_id).is_some()
             {
                 // Mentioning implementers of `Copy`, `Debug` and friends is not useful.
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 8c41d9d240c..d7606d88803 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1019,7 +1019,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         let mut never_suggest_borrow: Vec<_> =
             [LangItem::Copy, LangItem::Clone, LangItem::Unpin, LangItem::Sized]
                 .iter()
-                .filter_map(|lang_item| self.tcx.lang_items().require(*lang_item).ok())
+                .filter_map(|lang_item| self.tcx.lang_items().get(*lang_item))
                 .collect();
 
         if let Some(def_id) = self.tcx.get_diagnostic_item(sym::Send) {
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 30feabe1a09..8908fe230b0 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -214,7 +214,9 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
         trait_ref, item, cause, pred
     );
     let (items, impl_def_id) = match item {
-        Some(hir::Item { kind: hir::ItemKind::Impl(impl_), def_id, .. }) => (impl_.items, *def_id),
+        Some(hir::Item { kind: hir::ItemKind::Impl(impl_), owner_id, .. }) => {
+            (impl_.items, *owner_id)
+        }
         _ => return,
     };
     let fix_span =
@@ -236,7 +238,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
                     tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.item_def_id)
                 && let Some(impl_item_span) = items
                     .iter()
-                    .find(|item| item.id.def_id.to_def_id() == impl_item_id)
+                    .find(|item| item.id.owner_id.to_def_id() == impl_item_id)
                     .map(fix_span)
             {
                 cause.span = impl_item_span;
@@ -251,7 +253,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
                     tcx.impl_item_implementor_ids(impl_def_id).get(&item_def_id)
                 && let Some(impl_item_span) = items
                     .iter()
-                    .find(|item| item.id.def_id.to_def_id() == impl_item_id)
+                    .find(|item| item.id.owner_id.to_def_id() == impl_item_id)
                     .map(fix_span)
             {
                 cause.span = impl_item_span;
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index 3e2553c425e..424b52309d3 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -17,10 +17,10 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] {
     let item = tcx.hir().expect_item(def_id.expect_local());
     match item.kind {
         hir::ItemKind::Trait(.., ref trait_item_refs) => tcx.arena.alloc_from_iter(
-            trait_item_refs.iter().map(|trait_item_ref| trait_item_ref.id.def_id.to_def_id()),
+            trait_item_refs.iter().map(|trait_item_ref| trait_item_ref.id.owner_id.to_def_id()),
         ),
         hir::ItemKind::Impl(ref impl_) => tcx.arena.alloc_from_iter(
-            impl_.items.iter().map(|impl_item_ref| impl_item_ref.id.def_id.to_def_id()),
+            impl_.items.iter().map(|impl_item_ref| impl_item_ref.id.owner_id.to_def_id()),
         ),
         hir::ItemKind::TraitAlias(..) => &[],
         _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait"),
@@ -46,7 +46,7 @@ fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItem {
     match parent_item.kind {
         hir::ItemKind::Impl(ref impl_) => {
             if let Some(impl_item_ref) =
-                impl_.items.iter().find(|i| i.id.def_id.to_def_id() == def_id)
+                impl_.items.iter().find(|i| i.id.owner_id.to_def_id() == def_id)
             {
                 let assoc_item = associated_item_from_impl_item_ref(impl_item_ref);
                 debug_assert_eq!(assoc_item.def_id, def_id);
@@ -56,7 +56,7 @@ fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItem {
 
         hir::ItemKind::Trait(.., ref trait_item_refs) => {
             if let Some(trait_item_ref) =
-                trait_item_refs.iter().find(|i| i.id.def_id.to_def_id() == def_id)
+                trait_item_refs.iter().find(|i| i.id.owner_id.to_def_id() == def_id)
             {
                 let assoc_item = associated_item_from_trait_item_ref(trait_item_ref);
                 debug_assert_eq!(assoc_item.def_id, def_id);
@@ -75,7 +75,7 @@ fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItem {
 }
 
 fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty::AssocItem {
-    let def_id = trait_item_ref.id.def_id;
+    let owner_id = trait_item_ref.id.owner_id;
     let (kind, has_self) = match trait_item_ref.kind {
         hir::AssocItemKind::Const => (ty::AssocKind::Const, false),
         hir::AssocItemKind::Fn { has_self } => (ty::AssocKind::Fn, has_self),
@@ -85,15 +85,15 @@ fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty
     ty::AssocItem {
         name: trait_item_ref.ident.name,
         kind,
-        def_id: def_id.to_def_id(),
-        trait_item_def_id: Some(def_id.to_def_id()),
+        def_id: owner_id.to_def_id(),
+        trait_item_def_id: Some(owner_id.to_def_id()),
         container: ty::TraitContainer,
         fn_has_self_parameter: has_self,
     }
 }
 
 fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::AssocItem {
-    let def_id = impl_item_ref.id.def_id;
+    let def_id = impl_item_ref.id.owner_id;
     let (kind, has_self) = match impl_item_ref.kind {
         hir::AssocItemKind::Const => (ty::AssocKind::Const, false),
         hir::AssocItemKind::Fn { has_self } => (ty::AssocKind::Fn, has_self),
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index 416c1ec510b..6436713b388 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -4,7 +4,7 @@ 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_span::{sym, DUMMY_SP};
+use rustc_span::sym;
 use rustc_trait_selection::traits;
 use traits::{translate_substs, Reveal};
 
@@ -236,7 +236,7 @@ fn resolve_associated_item<'tcx>(
                 if name == sym::clone {
                     let self_ty = trait_ref.self_ty();
 
-                    let is_copy = self_ty.is_copy_modulo_regions(tcx.at(DUMMY_SP), param_env);
+                    let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env);
                     match self_ty.kind() {
                         _ if is_copy => (),
                         ty::Generator(..)
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 345911f4309..52ba0eee97c 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -399,7 +399,7 @@ fn layout_of_uncached<'tcx>(
             }
 
             let pointee = tcx.normalize_erasing_regions(param_env, pointee);
-            if pointee.is_sized(tcx.at(DUMMY_SP), param_env) {
+            if pointee.is_sized(tcx, param_env) {
                 return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr)));
             }
 
@@ -755,8 +755,7 @@ fn layout_of_uncached<'tcx>(
                 } else {
                     let param_env = tcx.param_env(def.did());
                     let last_field = def.variant(v).fields.last().unwrap();
-                    let always_sized =
-                        tcx.type_of(last_field.did).is_sized(tcx.at(DUMMY_SP), param_env);
+                    let always_sized = tcx.type_of(last_field.did).is_sized(tcx, param_env);
                     if !always_sized { StructKind::MaybeUnsized } else { StructKind::AlwaysSized }
                 };
 
diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs
index d390a308153..024dcd591bd 100644
--- a/compiler/rustc_ty_utils/src/needs_drop.rs
+++ b/compiler/rustc_ty_utils/src/needs_drop.rs
@@ -109,7 +109,7 @@ where
 
             for component in components {
                 match *component.kind() {
-                    _ if component.is_copy_modulo_regions(tcx.at(DUMMY_SP), self.param_env) => (),
+                    _ if component.is_copy_modulo_regions(tcx, self.param_env) => (),
 
                     ty::Closure(_, substs) => {
                         queue_type(self, substs.as_closure().tupled_upvars_ty());
diff --git a/config.toml.example b/config.toml.example
index a46813e4d7a..2373fb2ec4f 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -291,10 +291,6 @@ changelog-seen = 2
 # on this runtime, such as `-C profile-generate` or `-C instrument-coverage`).
 #profiler = false
 
-# Use the optimized LLVM C intrinsics for `compiler_builtins`, rather than Rust intrinsics.
-# Requires the LLVM submodule to be managed by bootstrap (i.e. not external).
-#optimized-compiler-builtins = false
-
 # Indicates whether the native libraries linked into Cargo will be statically
 # linked or not.
 #cargo-native-static = false
diff --git a/library/core/src/async_iter/async_iter.rs b/library/core/src/async_iter/async_iter.rs
index 016a3685e85..12a47f9fc76 100644
--- a/library/core/src/async_iter/async_iter.rs
+++ b/library/core/src/async_iter/async_iter.rs
@@ -2,7 +2,7 @@ use crate::ops::DerefMut;
 use crate::pin::Pin;
 use crate::task::{Context, Poll};
 
-/// An interface for dealing with asynchronous iterators.
+/// A trait for dealing with asynchronous iterators.
 ///
 /// This is the main async iterator trait. For more about the concept of async iterators
 /// generally, please see the [module-level documentation]. In particular, you
diff --git a/library/core/src/error.rs b/library/core/src/error.rs
index 89053060fbb..b24ca037d1a 100644
--- a/library/core/src/error.rs
+++ b/library/core/src/error.rs
@@ -1,5 +1,5 @@
 #![doc = include_str!("error.md")]
-#![unstable(feature = "error_in_core", issue = "none")]
+#![unstable(feature = "error_in_core", issue = "103765")]
 
 #[cfg(test)]
 mod tests;
diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs
index 55e58c4e0ba..8923f548adf 100644
--- a/library/core/src/ffi/c_str.rs
+++ b/library/core/src/ffi/c_str.rs
@@ -221,9 +221,7 @@ impl CStr {
     /// # Examples
     ///
     /// ```ignore (extern-declaration)
-    /// # fn main() {
-    /// use std::ffi::CStr;
-    /// use std::os::raw::c_char;
+    /// use std::ffi::{c_char, CStr};
     ///
     /// extern "C" {
     ///     fn my_string() -> *const c_char;
@@ -233,14 +231,26 @@ impl CStr {
     ///     let slice = CStr::from_ptr(my_string());
     ///     println!("string returned: {}", slice.to_str().unwrap());
     /// }
-    /// # }
+    /// ```
+    ///
+    /// ```
+    /// #![feature(const_cstr_methods)]
+    ///
+    /// use std::ffi::{c_char, CStr};
+    ///
+    /// const HELLO_PTR: *const c_char = {
+    ///     const BYTES: &[u8] = b"Hello, world!\0";
+    ///     BYTES.as_ptr().cast()
+    /// };
+    /// const HELLO: &CStr = unsafe { CStr::from_ptr(HELLO_PTR) };
     /// ```
     ///
     /// [valid]: core::ptr#safety
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
+    #[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")]
+    pub const unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
         // SAFETY: The caller has provided a pointer that points to a valid C
         // string with a NUL terminator of size less than `isize::MAX`, whose
         // content remain valid and doesn't change for the lifetime of the
@@ -252,13 +262,29 @@ impl CStr {
         //
         // The cast from c_char to u8 is ok because a c_char is always one byte.
         unsafe {
-            extern "C" {
-                /// Provided by libc or compiler_builtins.
-                fn strlen(s: *const c_char) -> usize;
+            const fn strlen_ct(s: *const c_char) -> usize {
+                let mut len = 0;
+
+                // SAFETY: Outer caller has provided a pointer to a valid C string.
+                while unsafe { *s.add(len) } != 0 {
+                    len += 1;
+                }
+
+                len
             }
-            let len = strlen(ptr);
-            let ptr = ptr as *const u8;
-            CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1))
+
+            fn strlen_rt(s: *const c_char) -> usize {
+                extern "C" {
+                    /// Provided by libc or compiler_builtins.
+                    fn strlen(s: *const c_char) -> usize;
+                }
+
+                // SAFETY: Outer caller has provided a pointer to a valid C string.
+                unsafe { strlen(s) }
+            }
+
+            let len = intrinsics::const_eval_select((ptr,), strlen_ct, strlen_rt);
+            Self::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr.cast(), len + 1))
         }
     }
 
diff --git a/library/core/src/future/poll_fn.rs b/library/core/src/future/poll_fn.rs
index db2a523323b..90cb797391a 100644
--- a/library/core/src/future/poll_fn.rs
+++ b/library/core/src/future/poll_fn.rs
@@ -5,7 +5,9 @@ use crate::task::{Context, Poll};
 
 /// Creates a future that wraps a function returning [`Poll`].
 ///
-/// Polling the future delegates to the wrapped function.
+/// Polling the future delegates to the wrapped function. If the returned future is pinned, then the
+/// captured environment of the wrapped function is also pinned in-place, so as long as the closure
+/// does not move out of its captures it can soundly create pinned references to them.
 ///
 /// # Examples
 ///
@@ -41,7 +43,7 @@ pub struct PollFn<F> {
 }
 
 #[stable(feature = "future_poll_fn", since = "1.64.0")]
-impl<F> Unpin for PollFn<F> {}
+impl<F: Unpin> Unpin for PollFn<F> {}
 
 #[stable(feature = "future_poll_fn", since = "1.64.0")]
 impl<F> fmt::Debug for PollFn<F> {
@@ -57,7 +59,8 @@ where
 {
     type Output = T;
 
-    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
-        (&mut self.f)(cx)
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
+        // SAFETY: We are not moving out of the pinned field.
+        (unsafe { &mut self.get_unchecked_mut().f })(cx)
     }
 }
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 789a87968d1..83c7e8977e9 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -14,7 +14,7 @@ use super::super::{
 
 fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
 
-/// An interface for dealing with iterators.
+/// A trait for dealing with iterators.
 ///
 /// This is the main iterator trait. For more about the concept of iterators
 /// generally, please see the [module-level documentation]. In particular, you
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 9195da5a44f..2e1a667097c 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -1004,7 +1004,7 @@ pub fn drop<T>(_x: T) {}
 /// ```
 #[inline]
 #[unstable(feature = "mem_copy_fn", issue = "98262")]
-pub fn copy<T: Copy>(x: &T) -> T {
+pub const fn copy<T: Copy>(x: &T) -> T {
     *x
 }
 
diff --git a/library/panic_unwind/src/emcc.rs b/library/panic_unwind/src/emcc.rs
index 7c233c7c3a1..c6d42308596 100644
--- a/library/panic_unwind/src/emcc.rs
+++ b/library/panic_unwind/src/emcc.rs
@@ -47,7 +47,12 @@ static EXCEPTION_TYPE_INFO: TypeInfo = TypeInfo {
     name: b"rust_panic\0".as_ptr(),
 };
 
+// NOTE(nbdd0121): The `canary` field will be part of stable ABI after `c_unwind` stabilization.
+#[repr(C)]
 struct Exception {
+    // See `gcc.rs` on why this is present. We already have a static here so just use it.
+    canary: *const TypeInfo,
+
     // This is necessary because C++ code can capture our exception with
     // std::exception_ptr and rethrow it multiple times, possibly even in
     // another thread.
@@ -70,27 +75,38 @@ pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
     let catch_data = &*(ptr as *mut CatchData);
 
     let adjusted_ptr = __cxa_begin_catch(catch_data.ptr as *mut libc::c_void) as *mut Exception;
-    let out = if catch_data.is_rust_panic {
-        let was_caught = (*adjusted_ptr).caught.swap(true, Ordering::SeqCst);
-        if was_caught {
-            // Since cleanup() isn't allowed to panic, we just abort instead.
-            intrinsics::abort();
-        }
-        (*adjusted_ptr).data.take().unwrap()
-    } else {
+    if !catch_data.is_rust_panic {
         super::__rust_foreign_exception();
-    };
+    }
+
+    let canary = ptr::addr_of!((*adjusted_ptr).canary).read();
+    if !ptr::eq(canary, &EXCEPTION_TYPE_INFO) {
+        super::__rust_foreign_exception();
+    }
+
+    let was_caught = (*adjusted_ptr).caught.swap(true, Ordering::SeqCst);
+    if was_caught {
+        // Since cleanup() isn't allowed to panic, we just abort instead.
+        intrinsics::abort();
+    }
+    let out = (*adjusted_ptr).data.take().unwrap();
     __cxa_end_catch();
     out
 }
 
 pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
-    let sz = mem::size_of_val(&data);
-    let exception = __cxa_allocate_exception(sz) as *mut Exception;
+    let exception = __cxa_allocate_exception(mem::size_of::<Exception>()) as *mut Exception;
     if exception.is_null() {
         return uw::_URC_FATAL_PHASE1_ERROR as u32;
     }
-    ptr::write(exception, Exception { caught: AtomicBool::new(false), data: Some(data) });
+    ptr::write(
+        exception,
+        Exception {
+            canary: &EXCEPTION_TYPE_INFO,
+            caught: AtomicBool::new(false),
+            data: Some(data),
+        },
+    );
     __cxa_throw(exception as *mut _, &EXCEPTION_TYPE_INFO, exception_cleanup);
 }
 
diff --git a/library/panic_unwind/src/gcc.rs b/library/panic_unwind/src/gcc.rs
index 261404e8795..0b7a873a691 100644
--- a/library/panic_unwind/src/gcc.rs
+++ b/library/panic_unwind/src/gcc.rs
@@ -38,12 +38,23 @@
 
 use alloc::boxed::Box;
 use core::any::Any;
+use core::ptr;
 
 use unwind as uw;
 
+// In case where multiple copies of std exist in a single process,
+// we use address of this static variable to distinguish an exception raised by
+// this copy and some other copy (which needs to be treated as foreign exception).
+static CANARY: u8 = 0;
+
+// NOTE(nbdd0121)
+// Once `c_unwind` feature is stabilized, there will be ABI stability requirement
+// on this struct. The first two field must be `_Unwind_Exception` and `canary`,
+// as it may be accessed by a different version of the std with a different compiler.
 #[repr(C)]
 struct Exception {
     _uwe: uw::_Unwind_Exception,
+    canary: *const u8,
     cause: Box<dyn Any + Send>,
 }
 
@@ -54,6 +65,7 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
             exception_cleanup,
             private: [0; uw::unwinder_private_data_size],
         },
+        canary: &CANARY,
         cause: data,
     });
     let exception_param = Box::into_raw(exception) as *mut uw::_Unwind_Exception;
@@ -75,10 +87,22 @@ pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
     if (*exception).exception_class != rust_exception_class() {
         uw::_Unwind_DeleteException(exception);
         super::__rust_foreign_exception();
-    } else {
-        let exception = Box::from_raw(exception as *mut Exception);
-        exception.cause
     }
+
+    let exception = exception.cast::<Exception>();
+    // Just access the canary field, avoid accessing the entire `Exception` as
+    // it can be a foreign Rust exception.
+    let canary = ptr::addr_of!((*exception).canary).read();
+    if !ptr::eq(canary, &CANARY) {
+        // A foreign Rust exception, treat it slightly differently from other
+        // foreign exceptions, because call into `_Unwind_DeleteException` will
+        // call into `__rust_drop_panic` which produces a confusing
+        // "Rust panic must be rethrown" message.
+        super::__rust_foreign_exception();
+    }
+
+    let exception = Box::from_raw(exception as *mut Exception);
+    exception.cause
 }
 
 // Rust's exception class identifier.  This is used by personality routines to
diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs
index 6b8d0656861..651115a8248 100644
--- a/library/panic_unwind/src/seh.rs
+++ b/library/panic_unwind/src/seh.rs
@@ -49,9 +49,15 @@
 use alloc::boxed::Box;
 use core::any::Any;
 use core::mem::{self, ManuallyDrop};
+use core::ptr;
 use libc::{c_int, c_uint, c_void};
 
+// NOTE(nbdd0121): The `canary` field will be part of stable ABI after `c_unwind` stabilization.
+#[repr(C)]
 struct Exception {
+    // See `gcc.rs` on why this is present. We already have a static here so just use it.
+    canary: *const _TypeDescriptor,
+
     // This needs to be an Option because we catch the exception by reference
     // and its destructor is executed by the C++ runtime. When we take the Box
     // out of the exception, we need to leave the exception in a valid state
@@ -235,7 +241,7 @@ static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor {
 macro_rules! define_cleanup {
     ($abi:tt $abi2:tt) => {
         unsafe extern $abi fn exception_cleanup(e: *mut Exception) {
-            if let Exception { data: Some(b) } = e.read() {
+            if let Exception { data: Some(b), .. } = e.read() {
                 drop(b);
                 super::__rust_drop_panic();
             }
@@ -265,7 +271,7 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
     // The ManuallyDrop is needed here since we don't want Exception to be
     // dropped when unwinding. Instead it will be dropped by exception_cleanup
     // which is invoked by the C++ runtime.
-    let mut exception = ManuallyDrop::new(Exception { data: Some(data) });
+    let mut exception = ManuallyDrop::new(Exception { canary: &TYPE_DESCRIPTOR, data: Some(data) });
     let throw_ptr = &mut exception as *mut _ as *mut _;
 
     // This... may seems surprising, and justifiably so. On 32-bit MSVC the
@@ -321,8 +327,12 @@ pub unsafe fn cleanup(payload: *mut u8) -> Box<dyn Any + Send> {
     // __rust_try. This happens when a non-Rust foreign exception is caught.
     if payload.is_null() {
         super::__rust_foreign_exception();
-    } else {
-        let exception = &mut *(payload as *mut Exception);
-        exception.data.take().unwrap()
     }
+    let exception = payload as *mut Exception;
+    let canary = ptr::addr_of!((*exception).canary).read();
+    if !ptr::eq(canary, &TYPE_DESCRIPTOR) {
+        // A foreign Rust exception.
+        super::__rust_foreign_exception();
+    }
+    (*exception).data.take().unwrap()
 }
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 34983b976e3..708edc5de47 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -759,7 +759,7 @@ where
 
     /// Tries to reserve capacity for at least `additional` more elements to be inserted
     /// in the `HashMap`. The collection may reserve more space to speculatively
-    /// avoid frequent reallocations. After calling `reserve`,
+    /// avoid frequent reallocations. After calling `try_reserve`,
     /// capacity will be greater than or equal to `self.len() + additional` if
     /// it returns `Ok(())`.
     /// Does nothing if capacity is already sufficient.
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index c36eeae3388..cee884145c7 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -462,7 +462,7 @@ where
 
     /// Tries to reserve capacity for at least `additional` more elements to be inserted
     /// in the `HashSet`. The collection may reserve more space to speculatively
-    /// avoid frequent reallocations. After calling `reserve`,
+    /// avoid frequent reallocations. After calling `try_reserve`,
     /// capacity will be greater than or equal to `self.len() + additional` if
     /// it returns `Ok(())`.
     /// Does nothing if capacity is already sufficient.
diff --git a/library/test/src/console.rs b/library/test/src/console.rs
index b1270c27271..8cb88016b23 100644
--- a/library/test/src/console.rs
+++ b/library/test/src/console.rs
@@ -228,9 +228,9 @@ fn on_test_event(
     out: &mut dyn OutputFormatter,
 ) -> io::Result<()> {
     match (*event).clone() {
-        TestEvent::TeFiltered(ref filtered_tests, shuffle_seed) => {
-            st.total = filtered_tests.len();
-            out.write_run_start(filtered_tests.len(), shuffle_seed)?;
+        TestEvent::TeFiltered(filtered_tests, shuffle_seed) => {
+            st.total = filtered_tests;
+            out.write_run_start(filtered_tests, shuffle_seed)?;
         }
         TestEvent::TeFilteredOut(filtered_out) => {
             st.filtered_out = filtered_out;
diff --git a/library/test/src/event.rs b/library/test/src/event.rs
index 6ff1a615eb4..80281ebd2d4 100644
--- a/library/test/src/event.rs
+++ b/library/test/src/event.rs
@@ -28,7 +28,7 @@ impl CompletedTest {
 
 #[derive(Debug, Clone)]
 pub enum TestEvent {
-    TeFiltered(Vec<TestDesc>, Option<u64>),
+    TeFiltered(usize, Option<u64>),
     TeWait(TestDesc),
     TeResult(CompletedTest),
     TeTimeout(TestDesc),
diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs
index 141f16d17f0..f16d94bbc81 100644
--- a/library/test/src/lib.rs
+++ b/library/test/src/lib.rs
@@ -219,6 +219,38 @@ pub fn assert_test_result<T: Termination>(result: T) -> Result<(), String> {
     }
 }
 
+struct FilteredTests {
+    tests: Vec<(TestId, TestDescAndFn)>,
+    benchs: Vec<(TestId, TestDescAndFn)>,
+    next_id: usize,
+}
+
+impl FilteredTests {
+    fn add_bench(&mut self, desc: TestDesc, testfn: TestFn) {
+        let test = TestDescAndFn { desc, testfn };
+        self.benchs.push((TestId(self.next_id), test));
+        self.next_id += 1;
+    }
+    fn add_test(&mut self, desc: TestDesc, testfn: TestFn) {
+        let test = TestDescAndFn { desc, testfn };
+        self.tests.push((TestId(self.next_id), test));
+        self.next_id += 1;
+    }
+    fn add_bench_as_test(
+        &mut self,
+        desc: TestDesc,
+        benchfn: impl Fn(&mut Bencher) -> Result<(), String> + Send + 'static,
+    ) {
+        let testfn = DynTestFn(Box::new(move || {
+            bench::run_once(|b| __rust_begin_short_backtrace(|| benchfn(b)))
+        }));
+        self.add_test(desc, testfn);
+    }
+    fn total_len(&self) -> usize {
+        self.tests.len() + self.benchs.len()
+    }
+}
+
 pub fn run_tests<F>(
     opts: &TestOpts,
     tests: Vec<TestDescAndFn>,
@@ -247,45 +279,51 @@ where
 
     let tests_len = tests.len();
 
-    let mut filtered_tests = filter_tests(opts, tests);
-    if !opts.bench_benchmarks {
-        filtered_tests = convert_benchmarks_to_tests(filtered_tests);
-    }
+    let mut filtered = FilteredTests { tests: Vec::new(), benchs: Vec::new(), next_id: 0 };
 
-    let filtered_tests = {
-        let mut filtered_tests = filtered_tests;
-        for test in filtered_tests.iter_mut() {
-            test.desc.name = test.desc.name.with_padding(test.testfn.padding());
-        }
+    for test in filter_tests(opts, tests) {
+        let mut desc = test.desc;
+        desc.name = desc.name.with_padding(test.testfn.padding());
 
-        filtered_tests
-    };
+        match test.testfn {
+            DynBenchFn(benchfn) => {
+                if opts.bench_benchmarks {
+                    filtered.add_bench(desc, DynBenchFn(benchfn));
+                } else {
+                    filtered.add_bench_as_test(desc, benchfn);
+                }
+            }
+            StaticBenchFn(benchfn) => {
+                if opts.bench_benchmarks {
+                    filtered.add_bench(desc, StaticBenchFn(benchfn));
+                } else {
+                    filtered.add_bench_as_test(desc, benchfn);
+                }
+            }
+            testfn => {
+                filtered.add_test(desc, testfn);
+            }
+        };
+    }
 
-    let filtered_out = tests_len - filtered_tests.len();
+    let filtered_out = tests_len - filtered.total_len();
     let event = TestEvent::TeFilteredOut(filtered_out);
     notify_about_test_event(event)?;
 
-    let filtered_descs = filtered_tests.iter().map(|t| t.desc.clone()).collect();
-
     let shuffle_seed = get_shuffle_seed(opts);
 
-    let event = TestEvent::TeFiltered(filtered_descs, shuffle_seed);
+    let event = TestEvent::TeFiltered(filtered.total_len(), shuffle_seed);
     notify_about_test_event(event)?;
 
-    let (mut filtered_tests, filtered_benchs): (Vec<_>, _) = filtered_tests
-        .into_iter()
-        .enumerate()
-        .map(|(i, e)| (TestId(i), e))
-        .partition(|(_, e)| matches!(e.testfn, StaticTestFn(_) | DynTestFn(_)));
-
     let concurrency = opts.test_threads.unwrap_or_else(get_concurrency);
 
+    let mut remaining = filtered.tests;
     if let Some(shuffle_seed) = shuffle_seed {
-        shuffle_tests(shuffle_seed, &mut filtered_tests);
+        shuffle_tests(shuffle_seed, &mut remaining);
     }
     // Store the tests in a VecDeque so we can efficiently remove the first element to run the
     // tests in the order they were passed (unless shuffled).
-    let mut remaining = VecDeque::from(filtered_tests);
+    let mut remaining = VecDeque::from(remaining);
     let mut pending = 0;
 
     let (tx, rx) = channel::<CompletedTest>();
@@ -402,7 +440,7 @@ where
 
     if opts.bench_benchmarks {
         // All benchmarks run at the end, in serial.
-        for (id, b) in filtered_benchs {
+        for (id, b) in filtered.benchs {
             let event = TestEvent::TeWait(b.desc.clone());
             notify_about_test_event(event)?;
             run_test(opts, false, id, b, run_strategy, tx.clone(), Concurrent::No);
@@ -432,7 +470,9 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescA
     }
 
     // Skip tests that match any of the skip filters
-    filtered.retain(|test| !opts.skip.iter().any(|sf| matches_filter(test, sf)));
+    if !opts.skip.is_empty() {
+        filtered.retain(|test| !opts.skip.iter().any(|sf| matches_filter(test, sf)));
+    }
 
     // Excludes #[should_panic] tests
     if opts.exclude_should_panic {
diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs
index e69cab956c5..23828f4758d 100644
--- a/src/bootstrap/bin/rustdoc.rs
+++ b/src/bootstrap/bin/rustdoc.rs
@@ -55,13 +55,9 @@ fn main() {
         arg.push(&linker);
         cmd.arg(arg);
     }
-    if env::var_os("RUSTDOC_FUSE_LD_LLD").is_some() {
+    if let Ok(no_threads) = env::var("RUSTDOC_LLD_NO_THREADS") {
         cmd.arg("-Clink-arg=-fuse-ld=lld");
-        if cfg!(windows) {
-            cmd.arg("-Clink-arg=-Wl,/threads:1");
-        } else {
-            cmd.arg("-Clink-arg=-Wl,--threads=1");
-        }
+        cmd.arg(format!("-Clink-arg=-Wl,{}", no_threads));
     }
     // Cargo doesn't pass RUSTDOCFLAGS to proc_macros:
     // https://github.com/rust-lang/cargo/issues/4423
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 8b144f14635..c8285c85d03 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -621,6 +621,7 @@ impl<'a> Builder<'a> {
                 check::CodegenBackend,
                 check::Clippy,
                 check::Miri,
+                check::CargoMiri,
                 check::Rls,
                 check::RustAnalyzer,
                 check::Rustfmt,
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 229851238f1..4450dd7e80f 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -451,14 +451,13 @@ macro_rules! tool_check_step {
 }
 
 tool_check_step!(Rustdoc, "src/tools/rustdoc", "src/librustdoc", SourceType::InTree);
-// Clippy and Rustfmt are hybrids. They are external tools, but use a git subtree instead
+// Clippy, miri and Rustfmt are hybrids. They are external tools, but use a git subtree instead
 // of a submodule. Since the SourceType only drives the deny-warnings
 // behavior, treat it as in-tree so that any new warnings in clippy will be
 // rejected.
 tool_check_step!(Clippy, "src/tools/clippy", SourceType::InTree);
-// Miri on the other hand is treated as out of tree, since InTree also causes it to
-// be run as part of `check`, which can fail on platforms which libffi-sys has no support for.
-tool_check_step!(Miri, "src/tools/miri", SourceType::Submodule);
+tool_check_step!(Miri, "src/tools/miri", SourceType::InTree);
+tool_check_step!(CargoMiri, "src/tools/miri/cargo-miri", SourceType::InTree);
 tool_check_step!(Rls, "src/tools/rls", SourceType::InTree);
 tool_check_step!(Rustfmt, "src/tools/rustfmt", SourceType::InTree);
 
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index e02a10b8164..18e780a108d 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -299,7 +299,9 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
 
     // Determine if we're going to compile in optimized C intrinsics to
     // the `compiler-builtins` crate. These intrinsics live in LLVM's
-    // `compiler-rt` repository.
+    // `compiler-rt` repository, but our `src/llvm-project` submodule isn't
+    // always checked out, so we need to conditionally look for this. (e.g. if
+    // an external LLVM is used we skip the LLVM submodule checkout).
     //
     // Note that this shouldn't affect the correctness of `compiler-builtins`,
     // but only its speed. Some intrinsics in C haven't been translated to Rust
@@ -310,15 +312,8 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
     // If `compiler-rt` is available ensure that the `c` feature of the
     // `compiler-builtins` crate is enabled and it's configured to learn where
     // `compiler-rt` is located.
-    let compiler_builtins_c_feature = if builder.config.optimized_compiler_builtins {
-        if !builder.is_rust_llvm(target) {
-            panic!(
-                "need a managed LLVM submodule for optimized intrinsics support; unset `llvm-config` or `optimized-compiler-builtins`"
-            );
-        }
-
-        builder.update_submodule(&Path::new("src").join("llvm-project"));
-        let compiler_builtins_root = builder.src.join("src/llvm-project/compiler-rt");
+    let compiler_builtins_root = builder.src.join("src/llvm-project/compiler-rt");
+    let compiler_builtins_c_feature = if compiler_builtins_root.exists() {
         // Note that `libprofiler_builtins/build.rs` also computes this so if
         // you're changing something here please also change that.
         cargo.env("RUST_COMPILER_RT_ROOT", &compiler_builtins_root);
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index a8c403675d8..34d5504827c 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -73,8 +73,6 @@ pub struct Config {
     pub color: Color,
     pub patch_binaries_for_nix: bool,
     pub stage0_metadata: Stage0Metadata,
-    /// Whether to use the `c` feature of the `compiler_builtins` crate.
-    pub optimized_compiler_builtins: bool,
 
     pub on_fail: Option<String>,
     pub stage: u32,
@@ -624,7 +622,6 @@ define_config! {
         bench_stage: Option<u32> = "bench-stage",
         patch_binaries_for_nix: Option<bool> = "patch-binaries-for-nix",
         metrics: Option<bool> = "metrics",
-        optimized_compiler_builtins: Option<bool> = "optimized-compiler-builtins",
     }
 }
 
@@ -1013,7 +1010,6 @@ impl Config {
         set(&mut config.print_step_timings, build.print_step_timings);
         set(&mut config.print_step_rusage, build.print_step_rusage);
         set(&mut config.patch_binaries_for_nix, build.patch_binaries_for_nix);
-        set(&mut config.optimized_compiler_builtins, build.optimized_compiler_builtins);
 
         config.verbose = cmp::max(config.verbose, flags.verbose);
 
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index c636d4c2b47..805633c926c 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -1847,21 +1847,23 @@ fn add_env(builder: &Builder<'_>, cmd: &mut Command, target: TargetSelection) {
 ///
 /// Returns whether the files were actually copied.
 fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir: &Path) -> bool {
-    if !builder.is_rust_llvm(target) {
-        // If the LLVM was externally provided, then we don't currently copy
-        // artifacts into the sysroot. This is not necessarily the right
-        // choice (in particular, it will require the LLVM dylib to be in
-        // the linker's load path at runtime), but the common use case for
-        // external LLVMs is distribution provided LLVMs, and in that case
-        // they're usually in the standard search path (e.g., /usr/lib) and
-        // copying them here is going to cause problems as we may end up
-        // with the wrong files and isn't what distributions want.
-        //
-        // This behavior may be revisited in the future though.
-        //
-        // If the LLVM is coming from ourselves (just from CI) though, we
-        // still want to install it, as it otherwise won't be available.
-        return false;
+    if let Some(config) = builder.config.target_config.get(&target) {
+        if config.llvm_config.is_some() && !builder.config.llvm_from_ci {
+            // If the LLVM was externally provided, then we don't currently copy
+            // artifacts into the sysroot. This is not necessarily the right
+            // choice (in particular, it will require the LLVM dylib to be in
+            // the linker's load path at runtime), but the common use case for
+            // external LLVMs is distribution provided LLVMs, and in that case
+            // they're usually in the standard search path (e.g., /usr/lib) and
+            // copying them here is going to cause problems as we may end up
+            // with the wrong files and isn't what distributions want.
+            //
+            // This behavior may be revisited in the future though.
+            //
+            // If the LLVM is coming from ourselves (just from CI) though, we
+            // still want to install it, as it otherwise won't be available.
+            return false;
+        }
     }
 
     // On macOS, rustc (and LLVM tools) link to an unversioned libLLVM.dylib
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index ea06caf9c33..5d265b9ad0c 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -765,7 +765,7 @@ impl Step for Rustc {
 }
 
 macro_rules! tool_doc {
-    ($tool: ident, $should_run: literal, $path: literal, [$($krate: literal),+ $(,)?], in_tree = $in_tree:expr $(,)?) => {
+    ($tool: ident, $should_run: literal, $path: literal, [$($krate: literal),+ $(,)?] $(,)?) => {
         #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
         pub struct $tool {
             target: TargetSelection,
@@ -821,12 +821,6 @@ macro_rules! tool_doc {
                 t!(fs::create_dir_all(&out_dir));
                 t!(symlink_dir_force(&builder.config, &out, &out_dir));
 
-                let source_type = if $in_tree == true {
-                    SourceType::InTree
-                } else {
-                    SourceType::Submodule
-                };
-
                 // Build cargo command.
                 let mut cargo = prepare_tool_cargo(
                     builder,
@@ -835,7 +829,7 @@ macro_rules! tool_doc {
                     target,
                     "doc",
                     $path,
-                    source_type,
+                    SourceType::InTree,
                     &[],
                 );
 
@@ -851,38 +845,21 @@ macro_rules! tool_doc {
                 cargo.rustdocflag("--show-type-layout");
                 cargo.rustdocflag("--generate-link-to-definition");
                 cargo.rustdocflag("-Zunstable-options");
-                if $in_tree == true {
-                    builder.run(&mut cargo.into());
-                } else {
-                    // Allow out-of-tree docs to fail (since the tool might be in a broken state).
-                    if !builder.try_run(&mut cargo.into()) {
-                        builder.info(&format!(
-                            "WARNING: tool {} failed to document; ignoring failure because it is an out-of-tree tool",
-                            stringify!($tool).to_lowercase(),
-                        ));
-                    }
-                }
+                builder.run(&mut cargo.into());
             }
         }
     }
 }
 
-tool_doc!(
-    Rustdoc,
-    "rustdoc-tool",
-    "src/tools/rustdoc",
-    ["rustdoc", "rustdoc-json-types"],
-    in_tree = true
-);
+tool_doc!(Rustdoc, "rustdoc-tool", "src/tools/rustdoc", ["rustdoc", "rustdoc-json-types"],);
 tool_doc!(
     Rustfmt,
     "rustfmt-nightly",
     "src/tools/rustfmt",
     ["rustfmt-nightly", "rustfmt-config_proc_macro"],
-    in_tree = true
 );
-tool_doc!(Clippy, "clippy", "src/tools/clippy", ["clippy_utils"], in_tree = true);
-tool_doc!(Miri, "miri", "src/tools/miri", ["miri"], in_tree = false);
+tool_doc!(Clippy, "clippy", "src/tools/clippy", ["clippy_utils"]);
+tool_doc!(Miri, "miri", "src/tools/miri", ["miri"]);
 
 #[derive(Ord, PartialOrd, Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct ErrorIndex {
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 7e70e99bb8c..f5def8ba834 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -1152,8 +1152,8 @@ impl Build {
                 options[0] = Some("-Clink-arg=-fuse-ld=lld".to_string());
             }
 
-            let threads = if target.contains("windows") { "/threads:1" } else { "--threads=1" };
-            options[1] = Some(format!("-Clink-arg=-Wl,{}", threads));
+            let no_threads = util::lld_flag_no_threads(target.contains("windows"));
+            options[1] = Some(format!("-Clink-arg=-Wl,{}", no_threads));
         }
 
         IntoIterator::into_iter(options).flatten()
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index ebac73d8aad..944fc3557f8 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -509,7 +509,7 @@ impl Step for Miri {
             host,
             "run",
             "src/tools/miri/cargo-miri",
-            SourceType::Submodule,
+            SourceType::InTree,
             &[],
         );
         cargo.add_rustc_lib_path(builder, compiler);
@@ -557,7 +557,7 @@ impl Step for Miri {
             host,
             "test",
             "src/tools/miri",
-            SourceType::Submodule,
+            SourceType::InTree,
             &[],
         );
         cargo.add_rustc_lib_path(builder, compiler);
@@ -771,7 +771,10 @@ impl Step for RustdocTheme {
             cmd.env("RUSTDOC_LINKER", linker);
         }
         if builder.is_fuse_ld_lld(self.compiler.host) {
-            cmd.env("RUSTDOC_FUSE_LD_LLD", "1");
+            cmd.env(
+                "RUSTDOC_LLD_NO_THREADS",
+                util::lld_flag_no_threads(self.compiler.host.contains("windows")),
+            );
         }
         try_run(builder, &mut cmd);
     }
@@ -1418,7 +1421,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the
         }
         let mut flags = if is_rustdoc { Vec::new() } else { vec!["-Crpath".to_string()] };
         flags.push(format!("-Cdebuginfo={}", builder.config.rust_debuginfo_level_tests));
-        flags.push(builder.config.cmd.rustc_args().join(" "));
+        flags.extend(builder.config.cmd.rustc_args().iter().map(|s| s.to_string()));
 
         if let Some(linker) = builder.linker(target) {
             cmd.arg("--linker").arg(linker);
@@ -1427,12 +1430,16 @@ note: if you're sure you want to do this, please open an issue as to why. In the
         let mut hostflags = flags.clone();
         hostflags.push(format!("-Lnative={}", builder.test_helpers_out(compiler.host).display()));
         hostflags.extend(builder.lld_flags(compiler.host));
-        cmd.arg("--host-rustcflags").arg(hostflags.join(" "));
+        for flag in hostflags {
+            cmd.arg("--host-rustcflags").arg(flag);
+        }
 
         let mut targetflags = flags;
         targetflags.push(format!("-Lnative={}", builder.test_helpers_out(target).display()));
         targetflags.extend(builder.lld_flags(target));
-        cmd.arg("--target-rustcflags").arg(targetflags.join(" "));
+        for flag in targetflags {
+            cmd.arg("--target-rustcflags").arg(flag);
+        }
 
         cmd.arg("--python").arg(builder.python());
 
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index eec74b2675a..d3952206947 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -794,10 +794,9 @@ macro_rules! tool_extended {
        $($name:ident,
        $path:expr,
        $tool_name:expr,
-       stable = $stable:expr,
-       $(in_tree = $in_tree:expr,)?
-       $(tool_std = $tool_std:literal,)?
-       $extra_deps:block;)+) => {
+       stable = $stable:expr
+       $(,tool_std = $tool_std:literal)?
+       ;)+) => {
         $(
             #[derive(Debug, Clone, Hash, PartialEq, Eq)]
         pub struct $name {
@@ -839,7 +838,6 @@ macro_rules! tool_extended {
 
             #[allow(unused_mut)]
             fn run(mut $sel, $builder: &Builder<'_>) -> Option<PathBuf> {
-                $extra_deps
                 $builder.ensure(ToolBuild {
                     compiler: $sel.compiler,
                     target: $sel.target,
@@ -848,11 +846,7 @@ macro_rules! tool_extended {
                     path: $path,
                     extra_features: $sel.extra_features,
                     is_optional_tool: true,
-                    source_type: if false $(|| $in_tree)* {
-                        SourceType::InTree
-                    } else {
-                        SourceType::Submodule
-                    },
+                    source_type: SourceType::InTree,
                 })
             }
         }
@@ -865,17 +859,17 @@ macro_rules! tool_extended {
 // Note: Most submodule updates for tools are handled by bootstrap.py, since they're needed just to
 // invoke Cargo to build bootstrap. See the comment there for more details.
 tool_extended!((self, builder),
-    Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true, in_tree=true, {};
-    CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true, in_tree=true, {};
-    Clippy, "src/tools/clippy", "clippy-driver", stable=true, in_tree=true, {};
-    Miri, "src/tools/miri", "miri", stable=false, in_tree=true, {};
-    CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=false, in_tree=true, {};
+    Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true;
+    CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true;
+    Clippy, "src/tools/clippy", "clippy-driver", stable=true;
+    Miri, "src/tools/miri", "miri", stable=false;
+    CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=true;
     // FIXME: tool_std is not quite right, we shouldn't allow nightly features.
     // But `builder.cargo` doesn't know how to handle ToolBootstrap in stages other than 0,
     // and this is close enough for now.
-    Rls, "src/tools/rls", "rls", stable=true, in_tree=true, tool_std=true, {};
-    RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, in_tree=true, tool_std=true, {};
-    Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, in_tree=true, {};
+    Rls, "src/tools/rls", "rls", stable=true, tool_std=true;
+    RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, tool_std=true;
+    Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true;
 );
 
 impl<'a> Builder<'a> {
diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs
index 0ebabbd5ca5..20c3801f0a5 100644
--- a/src/bootstrap/util.rs
+++ b/src/bootstrap/util.rs
@@ -13,6 +13,7 @@ use std::time::{Instant, SystemTime, UNIX_EPOCH};
 
 use crate::builder::Builder;
 use crate::config::{Config, TargetSelection};
+use crate::OnceCell;
 
 /// A helper macro to `unwrap` a result except also print out details like:
 ///
@@ -607,3 +608,16 @@ pub fn get_clang_cl_resource_dir(clang_cl_path: &str) -> PathBuf {
     let clang_rt_dir = clang_rt_builtins.parent().expect("The clang lib folder should exist");
     clang_rt_dir.to_path_buf()
 }
+
+pub fn lld_flag_no_threads(is_windows: bool) -> &'static str {
+    static LLD_NO_THREADS: OnceCell<(&'static str, &'static str)> = OnceCell::new();
+    let (windows, other) = LLD_NO_THREADS.get_or_init(|| {
+        let out = output(Command::new("lld").arg("-flavor").arg("ld").arg("--version"));
+        let newer = match (out.find(char::is_numeric), out.find('.')) {
+            (Some(b), Some(e)) => out.as_str()[b..e].parse::<i32>().ok().unwrap_or(14) > 10,
+            _ => true,
+        };
+        if newer { ("/threads:1", "--threads=1") } else { ("/no-threads", "--no-threads") }
+    });
+    if is_windows { windows } else { other }
+}
diff --git a/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile b/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile
index 637b5fa22f9..5ddd3f18039 100644
--- a/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile
+++ b/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile
@@ -47,6 +47,4 @@ ENV RUST_CONFIGURE_ARGS --disable-jemalloc \
   --set=$TARGET.cc=x86_64-unknown-haiku-gcc \
   --set=$TARGET.cxx=x86_64-unknown-haiku-g++ \
   --set=$TARGET.llvm-config=/bin/llvm-config-haiku
-ENV EXTERNAL_LLVM 1
-
 ENV SCRIPT python3 ../x.py dist --host=$HOST --target=$HOST
diff --git a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile
index cd86d9fb584..bff3f8f2192 100644
--- a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile
@@ -23,6 +23,7 @@ RUN yum upgrade -y && \
       libstdc++-devel.x86_64 \
       make \
       ncurses-devel \
+      ninja-build \
       openssl-devel \
       patch \
       perl \
@@ -64,7 +65,6 @@ ENV RUST_CONFIGURE_ARGS \
       --enable-profiler \
       --set target.i686-unknown-linux-gnu.linker=clang \
       --build=i686-unknown-linux-gnu \
-      --set llvm.ninja=false \
       --set rust.jemalloc
 ENV SCRIPT python3 ../x.py dist --build $HOSTS --host $HOSTS --target $HOSTS
 ENV CARGO_TARGET_I686_UNKNOWN_LINUX_GNU_LINKER=clang
diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
index 8250ec0c311..126c292b38e 100644
--- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
@@ -129,6 +129,4 @@ ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --disable-docs \
   --set target.wasm32-wasi.wasi-root=/wasm32-wasi \
   --musl-root-armv7=/musl-armv7
 
-ENV EXTERNAL_LLVM 1
-
 ENV SCRIPT python3 ../x.py dist --host='' --target $TARGETS
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
index 423aba06cca..6fdf05aebd6 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
@@ -23,6 +23,7 @@ RUN yum upgrade -y && \
       libstdc++-devel.x86_64 \
       make \
       ncurses-devel \
+      ninja-build \
       openssl-devel \
       patch \
       perl \
@@ -76,7 +77,6 @@ ENV RUST_CONFIGURE_ARGS \
       --set target.x86_64-unknown-linux-gnu.ar=/rustroot/bin/llvm-ar \
       --set target.x86_64-unknown-linux-gnu.ranlib=/rustroot/bin/llvm-ranlib \
       --set llvm.thin-lto=true \
-      --set llvm.ninja=false \
       --set rust.jemalloc \
       --set rust.use-lld=true \
       --set rust.lto=thin
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh
index 9abfd4e9731..15ab3e5bd6e 100755
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh
@@ -25,6 +25,7 @@ INC="/rustroot/include:/usr/include"
 # disable them. BOLT is used for optimizing LLVM.
 hide_output \
     cmake ../llvm \
+      -GNinja \
       -DCMAKE_C_COMPILER=/rustroot/bin/gcc \
       -DCMAKE_CXX_COMPILER=/rustroot/bin/g++ \
       -DCMAKE_BUILD_TYPE=Release \
@@ -39,8 +40,8 @@ hide_output \
       -DLLVM_ENABLE_PROJECTS="clang;lld;compiler-rt;bolt" \
       -DC_INCLUDE_DIRS="$INC"
 
-hide_output make -j$(nproc)
-hide_output make install
+hide_output ninja
+hide_output ninja install
 
 cd ../..
 rm -rf llvm-project
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile
index 1289f116fe9..23f2215c2d9 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile
@@ -29,7 +29,6 @@ RUN sh /scripts/sccache.sh
 # We are disabling CI LLVM since this builder is intentionally using a host
 # LLVM, rather than the typical src/llvm-project LLVM.
 ENV NO_DOWNLOAD_CI_LLVM 1
-ENV EXTERNAL_LLVM 1
 
 # Using llvm-link-shared due to libffi issues -- see #34486
 ENV RUST_CONFIGURE_ARGS \
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile
index 4b89a72baa1..8f6831bc54e 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile
@@ -40,7 +40,6 @@ RUN sh /scripts/sccache.sh
 # We are disabling CI LLVM since this builder is intentionally using a host
 # LLVM, rather than the typical src/llvm-project LLVM.
 ENV NO_DOWNLOAD_CI_LLVM 1
-ENV EXTERNAL_LLVM 1
 
 # Using llvm-link-shared due to libffi issues -- see #34486
 ENV RUST_CONFIGURE_ARGS \
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
index 80a066cac29..d8738455610 100755
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
@@ -27,6 +27,10 @@ python3 "$X_PY" test --stage 2 src/tools/rustfmt
 python3 "$X_PY" test --stage 2 src/tools/miri
 # We natively run this script on x86_64-unknown-linux-gnu and x86_64-pc-windows-msvc.
 # Also cover some other targets (on both of these hosts) via cross-testing.
-python3 "$X_PY" test --stage 2 src/tools/miri --target i686-pc-windows-msvc
+#
+# Currently disabled -- we end up pulling in a cross-compile of LLVM (maybe
+# just overly eager sanity checks), but in any case this won't work when
+# building LLVM as of this comment.
+#python3 "$X_PY" test --stage 2 src/tools/miri --target i686-pc-windows-msvc
 #FIXME(https://github.com/rust-lang/rust/issues/103519): macOS testing is currently disabled
 # python3 "$X_PY" test --stage 2 src/tools/miri --target aarch64-apple-darwin
diff --git a/src/ci/run.sh b/src/ci/run.sh
index 9d98ce22498..9a247fb60a8 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -69,11 +69,6 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.codegen-units-std=1"
 # space required for CI artifacts.
 RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --dist-compression-formats=xz"
 
-# Enable the `c` feature for compiler_builtins, but only when the `compiler-rt` source is available.
-if [ "$EXTERNAL_LLVM" = "" ]; then
-  RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set build.optimized-compiler-builtins"
-fi
-
 if [ "$DIST_SRC" = "" ]; then
   RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-dist-src"
 fi
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 06883ddd58b..86bb2c0d381 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -29,6 +29,7 @@
     - [\*-kmc-solid_\*](platform-support/kmc-solid.md)
     - [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md)
     - [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md)
+    - [mipsel-sony-psx](platform-support/mipsel-sony-psx.md)
     - [nvptx64-nvidia-cuda](platform-support/nvptx64-nvidia-cuda.md)
     - [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md)
     - [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index b1c3b618cec..f5a49410ea5 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -531,8 +531,10 @@ platforms. Possible values are:
   debug information. On other Unix platforms this means that `*.dwo` files will
   contain debug information.
 
-Note that `packed` and `unpacked` are gated behind `-Z unstable-options` on
-non-macOS platforms at this time.
+Note that all three options are supported on Linux and Apple platforms,
+`packed` is supported on Windows-MSVC, and all other platforms support `off`.
+Attempting to use an unsupported option requires using the nightly channel
+with the `-Z unstable-options` flag.
 
 ## strip
 
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index a36518cc8ce..3ae9872cf62 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -260,6 +260,7 @@ target | std | host | notes
 `mips-unknown-linux-uclibc` | ✓ |  | MIPS Linux with uClibc
 [`mips64-openwrt-linux-musl`](platform-support/mips64-openwrt-linux-musl.md) | ? |  | MIPS64 for OpenWrt Linux MUSL
 `mipsel-sony-psp` | * |  | MIPS (LE) Sony PlayStation Portable (PSP)
+[`mipsel-sony-psx`](platform-support/mipsel-sony-psx.md) | * |  | MIPS (LE) Sony PlayStation 1 (PSX)
 `mipsel-unknown-linux-uclibc` | ✓ |  | MIPS (LE) Linux with uClibc
 `mipsel-unknown-none` | * |  | Bare MIPS (LE) softfloat
 `mipsisa32r6-unknown-linux-gnu` | ? |  |
diff --git a/src/doc/rustc/src/platform-support/mipsel-sony-psx.md b/src/doc/rustc/src/platform-support/mipsel-sony-psx.md
new file mode 100644
index 00000000000..589100e8888
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/mipsel-sony-psx.md
@@ -0,0 +1,49 @@
+# mipsel-sony-psx
+
+**Tier: 3**
+
+Sony PlayStation 1 (psx)
+
+## Designated Developer
+
+* [@ayrtonm](https://github.com/ayrtonm)
+
+## Requirements
+
+This target is cross-compiled.
+It has no special requirements for the host.
+
+## Building
+
+The target can be built by enabling it for a `rustc` build:
+
+```toml
+[build]
+build-stage = 1
+target = ["mipsel-sony-psx"]
+```
+
+## Cross-compilation
+
+This target can be cross-compiled from any host.
+
+## Testing
+
+Currently there is no support to run the rustc test suite for this target.
+
+## Building Rust programs
+
+Since it is Tier 3, rust doesn't ship pre-compiled artifacts for this target.
+
+Just use the `build-std` nightly cargo feature to build the `core` and `alloc` libraries:
+```shell
+cargo build -Zbuild-std=core,alloc --target mipsel-sony-psx
+```
+
+The command above generates an ELF. To generate binaries in the PSEXE format that emulators run, you can use [cargo-psx](https://github.com/ayrtonm/psx-sdk-rs#readme):
+
+```shell
+cargo psx build
+```
+
+or use `-Clink-arg=--oformat=binary` to produce a flat binary.
diff --git a/src/doc/rustdoc/book.toml b/src/doc/rustdoc/book.toml
index 45405a11765..dfa68578500 100644
--- a/src/doc/rustdoc/book.toml
+++ b/src/doc/rustdoc/book.toml
@@ -6,5 +6,9 @@ title = "The rustdoc book"
 git-repository-url = "https://github.com/rust-lang/rust/tree/master/src/doc/rustdoc"
 
 [output.html.redirect]
+"/what-to-include.html" = "write-documentation/what-to-include.html"
 "/the-doc-attribute.html" = "write-documentation/the-doc-attribute.html"
+"/linking-to-items-by-name.html" = "write-documentation/linking-to-items-by-name.html"
 "/documentation-tests.html" = "write-documentation/documentation-tests.html"
+"/website-features.html" = "advanced-features.html#custom-search-engines"
+"/passes.html" = "deprecated-features.html#passes"
diff --git a/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md b/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md
new file mode 100644
index 00000000000..b20c30ec8f1
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md
@@ -0,0 +1,10 @@
+# `extended_varargs_abi_support`
+
+The tracking issue for this feature is: [#100189]
+
+[#100189]: https://github.com/rust-lang/rust/issues/100189
+
+------------------------
+
+This feature adds the possibility of using `sysv64`, `win64` or `efiapi` calling
+conventions on functions with varargs.
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index efa9242a467..764a6d3aa48 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -148,7 +148,7 @@ where
             })
             .collect();
         // We are only interested in case the type *doesn't* implement the Sized trait.
-        if !ty.is_sized(tcx.at(rustc_span::DUMMY_SP), param_env) {
+        if !ty.is_sized(tcx, param_env) {
             // In case `#![no_core]` is used, `sized_trait` returns nothing.
             if let Some(item) = tcx.lang_items().sized_trait().and_then(|sized_trait_did| {
                 self.generate_for_trait(ty, sized_trait_did, param_env, item_def_id, &f, true)
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index 7c59e785752..f82fb498131 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -20,7 +20,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
         trace!("get_blanket_impls({:?})", ty);
         let mut impls = Vec::new();
         for trait_def_id in cx.tcx.all_traits() {
-            if !cx.cache.access_levels.is_public(trait_def_id)
+            if !cx.cache.effective_visibilities.is_directly_public(cx.tcx, trait_def_id)
                 || cx.generated_synthetics.get(&(ty.0, trait_def_id)).is_some()
             {
                 continue;
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 432d318907f..d93f0bd4e56 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -55,12 +55,39 @@ pub(crate) fn try_inline(
     let mut ret = Vec::new();
 
     debug!("attrs={:?}", attrs);
-    let attrs_clone = attrs;
+
+    let attrs_without_docs = attrs.map(|attrs| {
+        attrs.into_iter().filter(|a| a.doc_str().is_none()).cloned().collect::<Vec<_>>()
+    });
+    // We need this ugly code because:
+    //
+    // ```
+    // attrs_without_docs.map(|a| a.as_slice())
+    // ```
+    //
+    // will fail because it returns a temporary slice and:
+    //
+    // ```
+    // attrs_without_docs.map(|s| {
+    //     vec = s.as_slice();
+    //     vec
+    // })
+    // ```
+    //
+    // will fail because we're moving an uninitialized variable into a closure.
+    let vec;
+    let attrs_without_docs = match attrs_without_docs {
+        Some(s) => {
+            vec = s;
+            Some(vec.as_slice())
+        }
+        None => None,
+    };
 
     let kind = match res {
         Res::Def(DefKind::Trait, did) => {
             record_extern_fqn(cx, did, ItemType::Trait);
-            build_impls(cx, Some(parent_module), did, attrs, &mut ret);
+            build_impls(cx, Some(parent_module), did, attrs_without_docs, &mut ret);
             clean::TraitItem(Box::new(build_external_trait(cx, did)))
         }
         Res::Def(DefKind::Fn, did) => {
@@ -69,27 +96,27 @@ pub(crate) fn try_inline(
         }
         Res::Def(DefKind::Struct, did) => {
             record_extern_fqn(cx, did, ItemType::Struct);
-            build_impls(cx, Some(parent_module), did, attrs, &mut ret);
+            build_impls(cx, Some(parent_module), did, attrs_without_docs, &mut ret);
             clean::StructItem(build_struct(cx, did))
         }
         Res::Def(DefKind::Union, did) => {
             record_extern_fqn(cx, did, ItemType::Union);
-            build_impls(cx, Some(parent_module), did, attrs, &mut ret);
+            build_impls(cx, Some(parent_module), did, attrs_without_docs, &mut ret);
             clean::UnionItem(build_union(cx, did))
         }
         Res::Def(DefKind::TyAlias, did) => {
             record_extern_fqn(cx, did, ItemType::Typedef);
-            build_impls(cx, Some(parent_module), did, attrs, &mut ret);
+            build_impls(cx, Some(parent_module), did, attrs_without_docs, &mut ret);
             clean::TypedefItem(build_type_alias(cx, did))
         }
         Res::Def(DefKind::Enum, did) => {
             record_extern_fqn(cx, did, ItemType::Enum);
-            build_impls(cx, Some(parent_module), did, attrs, &mut ret);
+            build_impls(cx, Some(parent_module), did, attrs_without_docs, &mut ret);
             clean::EnumItem(build_enum(cx, did))
         }
         Res::Def(DefKind::ForeignTy, did) => {
             record_extern_fqn(cx, did, ItemType::ForeignType);
-            build_impls(cx, Some(parent_module), did, attrs, &mut ret);
+            build_impls(cx, Some(parent_module), did, attrs_without_docs, &mut ret);
             clean::ForeignTypeItem
         }
         // Never inline enum variants but leave them shown as re-exports.
@@ -123,7 +150,7 @@ pub(crate) fn try_inline(
         _ => return None,
     };
 
-    let (attrs, cfg) = merge_attrs(cx, Some(parent_module), load_attrs(cx, did), attrs_clone);
+    let (attrs, cfg) = merge_attrs(cx, Some(parent_module), load_attrs(cx, did), attrs);
     cx.inlined.insert(did.into());
     let mut item = clean::Item::from_def_id_and_attrs_and_parts(
         did,
@@ -296,6 +323,21 @@ pub(crate) fn build_impls(
     for &did in tcx.inherent_impls(did).iter() {
         build_impl(cx, parent_module, did, attrs, ret);
     }
+
+    // This pretty much exists expressly for `dyn Error` traits that exist in the `alloc` crate.
+    // See also:
+    //
+    // * https://github.com/rust-lang/rust/issues/103170 — where it didn't used to get documented
+    // * https://github.com/rust-lang/rust/pull/99917 — where the feature got used
+    // * https://github.com/rust-lang/rust/issues/53487 — overall tracking issue for Error
+    if tcx.has_attr(did, sym::rustc_has_incoherent_inherent_impls) {
+        use rustc_middle::ty::fast_reject::SimplifiedTypeGen::*;
+        let type_ =
+            if tcx.is_trait(did) { TraitSimplifiedType(did) } else { AdtSimplifiedType(did) };
+        for &did in tcx.incoherent_impls(type_) {
+            build_impl(cx, parent_module, did, attrs, ret);
+        }
+    }
 }
 
 /// `parent_module` refers to the parent of the re-export, not the original item
@@ -347,7 +389,7 @@ pub(crate) fn build_impl(
     if !did.is_local() {
         if let Some(traitref) = associated_trait {
             let did = traitref.def_id;
-            if !cx.cache.access_levels.is_public(did) {
+            if !cx.cache.effective_visibilities.is_directly_public(tcx, did) {
                 return;
             }
 
@@ -376,7 +418,7 @@ pub(crate) fn build_impl(
     // reachable in rustdoc generated documentation
     if !did.is_local() {
         if let Some(did) = for_.def_id(&cx.cache) {
-            if !cx.cache.access_levels.is_public(did) {
+            if !cx.cache.effective_visibilities.is_directly_public(tcx, did) {
                 return;
             }
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index a3a1abc3cf0..8a0e6a82126 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1042,7 +1042,7 @@ fn clean_poly_trait_ref<'tcx>(
 }
 
 fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext<'tcx>) -> Item {
-    let local_did = trait_item.def_id.to_def_id();
+    let local_did = trait_item.owner_id.to_def_id();
     cx.with_param_env(local_did, |cx| {
         let inner = match trait_item.kind {
             hir::TraitItemKind::Const(ty, Some(default)) => AssocConstItem(
@@ -1094,7 +1094,7 @@ pub(crate) fn clean_impl_item<'tcx>(
     impl_: &hir::ImplItem<'tcx>,
     cx: &mut DocContext<'tcx>,
 ) -> Item {
-    let local_did = impl_.def_id.to_def_id();
+    let local_did = impl_.owner_id.to_def_id();
     cx.with_param_env(local_did, |cx| {
         let inner = match impl_.kind {
             hir::ImplItemKind::Const(ty, expr) => {
@@ -1103,7 +1103,7 @@ pub(crate) fn clean_impl_item<'tcx>(
             }
             hir::ImplItemKind::Fn(ref sig, body) => {
                 let m = clean_function(cx, sig, impl_.generics, body);
-                let defaultness = cx.tcx.impl_defaultness(impl_.def_id);
+                let defaultness = cx.tcx.impl_defaultness(impl_.owner_id);
                 MethodItem(m, Some(defaultness))
             }
             hir::ImplItemKind::Type(hir_ty) => {
@@ -1120,7 +1120,7 @@ pub(crate) fn clean_impl_item<'tcx>(
         let mut what_rustc_thinks =
             Item::from_def_id_and_parts(local_did, Some(impl_.ident.name), inner, cx);
 
-        let impl_ref = cx.tcx.impl_trait_ref(cx.tcx.local_parent(impl_.def_id.def_id));
+        let impl_ref = cx.tcx.impl_trait_ref(cx.tcx.local_parent(impl_.owner_id.def_id));
 
         // Trait impl items always inherit the impl's visibility --
         // we don't want to show `pub`.
@@ -1431,7 +1431,7 @@ fn maybe_expand_private_type_alias<'tcx>(
     let Res::Def(DefKind::TyAlias, def_id) = path.res else { return None };
     // Substitute private type aliases
     let def_id = def_id.as_local()?;
-    let alias = if !cx.cache.access_levels.is_exported(def_id.to_def_id()) {
+    let alias = if !cx.cache.effective_visibilities.is_exported(cx.tcx, def_id.to_def_id()) {
         &cx.tcx.hir().expect_item(def_id).kind
     } else {
         return None;
@@ -1958,7 +1958,7 @@ fn clean_maybe_renamed_item<'tcx>(
 ) -> Vec<Item> {
     use hir::ItemKind;
 
-    let def_id = item.def_id.to_def_id();
+    let def_id = item.owner_id.to_def_id();
     let mut name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id()));
     cx.with_param_env(def_id, |cx| {
         let kind = match item.kind {
@@ -2100,11 +2100,11 @@ fn clean_extern_crate<'tcx>(
     cx: &mut DocContext<'tcx>,
 ) -> Vec<Item> {
     // this is the ID of the `extern crate` statement
-    let cnum = cx.tcx.extern_mod_stmt_cnum(krate.def_id.def_id).unwrap_or(LOCAL_CRATE);
+    let cnum = cx.tcx.extern_mod_stmt_cnum(krate.owner_id.def_id).unwrap_or(LOCAL_CRATE);
     // this is the ID of the crate itself
     let crate_def_id = cnum.as_def_id();
     let attrs = cx.tcx.hir().attrs(krate.hir_id());
-    let ty_vis = cx.tcx.visibility(krate.def_id);
+    let ty_vis = cx.tcx.visibility(krate.owner_id);
     let please_inline = ty_vis.is_public()
         && attrs.iter().any(|a| {
             a.has_name(sym::doc)
@@ -2122,7 +2122,7 @@ fn clean_extern_crate<'tcx>(
         if let Some(items) = inline::try_inline(
             cx,
             cx.tcx.parent_module(krate.hir_id()).to_def_id(),
-            Some(krate.def_id.to_def_id()),
+            Some(krate.owner_id.to_def_id()),
             res,
             name,
             Some(attrs),
@@ -2158,11 +2158,11 @@ fn clean_use_statement<'tcx>(
         return Vec::new();
     }
 
-    let visibility = cx.tcx.visibility(import.def_id);
+    let visibility = cx.tcx.visibility(import.owner_id);
     let attrs = cx.tcx.hir().attrs(import.hir_id());
     let inline_attr = attrs.lists(sym::doc).get_word_attr(sym::inline);
     let pub_underscore = visibility.is_public() && name == kw::Underscore;
-    let current_mod = cx.tcx.parent_module_from_def_id(import.def_id.def_id);
+    let current_mod = cx.tcx.parent_module_from_def_id(import.owner_id.def_id);
 
     // The parent of the module in which this import resides. This
     // is the same as `current_mod` if that's already the top
@@ -2233,7 +2233,7 @@ fn clean_use_statement<'tcx>(
         }
         if !denied {
             let mut visited = FxHashSet::default();
-            let import_def_id = import.def_id.to_def_id();
+            let import_def_id = import.owner_id.to_def_id();
 
             if let Some(mut items) = inline::try_inline(
                 cx,
@@ -2256,7 +2256,7 @@ fn clean_use_statement<'tcx>(
         Import::new_simple(name, resolve_use_source(cx, path), true)
     };
 
-    vec![Item::from_def_id_and_parts(import.def_id.to_def_id(), None, ImportItem(inner), cx)]
+    vec![Item::from_def_id_and_parts(import.owner_id.to_def_id(), None, ImportItem(inner), cx)]
 }
 
 fn clean_maybe_renamed_foreign_item<'tcx>(
@@ -2264,7 +2264,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
     item: &hir::ForeignItem<'tcx>,
     renamed: Option<Symbol>,
 ) -> Item {
-    let def_id = item.def_id.to_def_id();
+    let def_id = item.owner_id.to_def_id();
     cx.with_param_env(def_id, |cx| {
         let kind = match item.kind {
             hir::ForeignItemKind::Fn(decl, names, generics) => {
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 4c130b2ffec..cd1f972dce8 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -240,13 +240,13 @@ impl ExternalCrate {
                     let item = tcx.hir().item(id);
                     match item.kind {
                         hir::ItemKind::Mod(_) => {
-                            as_keyword(Res::Def(DefKind::Mod, id.def_id.to_def_id()))
+                            as_keyword(Res::Def(DefKind::Mod, id.owner_id.to_def_id()))
                         }
                         hir::ItemKind::Use(path, hir::UseKind::Single)
-                            if tcx.visibility(id.def_id).is_public() =>
+                            if tcx.visibility(id.owner_id).is_public() =>
                         {
                             as_keyword(path.res.expect_non_local())
-                                .map(|(_, prim)| (id.def_id.to_def_id(), prim))
+                                .map(|(_, prim)| (id.owner_id.to_def_id(), prim))
                         }
                         _ => None,
                     }
@@ -308,14 +308,14 @@ impl ExternalCrate {
                     let item = tcx.hir().item(id);
                     match item.kind {
                         hir::ItemKind::Mod(_) => {
-                            as_primitive(Res::Def(DefKind::Mod, id.def_id.to_def_id()))
+                            as_primitive(Res::Def(DefKind::Mod, id.owner_id.to_def_id()))
                         }
                         hir::ItemKind::Use(path, hir::UseKind::Single)
-                            if tcx.visibility(id.def_id).is_public() =>
+                            if tcx.visibility(id.owner_id).is_public() =>
                         {
                             as_primitive(path.res.expect_non_local()).map(|(_, prim)| {
                                 // Pretend the primitive is local.
-                                (id.def_id.to_def_id(), prim)
+                                (id.owner_id.to_def_id(), prim)
                             })
                         }
                         _ => None,
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 4572a712258..8f3e29a31a0 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -8,7 +8,6 @@ use crate::clean::{
 };
 use crate::core::DocContext;
 use crate::formats::item_type::ItemType;
-use crate::visit_lib::LibEmbargoVisitor;
 
 use rustc_ast as ast;
 use rustc_ast::tokenstream::TokenTree;
@@ -32,7 +31,7 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
 
     for &cnum in cx.tcx.crates(()) {
         // Analyze doc-reachability for extern items
-        LibEmbargoVisitor::new(cx).visit_lib(cnum);
+        crate::visit_lib::lib_embargo_visit_item(cx, cnum.as_def_id());
     }
 
     // Clean the crate, translating the entire librustc_ast AST to one that is
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 8232353f915..3961802529b 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -1,6 +1,7 @@
 use rustc_ast::NodeId;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::{self, Lrc};
+use rustc_data_structures::unord::UnordSet;
 use rustc_errors::emitter::{Emitter, EmitterWriter};
 use rustc_errors::json::JsonEmitter;
 use rustc_feature::UnstableFeatures;
@@ -288,8 +289,7 @@ pub(crate) fn create_config(
             providers.typeck_item_bodies = |_, _| {};
             // hack so that `used_trait_imports` won't try to call typeck
             providers.used_trait_imports = |_, _| {
-                static EMPTY_SET: LazyLock<FxHashSet<LocalDefId>> =
-                    LazyLock::new(FxHashSet::default);
+                static EMPTY_SET: LazyLock<UnordSet<LocalDefId>> = LazyLock::new(UnordSet::default);
                 &EMPTY_SET
             };
             // In case typeck does end up being called, don't ICE in case there were name resolution errors
@@ -348,7 +348,6 @@ pub(crate) fn run_global_ctxt(
 
     let auto_traits =
         tcx.all_traits().filter(|&trait_def_id| tcx.trait_is_auto(trait_def_id)).collect();
-    let access_levels = tcx.privacy_access_levels(()).map_id(Into::into);
 
     let mut ctxt = DocContext {
         tcx,
@@ -361,7 +360,7 @@ pub(crate) fn run_global_ctxt(
         impl_trait_bounds: Default::default(),
         generated_synthetics: Default::default(),
         auto_traits,
-        cache: Cache::new(access_levels, render_options.document_private),
+        cache: Cache::new(render_options.document_private),
         inlined: FxHashSet::default(),
         output_format,
         render_options,
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index 2e428cfddcf..a0cf1ec78e2 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -2,7 +2,6 @@ use std::mem;
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir::def_id::{CrateNum, DefId};
-use rustc_middle::middle::privacy::AccessLevels;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::Symbol;
 
@@ -15,6 +14,7 @@ use crate::html::format::join_with_double_colon;
 use crate::html::markdown::short_markdown_summary;
 use crate::html::render::search_index::get_function_type_for_search;
 use crate::html::render::IndexItem;
+use crate::visit_lib::RustdocEffectiveVisibilities;
 
 /// This cache is used to store information about the [`clean::Crate`] being
 /// rendered in order to provide more useful documentation. This contains
@@ -77,8 +77,8 @@ pub(crate) struct Cache {
 
     // Note that external items for which `doc(hidden)` applies to are shown as
     // non-reachable while local items aren't. This is because we're reusing
-    // the access levels from the privacy check pass.
-    pub(crate) access_levels: AccessLevels<DefId>,
+    // the effective visibilities from the privacy check pass.
+    pub(crate) effective_visibilities: RustdocEffectiveVisibilities,
 
     /// The version of the crate being documented, if given from the `--crate-version` flag.
     pub(crate) crate_version: Option<String>,
@@ -132,8 +132,8 @@ struct CacheBuilder<'a, 'tcx> {
 }
 
 impl Cache {
-    pub(crate) fn new(access_levels: AccessLevels<DefId>, document_private: bool) -> Self {
-        Cache { access_levels, document_private, ..Cache::default() }
+    pub(crate) fn new(document_private: bool) -> Self {
+        Cache { document_private, ..Cache::default() }
     }
 
     /// Populates the `Cache` with more data. The returned `Crate` will be missing some data that was
@@ -381,7 +381,10 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
                     // paths map if there was already an entry present and we're
                     // not a public item.
                     if !self.cache.paths.contains_key(&item.item_id.expect_def_id())
-                        || self.cache.access_levels.is_public(item.item_id.expect_def_id())
+                        || self
+                            .cache
+                            .effective_visibilities
+                            .is_directly_public(self.tcx, item.item_id.expect_def_id())
                     {
                         self.cache.paths.insert(
                             item.item_id.expect_def_id(),
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 7d00002d05b..37202f786ed 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -659,7 +659,7 @@ pub(crate) fn href_with_root_path(
     }
 
     if !did.is_local()
-        && !cache.access_levels.is_public(did)
+        && !cache.effective_visibilities.is_directly_public(tcx, did)
         && !cache.document_private
         && !cache.primitive_locations.values().any(|&id| id == did)
     {
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 5e28204b21d..28136cc48d6 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -72,8 +72,12 @@ pub(crate) fn render_source_with_highlighting(
     line_numbers: Buffer,
     href_context: HrefContext<'_, '_, '_>,
     decoration_info: DecorationInfo,
+    extra: Option<&str>,
 ) {
     write_header(out, "", Some(line_numbers), Tooltip::None);
+    if let Some(extra) = extra {
+        out.push_str(extra);
+    }
     write_code(out, src, Some(href_context), Some(decoration_info));
     write_footer(out, None);
 }
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 96c57c8c85d..27dea8ec0b3 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -2869,10 +2869,6 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite
             write!(w, r#"<span class="prev">&pr;</span> <span class="next">&sc;</span>"#);
         }
 
-        if needs_expansion {
-            write!(w, r#"<span class="expand">&varr;</span>"#);
-        }
-
         // Look for the example file in the source map if it exists, otherwise return a dummy span
         let file_span = (|| {
             let source_map = tcx.sess.source_map();
@@ -2906,7 +2902,7 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite
             cx,
             &root_path,
             highlight::DecorationInfo(decoration_info),
-            sources::SourceContext::Embedded { offset: line_min },
+            sources::SourceContext::Embedded { offset: line_min, needs_expansion },
         );
         write!(w, "</div></div>");
 
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index 7ab65bff346..8a01c01049d 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -258,7 +258,7 @@ where
 
 pub(crate) enum SourceContext {
     Standalone,
-    Embedded { offset: usize },
+    Embedded { offset: usize, needs_expansion: bool },
 }
 
 /// Wrapper struct to render the source code of a file. This will do things like
@@ -274,14 +274,18 @@ pub(crate) fn print_src(
 ) {
     let lines = s.lines().count();
     let mut line_numbers = Buffer::empty_from(buf);
+    let extra;
     line_numbers.write_str("<pre class=\"src-line-numbers\">");
     match source_context {
         SourceContext::Standalone => {
+            extra = None;
             for line in 1..=lines {
                 writeln!(line_numbers, "<span id=\"{0}\">{0}</span>", line)
             }
         }
-        SourceContext::Embedded { offset } => {
+        SourceContext::Embedded { offset, needs_expansion } => {
+            extra =
+                if needs_expansion { Some(r#"<span class="expand">&varr;</span>"#) } else { None };
             for line in 1..=lines {
                 writeln!(line_numbers, "<span>{0}</span>", line + offset)
             }
@@ -297,5 +301,6 @@ pub(crate) fn print_src(
         line_numbers,
         highlight::HrefContext { context, file_span, root_path, current_href },
         decoration_info,
+        extra,
     );
 }
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 934334e0c88..894499e5c4f 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -163,9 +163,6 @@ h1.fqn {
 	padding-bottom: 6px;
 	margin-bottom: 15px;
 }
-#toggle-all-docs {
-	text-decoration: none;
-}
 /* The only headings that get underlines are:
 	 Markdown-generated headings within the top-doc
 	 Rustdoc-generated h2 section headings (e.g. "Implementations", "Required Methods", etc)
@@ -209,7 +206,7 @@ ul.all-items {
 	font-family: "Fira Sans", Arial, NanumBarunGothic, sans-serif;
 }
 
-a#toggle-all-docs,
+#toggle-all-docs,
 a.anchor,
 .small-section-header a,
 #source-sidebar a,
@@ -292,10 +289,6 @@ p:last-child {
 	margin: 0;
 }
 
-summary {
-	outline: none;
-}
-
 /* Fix some style changes due to normalize.css 8 */
 
 button {
@@ -303,6 +296,16 @@ button {
 	padding: 1px 6px;
 }
 
+button#toggle-all-docs {
+	padding: 0;
+	background: none;
+	border: none;
+	cursor: pointer;
+	/* iOS button gradient: https://stackoverflow.com/q/5438567 */
+	-webkit-appearance: none;
+	opacity: 1;
+}
+
 /* end tweaks for normalize.css 8 */
 
 .rustdoc {
@@ -497,9 +500,7 @@ ul.block, .block li {
 .sidebar h2 {
 	overflow-wrap: anywhere;
 	padding: 0;
-	margin: 0;
-	margin-top: 0.7rem;
-	margin-bottom: 0.7rem;
+	margin: 0.7rem 0;
 }
 
 .sidebar h3 {
@@ -571,10 +572,18 @@ ul.block, .block li {
 	padding: 13px 8px;
 	border-top-left-radius: 5px;
 	border-bottom-left-radius: 5px;
+	border-color: var(--example-line-numbers-border-color);
 }
 
 .src-line-numbers span {
 	cursor: pointer;
+	color: var(--src-line-numbers-span-color);
+}
+.src-line-numbers .line-highlighted {
+	background-color: var(--src-line-number-highlighted-background-color);
+}
+.src-line-numbers :target {
+	background-color: transparent;
 }
 
 .search-loading {
@@ -679,13 +688,16 @@ nav.sub {
 	display: flex;
 	align-items: center;
 }
-nav.sub form {
+.search-form {
+	position: relative;
+	display: flex;
+	height: 34px;
 	flex-grow: 1;
 }
 .source nav.sub {
 	margin: 0 0 15px 0;
 }
-.source nav.sub form {
+.source .search-form {
 	margin-left: 32px;
 }
 
@@ -776,11 +788,6 @@ table,
 	padding-right: 1.25rem;
 }
 
-.search-container {
-	position: relative;
-	display: flex;
-	height: 34px;
-}
 .search-results-title {
 	margin-top: 0;
 	white-space: nowrap;
@@ -801,10 +808,8 @@ table,
 }
 #crate-search {
 	min-width: 115px;
-	padding: 0;
 	/* keep these two in sync with "@-moz-document url-prefix()" below */
-	padding-left: 4px;
-	padding-right: 23px;
+	padding: 0 23px 0 4px;
 	/* prevents the <select> from overflowing the containing div in case it's shrunk */
 	max-width: 100%;
 	/* contents can overflow because of max-width limit, then show ellipsis */
@@ -856,15 +861,12 @@ so that we can apply CSS-filters to change the arrow color in themes */
 	   -webkit-appearance: textfield for search inputs. That
 	   causes rounded corners and no border on iOS Safari. */
 	-webkit-appearance: none;
-	/* Override Normalize.css: we have margins and do
-	 not want to overflow */
-	box-sizing: border-box !important;
 	outline: none;
 	border: 1px solid var(--border-color);
 	border-radius: 2px;
 	padding: 8px;
 	font-size: 1rem;
-	width: 100%;
+	flex-grow: 1;
 	background-color: var(--button-background-color);
 	color: var(--search-color);
 }
@@ -874,7 +876,6 @@ so that we can apply CSS-filters to change the arrow color in themes */
 
 .search-results {
 	display: none;
-	padding-bottom: 2em;
 }
 
 .search-results.active {
@@ -1527,6 +1528,8 @@ details.rustdoc-toggle > summary.hideme {
 
 details.rustdoc-toggle > summary {
 	list-style: none;
+	/* focus outline is shown on `::before` instead of this */
+	outline: none;
 }
 details.rustdoc-toggle > summary::-webkit-details-marker,
 details.rustdoc-toggle > summary::marker {
@@ -1718,7 +1721,6 @@ in storage.js
 		/* Hide the sidebar offscreen while not in use. Doing this instead of display: none means
 		   the sidebar stays visible for screen readers, which is useful for navigation. */
 		left: -1000px;
-		margin-left: 0;
 		margin: 0;
 		padding: 0;
 		z-index: 11;
@@ -1771,9 +1773,7 @@ in storage.js
 	.mobile-topbar .logo-container > img {
 		max-width: 35px;
 		max-height: 35px;
-		margin-left: 20px;
-		margin-top: 5px;
-		margin-bottom: 5px;
+		margin: 5px 0 5px 20px;
 	}
 
 	.mobile-topbar {
@@ -1951,7 +1951,7 @@ in storage.js
 		flex-direction: column;
 	}
 
-	nav.sub form {
+	.search-form {
 		align-self: stretch;
 	}
 
@@ -2022,45 +2022,36 @@ in storage.js
 	padding-bottom: 0;
 }
 
-.scraped-example .code-wrapper .prev {
+.scraped-example .code-wrapper .next,
+.scraped-example .code-wrapper .prev,
+.scraped-example .code-wrapper .expand {
 	position: absolute;
 	top: 0.25em;
-	right: 2.25em;
-	z-index: 100;
+	z-index: 1;
 	cursor: pointer;
 }
-
+.scraped-example .code-wrapper .prev {
+	right: 2.25em;
+}
 .scraped-example .code-wrapper .next {
-	position: absolute;
-	top: 0.25em;
 	right: 1.25em;
-	z-index: 100;
-	cursor: pointer;
 }
-
 .scraped-example .code-wrapper .expand {
-	position: absolute;
-	top: 0.25em;
 	right: 0.25em;
-	z-index: 100;
-	cursor: pointer;
 }
 
-.scraped-example:not(.expanded) .code-wrapper:before {
+.scraped-example:not(.expanded) .code-wrapper:before,
+.scraped-example:not(.expanded) .code-wrapper:after {
 	content: " ";
 	width: 100%;
 	height: 5px;
 	position: absolute;
-	z-index: 100;
+	z-index: 1;
+}
+.scraped-example:not(.expanded) .code-wrapper:before {
 	top: 0;
 }
-
 .scraped-example:not(.expanded) .code-wrapper:after {
-	content: " ";
-	width: 100%;
-	height: 5px;
-	position: absolute;
-	z-index: 100;
 	bottom: 0;
 }
 
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index 33817c16808..fdfdb3e1966 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -55,6 +55,9 @@ Original by Dempfi (https://github.com/dempfi/ayu)
 	--code-highlight-question-mark-color: #ff9011;
 	--code-highlight-comment-color: #788797;
 	--code-highlight-doc-comment-color: #a1ac88;
+	--example-line-numbers-border-color: none;
+	--src-line-numbers-span-color: #5c6773;
+	--src-line-number-highlighted-background-color: rgba(255, 236, 164, 0.06);
 }
 
 .slider {
@@ -112,10 +115,8 @@ pre, .rustdoc.source .example-wrap {
 	color: #ff7733;
 }
 
-.src-line-numbers span { color: #5c6773; }
 .src-line-numbers .line-highlighted {
 	color: #708090;
-	background-color: rgba(255, 236, 164, 0.06);
 	padding-right: 4px;
 	border-right: 1px solid #ffb44c;
 }
@@ -170,13 +171,6 @@ details.rustdoc-toggle > summary::before {
 	color: #788797;
 }
 
-.src-line-numbers :target { background-color: transparent; }
-
-pre.example-line-numbers {
-	color: #5c67736e;
-	border: none;
-}
-
 a.test-arrow {
 	font-size: 100%;
 	color: #788797;
diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css
index d88710288b9..361d3d4a225 100644
--- a/src/librustdoc/html/static/css/themes/dark.css
+++ b/src/librustdoc/html/static/css/themes/dark.css
@@ -50,6 +50,9 @@
 	--code-highlight-question-mark-color: #ff9011;
 	--code-highlight-comment-color: #8d8d8b;
 	--code-highlight-doc-comment-color: #8ca375;
+	--example-line-numbers-border-color: #4a4949;
+	--src-line-numbers-span-color: #3b91e2;
+	--src-line-number-highlighted-background-color: #0a042f;
 }
 
 .slider {
@@ -69,11 +72,6 @@ input:focus + .slider {
 		drop-shadow(0 -1px 0 #fff)
 }
 
-.src-line-numbers span { color: #3B91E2; }
-.src-line-numbers .line-highlighted {
-	background-color: #0a042f !important;
-}
-
 .content .item-info::before { color: #ccc; }
 
 body.source .example-wrap pre.rust a {
@@ -95,12 +93,6 @@ details.rustdoc-toggle > summary::before {
 	filter: invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);
 }
 
-.src-line-numbers :target { background-color: transparent; }
-
-pre.example-line-numbers {
-	border-color: #4a4949;
-}
-
 a.test-arrow {
 	color: #dedede;
 	background-color: rgba(78, 139, 202, 0.2);
diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css
index cadc71dab95..5eb4bbcf834 100644
--- a/src/librustdoc/html/static/css/themes/light.css
+++ b/src/librustdoc/html/static/css/themes/light.css
@@ -50,6 +50,9 @@
 	--code-highlight-question-mark-color: #ff9011;
 	--code-highlight-comment-color: #8e908c;
 	--code-highlight-doc-comment-color: #4d4d4c;
+	--example-line-numbers-border-color: #c7c7c7;
+	--src-line-numbers-span-color: #c67e2d;
+	--src-line-number-highlighted-background-color: #fdffd3;
 }
 
 .slider {
@@ -68,11 +71,6 @@ input:focus + .slider {
 	 */
 }
 
-.src-line-numbers span { color: #c67e2d; }
-.src-line-numbers .line-highlighted {
-	background-color: #FDFFD3 !important;
-}
-
 .content .item-info::before { color: #ccc; }
 
 body.source .example-wrap pre.rust a {
@@ -90,12 +88,6 @@ body.source .example-wrap pre.rust a {
 	filter: invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);
 }
 
-.src-line-numbers :target { background-color: transparent; }
-
-pre.example-line-numbers {
-	border-color: #c7c7c7;
-}
-
 a.test-arrow {
 	color: #f5f5f5;
 	background-color: rgba(78, 139, 202, 0.2);
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 0b816eace64..33480fa41cf 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -932,7 +932,7 @@ function loadCss(cssFileName) {
      * Hide all the popover menus.
      */
     window.hidePopoverMenus = function() {
-        onEachLazy(document.querySelectorAll(".search-container .popover"), elem => {
+        onEachLazy(document.querySelectorAll(".search-form .popover"), elem => {
             elem.style.display = "none";
         });
     };
diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html
index ee8938ea603..c3238691687 100644
--- a/src/librustdoc/html/templates/page.html
+++ b/src/librustdoc/html/templates/page.html
@@ -115,24 +115,22 @@
                 </a> {#- -#}
                 {%- endif -%}
                 <form class="search-form"> {#- -#}
-                    <div class="search-container"> {#- -#}
-                        <span></span> {#- This empty span is a hacky fix for Safari - See #93184 -#}
-                        <input {# -#}
-                            class="search-input" {# -#}
-                            name="search" {# -#}
-                            autocomplete="off" {# -#}
-                            spellcheck="false" {# -#}
-                            placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {# -#}
-                            type="search"> {#- -#}
-                        <div id="help-button" title="help" tabindex="-1"> {#- -#}
-                            <a href="{{page.root_path|safe}}help.html">?</a> {#- -#}
-                        </div> {#- -#}
-                        <div id="settings-menu" tabindex="-1"> {#- -#}
-                            <a href="{{page.root_path|safe}}settings.html" title="settings"> {#- -#}
-                                <img width="22" height="22" alt="Change settings" {# -#}
-                                 src="{{static_root_path|safe}}wheel{{page.resource_suffix}}.svg"> {#- -#}
-                            </a> {#- -#}
-                        </div> {#- -#}
+                    <span></span> {#- This empty span is a hacky fix for Safari - See #93184 -#}
+                    <input {# -#}
+                        class="search-input" {# -#}
+                        name="search" {# -#}
+                        autocomplete="off" {# -#}
+                        spellcheck="false" {# -#}
+                        placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {# -#}
+                        type="search"> {#- -#}
+                    <div id="help-button" title="help" tabindex="-1"> {#- -#}
+                        <a href="{{page.root_path|safe}}help.html">?</a> {#- -#}
+                    </div> {#- -#}
+                    <div id="settings-menu" tabindex="-1"> {#- -#}
+                        <a href="{{page.root_path|safe}}settings.html" title="settings"> {#- -#}
+                            <img width="22" height="22" alt="Change settings" {# -#}
+                             src="{{static_root_path|safe}}wheel{{page.resource_suffix}}.svg"> {#- -#}
+                        </a> {#- -#}
                     </div> {#- -#}
                 </form> {#- -#}
             </nav> {#- -#}
diff --git a/src/librustdoc/html/templates/print_item.html b/src/librustdoc/html/templates/print_item.html
index b6ce3ea3dee..e497b619366 100644
--- a/src/librustdoc/html/templates/print_item.html
+++ b/src/librustdoc/html/templates/print_item.html
@@ -21,8 +21,8 @@
                 <a class="srclink" href="{{href|safe}}">source</a> · {# -#}
             {%- else -%}
         {%- endmatch -%}
-        <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs"> {#- -#}
-            [<span class="inner">&#x2212;</span>] {#- -#}
-        </a> {#- -#}
+        <button id="toggle-all-docs" title="collapse all docs"> {#- -#}
+            [<span>&#x2212;</span>] {#- -#}
+        </button> {#- -#}
     </span> {#- -#}
 </div> {#- -#}
diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs
index 15982b40944..057d2fdd9d5 100644
--- a/src/librustdoc/passes/check_doc_test_visibility.rs
+++ b/src/librustdoc/passes/check_doc_test_visibility.rs
@@ -56,7 +56,7 @@ impl crate::doctest::Tester for Tests {
 }
 
 pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool {
-    if !cx.cache.access_levels.is_public(item.item_id.expect_def_id())
+    if !cx.cache.effective_visibilities.is_directly_public(cx.tcx, item.item_id.expect_def_id())
         || matches!(
             *item.kind,
             clean::StructFieldItem(_)
@@ -130,7 +130,7 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item
             );
         }
     } else if tests.found_tests > 0
-        && !cx.cache.access_levels.is_exported(item.item_id.expect_def_id())
+        && !cx.cache.effective_visibilities.is_exported(cx.tcx, item.item_id.expect_def_id())
     {
         cx.tcx.struct_span_lint_hir(
             crate::lint::PRIVATE_DOC_TESTS,
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 3513c13d522..0bd0dbbeb70 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1202,8 +1202,8 @@ impl LinkCollector<'_, '_> {
                 item.item_id.expect_def_id().as_local().map(|src_id| (src_id, dst_id))
             })
         {
-            if self.cx.tcx.privacy_access_levels(()).is_exported(src_id)
-                && !self.cx.tcx.privacy_access_levels(()).is_exported(dst_id)
+            if self.cx.tcx.effective_visibilities(()).is_exported(src_id)
+                && !self.cx.tcx.effective_visibilities(()).is_exported(dst_id)
             {
                 privacy_error(self.cx, diag_info, path_str);
             }
@@ -1893,7 +1893,7 @@ fn disambiguator_error(
     diag_info.link_range = disambiguator_range;
     report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, &diag_info, |diag, _sp| {
         let msg = format!(
-            "see {}/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators",
+            "see {}/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators",
             crate::DOC_RUST_LANG_ORG_CHANNEL
         );
         diag.note(&msg);
diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs
index 9914edf3036..e07a788a72a 100644
--- a/src/librustdoc/passes/strip_hidden.rs
+++ b/src/librustdoc/passes/strip_hidden.rs
@@ -27,6 +27,7 @@ pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clea
 
     // strip all impls referencing stripped items
     let mut stripper = ImplStripper {
+        tcx: cx.tcx,
         retained: &retained,
         cache: &cx.cache,
         is_json_output,
diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs
index f3aa3c7ce24..e3b958b2036 100644
--- a/src/librustdoc/passes/strip_private.rs
+++ b/src/librustdoc/passes/strip_private.rs
@@ -22,8 +22,9 @@ pub(crate) fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) ->
     // strip all private items
     {
         let mut stripper = Stripper {
+            tcx: cx.tcx,
             retained: &mut retained,
-            access_levels: &cx.cache.access_levels,
+            effective_visibilities: &cx.cache.effective_visibilities,
             update_retained: true,
             is_json_output,
         };
@@ -32,6 +33,7 @@ pub(crate) fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) ->
 
     // strip all impls referencing private items
     let mut stripper = ImplStripper {
+        tcx: cx.tcx,
         retained: &retained,
         cache: &cx.cache,
         is_json_output,
diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs
index a9d768f0149..4fa5c04ddf6 100644
--- a/src/librustdoc/passes/stripper.rs
+++ b/src/librustdoc/passes/stripper.rs
@@ -1,15 +1,19 @@
 //! A collection of utility functions for the `strip_*` passes.
 use rustc_hir::def_id::DefId;
-use rustc_middle::middle::privacy::AccessLevels;
+use rustc_middle::ty::TyCtxt;
+use rustc_span::symbol::sym;
+
 use std::mem;
 
-use crate::clean::{self, Item, ItemId, ItemIdSet};
+use crate::clean::{self, Item, ItemId, ItemIdSet, NestedAttributesExt};
 use crate::fold::{strip_item, DocFolder};
 use crate::formats::cache::Cache;
+use crate::visit_lib::RustdocEffectiveVisibilities;
 
-pub(crate) struct Stripper<'a> {
+pub(crate) struct Stripper<'a, 'tcx> {
+    pub(crate) tcx: TyCtxt<'tcx>,
     pub(crate) retained: &'a mut ItemIdSet,
-    pub(crate) access_levels: &'a AccessLevels<DefId>,
+    pub(crate) effective_visibilities: &'a RustdocEffectiveVisibilities,
     pub(crate) update_retained: bool,
     pub(crate) is_json_output: bool,
 }
@@ -19,18 +23,19 @@ pub(crate) struct Stripper<'a> {
 // are in the public API, which is not enough.
 #[inline]
 fn is_item_reachable(
+    tcx: TyCtxt<'_>,
     is_json_output: bool,
-    access_levels: &AccessLevels<DefId>,
+    effective_visibilities: &RustdocEffectiveVisibilities,
     item_id: ItemId,
 ) -> bool {
     if is_json_output {
-        access_levels.is_reachable(item_id.expect_def_id())
+        effective_visibilities.is_reachable(tcx, item_id.expect_def_id())
     } else {
-        access_levels.is_exported(item_id.expect_def_id())
+        effective_visibilities.is_exported(tcx, item_id.expect_def_id())
     }
 }
 
-impl<'a> DocFolder for Stripper<'a> {
+impl<'a> DocFolder for Stripper<'a, '_> {
     fn fold_item(&mut self, i: Item) -> Option<Item> {
         match *i.kind {
             clean::StrippedItem(..) => {
@@ -64,7 +69,12 @@ impl<'a> DocFolder for Stripper<'a> {
             | clean::ForeignTypeItem => {
                 let item_id = i.item_id;
                 if item_id.is_local()
-                    && !is_item_reachable(self.is_json_output, self.access_levels, item_id)
+                    && !is_item_reachable(
+                        self.tcx,
+                        self.is_json_output,
+                        self.effective_visibilities,
+                        item_id,
+                    )
                 {
                     debug!("Stripper: stripping {:?} {:?}", i.type_(), i.name);
                     return None;
@@ -144,14 +154,31 @@ impl<'a> DocFolder for Stripper<'a> {
 }
 
 /// This stripper discards all impls which reference stripped items
-pub(crate) struct ImplStripper<'a> {
+pub(crate) struct ImplStripper<'a, 'tcx> {
+    pub(crate) tcx: TyCtxt<'tcx>,
     pub(crate) retained: &'a ItemIdSet,
     pub(crate) cache: &'a Cache,
     pub(crate) is_json_output: bool,
     pub(crate) document_private: bool,
 }
 
-impl<'a> DocFolder for ImplStripper<'a> {
+impl<'a> ImplStripper<'a, '_> {
+    #[inline]
+    fn should_keep_impl(&self, item: &Item, for_def_id: DefId) -> bool {
+        if !for_def_id.is_local() || self.retained.contains(&for_def_id.into()) {
+            true
+        } else if self.is_json_output {
+            // If the "for" item is exported and the impl block isn't `#[doc(hidden)]`, then we
+            // need to keep it.
+            self.cache.effective_visibilities.is_exported(self.tcx, for_def_id)
+                && !item.attrs.lists(sym::doc).has_word(sym::hidden)
+        } else {
+            false
+        }
+    }
+}
+
+impl<'a> DocFolder for ImplStripper<'a, '_> {
     fn fold_item(&mut self, i: Item) -> Option<Item> {
         if let clean::ImplItem(ref imp) = *i.kind {
             // Impl blocks can be skipped if they are: empty; not a trait impl; and have no
@@ -167,8 +194,9 @@ impl<'a> DocFolder for ImplStripper<'a> {
                         let item_id = i.item_id;
                         item_id.is_local()
                             && !is_item_reachable(
+                                self.tcx,
                                 self.is_json_output,
-                                &self.cache.access_levels,
+                                &self.cache.effective_visibilities,
                                 item_id,
                             )
                     })
@@ -178,15 +206,17 @@ impl<'a> DocFolder for ImplStripper<'a> {
                     return None;
                 }
             }
+            // Because we don't inline in `maybe_inline_local` if the output format is JSON,
+            // we need to make a special check for JSON output: we want to keep it unless it has
+            // a `#[doc(hidden)]` attribute if the `for_` type is exported.
             if let Some(did) = imp.for_.def_id(self.cache) {
-                if did.is_local() && !imp.for_.is_assoc_ty() && !self.retained.contains(&did.into())
-                {
+                if !imp.for_.is_assoc_ty() && !self.should_keep_impl(&i, did) {
                     debug!("ImplStripper: impl item for stripped type; removing");
                     return None;
                 }
             }
             if let Some(did) = imp.trait_.as_ref().map(|t| t.def_id()) {
-                if did.is_local() && !self.retained.contains(&did.into()) {
+                if !self.should_keep_impl(&i, did) {
                     debug!("ImplStripper: impl item for stripped trait; removing");
                     return None;
                 }
@@ -194,7 +224,7 @@ impl<'a> DocFolder for ImplStripper<'a> {
             if let Some(generics) = imp.trait_.as_ref().and_then(|t| t.generics()) {
                 for typaram in generics {
                     if let Some(did) = typaram.def_id(self.cache) {
-                        if did.is_local() && !self.retained.contains(&did.into()) {
+                        if !self.should_keep_impl(&i, did) {
                             debug!(
                                 "ImplStripper: stripped item in trait's generics; removing impl"
                             );
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index b8522ea5d8f..7ee7eb25e0d 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -7,15 +7,14 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::Node;
 use rustc_hir::CRATE_HIR_ID;
-use rustc_middle::middle::privacy::AccessLevel;
-use rustc_middle::ty::{TyCtxt, Visibility};
+use rustc_middle::ty::TyCtxt;
 use rustc_span::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::Span;
 
 use std::mem;
 
-use crate::clean::{self, cfg::Cfg, AttributesExt, NestedAttributesExt};
+use crate::clean::{cfg::Cfg, AttributesExt, NestedAttributesExt};
 use crate::core;
 
 /// This module is used to store stuff from Rust's AST in a more convenient
@@ -221,23 +220,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         // made reachable by cross-crate inlining which we're checking here.
         // (this is done here because we need to know this upfront).
         if !res_did.is_local() && !is_no_inline {
-            let attrs = clean::inline::load_attrs(self.cx, res_did);
-            let self_is_hidden = attrs.lists(sym::doc).has_word(sym::hidden);
-            if !self_is_hidden {
-                if let Res::Def(kind, did) = res {
-                    if kind == DefKind::Mod {
-                        crate::visit_lib::LibEmbargoVisitor::new(self.cx).visit_mod(did)
-                    } else {
-                        // All items need to be handled here in case someone wishes to link
-                        // to them with intra-doc links
-                        self.cx.cache.access_levels.set_access_level(
-                            did,
-                            || Visibility::Restricted(CRATE_DEF_ID),
-                            AccessLevel::Public,
-                        );
-                    }
-                }
-            }
+            crate::visit_lib::lib_embargo_visit_item(self.cx, res_did);
             return false;
         }
 
@@ -246,7 +229,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             None => return false,
         };
 
-        let is_private = !self.cx.cache.access_levels.is_public(res_did);
+        let is_private =
+            !self.cx.cache.effective_visibilities.is_directly_public(self.cx.tcx, res_did);
         let is_hidden = inherits_doc_hidden(self.cx.tcx, res_hir_id);
 
         // Only inline if requested or if the item would otherwise be stripped.
@@ -295,11 +279,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         debug!("visiting item {:?}", item);
         let name = renamed.unwrap_or(item.ident.name);
 
-        let def_id = item.def_id.to_def_id();
+        let def_id = item.owner_id.to_def_id();
         let is_pub = self.cx.tcx.visibility(def_id).is_public();
 
         if is_pub {
-            self.store_path(item.def_id.to_def_id());
+            self.store_path(item.owner_id.to_def_id());
         }
 
         match item.kind {
@@ -360,7 +344,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                 // 3. We're inlining, since a reexport where inlining has been requested
                 //    should be inlined even if it is also documented at the top level.
 
-                let def_id = item.def_id.to_def_id();
+                let def_id = item.owner_id.to_def_id();
                 let is_macro_2_0 = !macro_def.macro_rules;
                 let nonexported = !self.cx.tcx.has_attr(def_id, sym::macro_export);
 
@@ -405,7 +389,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         om: &mut Module<'tcx>,
     ) {
         // If inlining we only want to include public functions.
-        if !self.inlining || self.cx.tcx.visibility(item.def_id).is_public() {
+        if !self.inlining || self.cx.tcx.visibility(item.owner_id).is_public() {
             om.foreigns.push((item, renamed));
         }
     }
diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs
index 0511494668b..e490559b0e9 100644
--- a/src/librustdoc/visit_lib.rs
+++ b/src/librustdoc/visit_lib.rs
@@ -1,86 +1,74 @@
+use crate::core::DocContext;
 use rustc_data_structures::fx::FxHashSet;
-use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_ID};
-use rustc_middle::middle::privacy::{AccessLevel, AccessLevels};
-use rustc_middle::ty::{TyCtxt, Visibility};
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::DefId;
+use rustc_middle::ty::TyCtxt;
 
 // FIXME: this may not be exhaustive, but is sufficient for rustdocs current uses
 
-/// Similar to `librustc_privacy::EmbargoVisitor`, but also takes
-/// specific rustdoc annotations into account (i.e., `doc(hidden)`)
-pub(crate) struct LibEmbargoVisitor<'a, 'tcx> {
-    tcx: TyCtxt<'tcx>,
-    // Accessibility levels for reachable nodes
-    access_levels: &'a mut AccessLevels<DefId>,
-    // Previous accessibility level, None means unreachable
-    prev_level: Option<AccessLevel>,
-    // Keeps track of already visited modules, in case a module re-exports its parent
-    visited_mods: FxHashSet<DefId>,
+#[derive(Default)]
+pub(crate) struct RustdocEffectiveVisibilities {
+    extern_public: FxHashSet<DefId>,
 }
 
-impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
-    pub(crate) fn new(cx: &'a mut crate::core::DocContext<'tcx>) -> LibEmbargoVisitor<'a, 'tcx> {
-        LibEmbargoVisitor {
-            tcx: cx.tcx,
-            access_levels: &mut cx.cache.access_levels,
-            prev_level: Some(AccessLevel::Public),
-            visited_mods: FxHashSet::default(),
+macro_rules! define_method {
+    ($method:ident) => {
+        pub(crate) fn $method(&self, tcx: TyCtxt<'_>, def_id: DefId) -> bool {
+            match def_id.as_local() {
+                Some(def_id) => tcx.effective_visibilities(()).$method(def_id),
+                None => self.extern_public.contains(&def_id),
+            }
         }
-    }
-
-    pub(crate) fn visit_lib(&mut self, cnum: CrateNum) {
-        let did = cnum.as_def_id();
-        self.update(did, Some(AccessLevel::Public));
-        self.visit_mod(did);
-    }
+    };
+}
 
-    // Updates node level and returns the updated level
-    fn update(&mut self, did: DefId, level: Option<AccessLevel>) -> Option<AccessLevel> {
-        let is_hidden = self.tcx.is_doc_hidden(did);
+impl RustdocEffectiveVisibilities {
+    define_method!(is_directly_public);
+    define_method!(is_exported);
+    define_method!(is_reachable);
+}
 
-        let old_level = self.access_levels.get_access_level(did);
-        // Accessibility levels can only grow
-        if level > old_level && !is_hidden {
-            self.access_levels.set_access_level(
-                did,
-                || Visibility::Restricted(CRATE_DEF_ID),
-                level.unwrap(),
-            );
-            level
-        } else {
-            old_level
-        }
+pub(crate) fn lib_embargo_visit_item(cx: &mut DocContext<'_>, def_id: DefId) {
+    assert!(!def_id.is_local());
+    LibEmbargoVisitor {
+        tcx: cx.tcx,
+        extern_public: &mut cx.cache.effective_visibilities.extern_public,
+        visited_mods: Default::default(),
     }
+    .visit_item(def_id)
+}
+
+/// Similar to `librustc_privacy::EmbargoVisitor`, but also takes
+/// specific rustdoc annotations into account (i.e., `doc(hidden)`)
+struct LibEmbargoVisitor<'a, 'tcx> {
+    tcx: TyCtxt<'tcx>,
+    // Effective visibilities for reachable nodes
+    extern_public: &'a mut FxHashSet<DefId>,
+    // Keeps track of already visited modules, in case a module re-exports its parent
+    visited_mods: FxHashSet<DefId>,
+}
 
-    pub(crate) fn visit_mod(&mut self, def_id: DefId) {
+impl LibEmbargoVisitor<'_, '_> {
+    fn visit_mod(&mut self, def_id: DefId) {
         if !self.visited_mods.insert(def_id) {
             return;
         }
 
         for item in self.tcx.module_children(def_id).iter() {
             if let Some(def_id) = item.res.opt_def_id() {
-                if self.tcx.def_key(def_id).parent.map_or(false, |d| d == def_id.index)
-                    || item.vis.is_public()
-                {
-                    self.visit_item(item.res);
+                if item.vis.is_public() {
+                    self.visit_item(def_id);
                 }
             }
         }
     }
 
-    fn visit_item(&mut self, res: Res<!>) {
-        let def_id = res.def_id();
-        let vis = self.tcx.visibility(def_id);
-        let inherited_item_level = if vis.is_public() { self.prev_level } else { None };
-
-        let item_level = self.update(def_id, inherited_item_level);
-
-        if let Res::Def(DefKind::Mod, _) = res {
-            let orig_level = self.prev_level;
-
-            self.prev_level = item_level;
-            self.visit_mod(def_id);
-            self.prev_level = orig_level;
+    fn visit_item(&mut self, def_id: DefId) {
+        if !self.tcx.is_doc_hidden(def_id) {
+            self.extern_public.insert(def_id);
+            if self.tcx.def_kind(def_id) == DefKind::Mod {
+                self.visit_mod(def_id);
+            }
         }
     }
 }
diff --git a/src/llvm-project b/src/llvm-project
-Subproject 4b85255772114ca4946d95fe591933dae7d6199
+Subproject 2a2ea6b49e79325e0d10d33fac2b10ea3bebcc7
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index 7379b04ad16..4bc91fc4030 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -51,6 +51,11 @@ pub struct ItemSummary {
     pub crate_id: u32,
     /// The list of path components for the fully qualified path of this item (e.g.
     /// `["std", "io", "lazy", "Lazy"]` for `std::io::lazy::Lazy`).
+    ///
+    /// Note that items can appear in multiple paths, and the one chosen is implementation
+    /// defined. Currenty, this is the full path to where the item was defined. Eg
+    /// [`String`] is currently `["alloc", "string", "String"]` and [`HashMap`] is
+    /// `["std", "collections", "hash", "map", "HashMap"]`, but this is subject to change.
     pub path: Vec<String>,
     /// Whether this item is a struct, trait, macro, etc.
     pub kind: ItemKind,
diff --git a/src/test/codegen/issue-103285-ptr-addr-overflow-check.rs b/src/test/codegen/issue-103285-ptr-addr-overflow-check.rs
new file mode 100644
index 00000000000..a3499babea2
--- /dev/null
+++ b/src/test/codegen/issue-103285-ptr-addr-overflow-check.rs
@@ -0,0 +1,16 @@
+// compile-flags: -O -C debug-assertions=yes
+
+#![crate_type = "lib"]
+#![feature(strict_provenance)]
+
+#[no_mangle]
+pub fn test(src: *const u8, dst: *const u8) -> usize {
+    // CHECK-LABEL: @test(
+    // CHECK-NOT: panic
+    let src_usize = src.addr();
+    let dst_usize = dst.addr();
+    if src_usize > dst_usize {
+        return src_usize - dst_usize;
+    }
+    return 0;
+}
diff --git a/src/test/codegen/match-optimized.rs b/src/test/codegen/match-optimized.rs
new file mode 100644
index 00000000000..36402cc7353
--- /dev/null
+++ b/src/test/codegen/match-optimized.rs
@@ -0,0 +1,60 @@
+// compile-flags: -C no-prepopulate-passes -O
+
+#![crate_type = "lib"]
+
+pub enum E {
+    A,
+    B,
+    C,
+}
+
+// CHECK-LABEL: @exhaustive_match
+#[no_mangle]
+pub fn exhaustive_match(e: E) -> u8 {
+// CHECK: switch{{.*}}, label %[[OTHERWISE:[a-zA-Z0-9_]+]] [
+// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[A:[a-zA-Z0-9_]+]]
+// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[B:[a-zA-Z0-9_]+]]
+// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[C:[a-zA-Z0-9_]+]]
+// CHECK-NEXT: ]
+// CHECK: [[OTHERWISE]]:
+// CHECK-NEXT: unreachable
+//
+// CHECK: [[A]]:
+// CHECK-NEXT: store i8 0, {{i8\*|ptr}} %1, align 1
+// CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]]
+// CHECK: [[B]]:
+// CHECK-NEXT: store i8 1, {{i8\*|ptr}} %1, align 1
+// CHECK-NEXT: br label %[[EXIT]]
+// CHECK: [[C]]:
+// CHECK-NEXT: store i8 2, {{i8\*|ptr}} %1, align 1
+// CHECK-NEXT: br label %[[EXIT]]
+    match e {
+        E::A => 0,
+        E::B => 1,
+        E::C => 2,
+    }
+}
+
+#[repr(u16)]
+pub enum E2 {
+    A = 13,
+    B = 42,
+}
+
+// For optimized code we produce a switch with an unreachable target as the `otherwise` so LLVM
+// knows the possible values. Compare with `src/test/codegen/match-unoptimized.rs`.
+
+// CHECK-LABEL: @exhaustive_match_2
+#[no_mangle]
+pub fn exhaustive_match_2(e: E2) -> u8 {
+    // CHECK: switch i16 %{{.+}}, label %[[UNREACH:.+]] [
+    // CHECK-NEXT: i16 13,
+    // CHECK-NEXT: i16 42,
+    // CHECK-NEXT: ]
+    // CHECK: [[UNREACH]]:
+    // CHECK-NEXT: unreachable
+    match e {
+        E2::A => 0,
+        E2::B => 1,
+    }
+}
diff --git a/src/test/codegen/match-unoptimized.rs b/src/test/codegen/match-unoptimized.rs
new file mode 100644
index 00000000000..be40b29e3d3
--- /dev/null
+++ b/src/test/codegen/match-unoptimized.rs
@@ -0,0 +1,23 @@
+// compile-flags: -C no-prepopulate-passes -Copt-level=0
+
+#![crate_type = "lib"]
+
+#[repr(u16)]
+pub enum E2 {
+    A = 13,
+    B = 42,
+}
+
+// For unoptimized code we produce a `br` instead of a `switch`. Compare with
+// `src/test/codegen/match-optimized.rs`
+
+// CHECK-LABEL: @exhaustive_match_2
+#[no_mangle]
+pub fn exhaustive_match_2(e: E2) -> u8 {
+    // CHECK: %[[CMP:.+]] = icmp eq i16 %{{.+}}, 13
+    // CHECK-NEXT: br i1 %[[CMP:.+]],
+    match e {
+        E2::A => 0,
+        E2::B => 1,
+    }
+}
diff --git a/src/test/codegen/match.rs b/src/test/codegen/match.rs
deleted file mode 100644
index b203641fddb..00000000000
--- a/src/test/codegen/match.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-// compile-flags: -C no-prepopulate-passes
-
-#![crate_type = "lib"]
-
-pub enum E {
-    A,
-    B,
-}
-
-// CHECK-LABEL: @exhaustive_match
-#[no_mangle]
-pub fn exhaustive_match(e: E) -> u8 {
-// CHECK: switch{{.*}}, label %[[OTHERWISE:[a-zA-Z0-9_]+]] [
-// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[A:[a-zA-Z0-9_]+]]
-// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[B:[a-zA-Z0-9_]+]]
-// CHECK-NEXT: ]
-// CHECK: [[OTHERWISE]]:
-// CHECK-NEXT: unreachable
-// CHECK: [[A]]:
-// CHECK-NEXT: store i8 0, {{i8\*|ptr}} %1, align 1
-// CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]]
-// CHECK: [[B]]:
-// CHECK-NEXT: store i8 1, {{i8\*|ptr}} %1, align 1
-// CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]]
-    match e {
-        E::A => 0,
-        E::B => 1,
-    }
-}
diff --git a/src/test/codegen/mir-inlined-line-numbers.rs b/src/test/codegen/mir-inlined-line-numbers.rs
new file mode 100644
index 00000000000..19d83f0eee7
--- /dev/null
+++ b/src/test/codegen/mir-inlined-line-numbers.rs
@@ -0,0 +1,25 @@
+// compile-flags: -O -g
+
+#![crate_type = "lib"]
+
+#[inline(always)]
+fn foo() {
+    bar();
+}
+
+#[inline(never)]
+#[no_mangle]
+fn bar() {
+    panic!();
+}
+
+#[no_mangle]
+pub fn example() {
+    foo();
+}
+
+// CHECK-LABEL: @example
+// CHECK:   tail call void @bar(), !dbg [[DBG_ID:![0-9]+]]
+// CHECK: [[DBG_ID]] = !DILocation(line: 7,
+// CHECK-SAME:                     inlinedAt: [[INLINE_ID:![0-9]+]])
+// CHECK: [[INLINE_ID]] = !DILocation(line: 18,
diff --git a/src/test/mir-opt/enum_cast.bar.mir_map.0.mir b/src/test/mir-opt/building/enum_cast.bar.built.after.mir
index e58085f701a..194b107bead 100644
--- a/src/test/mir-opt/enum_cast.bar.mir_map.0.mir
+++ b/src/test/mir-opt/building/enum_cast.bar.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `bar` 0 mir_map
+// MIR for `bar` after built
 
 fn bar(_1: Bar) -> usize {
     debug bar => _1;                     // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11
diff --git a/src/test/mir-opt/enum_cast.boo.mir_map.0.mir b/src/test/mir-opt/building/enum_cast.boo.built.after.mir
index 525c6234ed3..dde26afc77a 100644
--- a/src/test/mir-opt/enum_cast.boo.mir_map.0.mir
+++ b/src/test/mir-opt/building/enum_cast.boo.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `boo` 0 mir_map
+// MIR for `boo` after built
 
 fn boo(_1: Boo) -> usize {
     debug boo => _1;                     // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11
diff --git a/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir b/src/test/mir-opt/building/enum_cast.droppy.built.after.mir
index bb5faa48047..a43c523c71f 100644
--- a/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir
+++ b/src/test/mir-opt/building/enum_cast.droppy.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `droppy` 0 mir_map
+// MIR for `droppy` after built
 
 fn droppy() -> () {
     let mut _0: ();                      // return place in scope 0 at $DIR/enum_cast.rs:+0:13: +0:13
diff --git a/src/test/mir-opt/enum_cast.foo.mir_map.0.mir b/src/test/mir-opt/building/enum_cast.foo.built.after.mir
index a1d29a0b903..17e0abf2e31 100644
--- a/src/test/mir-opt/enum_cast.foo.mir_map.0.mir
+++ b/src/test/mir-opt/building/enum_cast.foo.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `foo` 0 mir_map
+// MIR for `foo` after built
 
 fn foo(_1: Foo) -> usize {
     debug foo => _1;                     // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11
diff --git a/src/test/mir-opt/enum_cast.rs b/src/test/mir-opt/building/enum_cast.rs
index 090142aaf35..98fd5acfb14 100644
--- a/src/test/mir-opt/enum_cast.rs
+++ b/src/test/mir-opt/building/enum_cast.rs
@@ -1,6 +1,6 @@
-// EMIT_MIR enum_cast.foo.mir_map.0.mir
-// EMIT_MIR enum_cast.bar.mir_map.0.mir
-// EMIT_MIR enum_cast.boo.mir_map.0.mir
+// EMIT_MIR enum_cast.foo.built.after.mir
+// EMIT_MIR enum_cast.bar.built.after.mir
+// EMIT_MIR enum_cast.boo.built.after.mir
 
 enum Foo {
     A
@@ -27,7 +27,7 @@ fn boo(boo: Boo) -> usize {
     boo as usize
 }
 
-// EMIT_MIR enum_cast.droppy.mir_map.0.mir
+// EMIT_MIR enum_cast.droppy.built.after.mir
 enum Droppy {
     A, B, C
 }
diff --git a/src/test/mir-opt/issue-101867.rs b/src/test/mir-opt/building/issue-101867.rs
index 8a357eb7995..a32d8cb3714 100644
--- a/src/test/mir-opt/issue-101867.rs
+++ b/src/test/mir-opt/building/issue-101867.rs
@@ -1,4 +1,4 @@
-// EMIT_MIR issue_101867.main.mir_map.0.mir
+// EMIT_MIR issue_101867.main.built.after.mir
 fn main() {
     let x: Option<u8> = Some(1);
     let Some(y) = x else {
diff --git a/src/test/mir-opt/issue-49232.rs b/src/test/mir-opt/building/issue-49232.rs
index 86494c76aec..7e9f0de81f7 100644
--- a/src/test/mir-opt/issue-49232.rs
+++ b/src/test/mir-opt/building/issue-49232.rs
@@ -1,7 +1,7 @@
 // We must mark a variable whose initialization fails due to an
 // abort statement as StorageDead.
 
-// EMIT_MIR issue_49232.main.mir_map.0.mir
+// EMIT_MIR issue_49232.main.built.after.mir
 fn main() {
     loop {
         let beacon = {
diff --git a/src/test/mir-opt/issue_101867.main.mir_map.0.mir b/src/test/mir-opt/building/issue_101867.main.built.after.mir
index 42a9e558760..6834205b649 100644
--- a/src/test/mir-opt/issue_101867.main.mir_map.0.mir
+++ b/src/test/mir-opt/building/issue_101867.main.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `main` 0 mir_map
+// MIR for `main` after built
 
 | User Type Annotations
 | 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option<u8>) }, span: $DIR/issue-101867.rs:3:12: 3:22, inferred_ty: std::option::Option<u8>
diff --git a/src/test/mir-opt/issue_49232.main.mir_map.0.mir b/src/test/mir-opt/building/issue_49232.main.built.after.mir
index 821323b5e24..b90f8c13589 100644
--- a/src/test/mir-opt/issue_49232.main.mir_map.0.mir
+++ b/src/test/mir-opt/building/issue_49232.main.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `main` 0 mir_map
+// MIR for `main` after built
 
 fn main() -> () {
     let mut _0: ();                      // return place in scope 0 at $DIR/issue-49232.rs:+0:11: +0:11
diff --git a/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir b/src/test/mir-opt/building/match_false_edges.full_tested_match.built.after.mir
index b193a8d76fc..9a190c3d60e 100644
--- a/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir
+++ b/src/test/mir-opt/building/match_false_edges.full_tested_match.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `full_tested_match` after PromoteTemps
+// MIR for `full_tested_match` after built
 
 fn full_tested_match() -> () {
     let mut _0: ();                      // return place in scope 0 at $DIR/match_false_edges.rs:+0:28: +0:28
@@ -12,7 +12,6 @@ fn full_tested_match() -> () {
     let mut _8: i32;                     // in scope 0 at $DIR/match_false_edges.rs:+2:35: +2:36
     let _9: i32;                         // in scope 0 at $DIR/match_false_edges.rs:+3:14: +3:15
     let mut _10: i32;                    // in scope 0 at $DIR/match_false_edges.rs:+3:24: +3:25
-    let mut _11: &std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
     scope 1 {
     }
     scope 2 {
@@ -34,7 +33,7 @@ fn full_tested_match() -> () {
 
     bb1: {
         _1 = (const 3_i32, const 3_i32); // scope 0 at $DIR/match_false_edges.rs:+4:17: +4:23
-        goto -> bb10;                    // scope 0 at $DIR/match_false_edges.rs:+4:17: +4:23
+        goto -> bb11;                    // scope 0 at $DIR/match_false_edges.rs:+4:17: +4:23
     }
 
     bb2: {
@@ -42,7 +41,7 @@ fn full_tested_match() -> () {
     }
 
     bb3: {
-        falseEdge -> [real: bb9, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:16
+        falseEdge -> [real: bb10, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:16
     }
 
     bb4: {
@@ -51,14 +50,10 @@ fn full_tested_match() -> () {
 
     bb5: {
         StorageLive(_6);                 // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
-        _11 = const _;                   // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
-                                         // mir::Constant
-                                         // + span: $DIR/match_false_edges.rs:14:14: 14:15
-                                         // + literal: Const { ty: &Option<i32>, val: Unevaluated(full_tested_match, [], Some(promoted[0])) }
-        _6 = &(((*_11) as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
+        _6 = &((_2 as Some).0: i32);     // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
         _4 = &shallow _2;                // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
         StorageLive(_7);                 // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
-        _7 = guard() -> [return: bb6, unwind: bb11]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+        _7 = guard() -> [return: bb6, unwind: bb12]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
                                          // mir::Constant
                                          // + span: $DIR/match_false_edges.rs:14:20: 14:25
                                          // + literal: Const { ty: fn() -> bool {guard}, val: Value(<ZST>) }
@@ -80,16 +75,20 @@ fn full_tested_match() -> () {
         StorageDead(_8);                 // scope 2 at $DIR/match_false_edges.rs:+2:36: +2:37
         StorageDead(_5);                 // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
         StorageDead(_6);                 // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
-        goto -> bb10;                    // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
+        goto -> bb11;                    // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
     }
 
     bb8: {
+        goto -> bb9;                     // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+    }
+
+    bb9: {
         StorageDead(_7);                 // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27
         StorageDead(_6);                 // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
         goto -> bb3;                     // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
     }
 
-    bb9: {
+    bb10: {
         StorageLive(_9);                 // scope 0 at $DIR/match_false_edges.rs:+3:14: +3:15
         _9 = ((_2 as Some).0: i32);      // scope 0 at $DIR/match_false_edges.rs:+3:14: +3:15
         StorageLive(_10);                // scope 3 at $DIR/match_false_edges.rs:+3:24: +3:25
@@ -97,17 +96,17 @@ fn full_tested_match() -> () {
         _1 = (const 2_i32, move _10);    // scope 3 at $DIR/match_false_edges.rs:+3:20: +3:26
         StorageDead(_10);                // scope 3 at $DIR/match_false_edges.rs:+3:25: +3:26
         StorageDead(_9);                 // scope 0 at $DIR/match_false_edges.rs:+3:25: +3:26
-        goto -> bb10;                    // scope 0 at $DIR/match_false_edges.rs:+3:25: +3:26
+        goto -> bb11;                    // scope 0 at $DIR/match_false_edges.rs:+3:25: +3:26
     }
 
-    bb10: {
+    bb11: {
         StorageDead(_2);                 // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7
         StorageDead(_1);                 // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7
         _0 = const ();                   // scope 0 at $DIR/match_false_edges.rs:+0:28: +6:2
         return;                          // scope 0 at $DIR/match_false_edges.rs:+6:2: +6:2
     }
 
-    bb11 (cleanup): {
+    bb12 (cleanup): {
         resume;                          // scope 0 at $DIR/match_false_edges.rs:+0:1: +6:2
     }
 }
diff --git a/src/test/mir-opt/match_false_edges.full_tested_match2.PromoteTemps.before.mir b/src/test/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir
index 145ed878fc9..1c9953e7efc 100644
--- a/src/test/mir-opt/match_false_edges.full_tested_match2.PromoteTemps.before.mir
+++ b/src/test/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `full_tested_match2` before PromoteTemps
+// MIR for `full_tested_match2` after built
 
 fn full_tested_match2() -> () {
     let mut _0: ();                      // return place in scope 0 at $DIR/match_false_edges.rs:+0:29: +0:29
@@ -32,7 +32,7 @@ fn full_tested_match2() -> () {
     }
 
     bb1: {
-        falseEdge -> [real: bb9, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:13
+        falseEdge -> [real: bb10, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:13
     }
 
     bb2: {
@@ -47,7 +47,7 @@ fn full_tested_match2() -> () {
         _1 = (const 2_i32, move _10);    // scope 3 at $DIR/match_false_edges.rs:+4:20: +4:26
         StorageDead(_10);                // scope 3 at $DIR/match_false_edges.rs:+4:25: +4:26
         StorageDead(_9);                 // scope 0 at $DIR/match_false_edges.rs:+4:25: +4:26
-        goto -> bb10;                    // scope 0 at $DIR/match_false_edges.rs:+4:25: +4:26
+        goto -> bb11;                    // scope 0 at $DIR/match_false_edges.rs:+4:25: +4:26
     }
 
     bb4: {
@@ -59,7 +59,7 @@ fn full_tested_match2() -> () {
         _6 = &((_2 as Some).0: i32);     // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
         _4 = &shallow _2;                // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
         StorageLive(_7);                 // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
-        _7 = guard() -> [return: bb6, unwind: bb11]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+        _7 = guard() -> [return: bb6, unwind: bb12]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
                                          // mir::Constant
                                          // + span: $DIR/match_false_edges.rs:25:20: 25:25
                                          // + literal: Const { ty: fn() -> bool {guard}, val: Value(<ZST>) }
@@ -81,28 +81,32 @@ fn full_tested_match2() -> () {
         StorageDead(_8);                 // scope 2 at $DIR/match_false_edges.rs:+2:36: +2:37
         StorageDead(_5);                 // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
         StorageDead(_6);                 // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
-        goto -> bb10;                    // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
+        goto -> bb11;                    // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
     }
 
     bb8: {
+        goto -> bb9;                     // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+    }
+
+    bb9: {
         StorageDead(_7);                 // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27
         StorageDead(_6);                 // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
         falseEdge -> [real: bb3, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
     }
 
-    bb9: {
+    bb10: {
         _1 = (const 3_i32, const 3_i32); // scope 0 at $DIR/match_false_edges.rs:+3:17: +3:23
-        goto -> bb10;                    // scope 0 at $DIR/match_false_edges.rs:+3:17: +3:23
+        goto -> bb11;                    // scope 0 at $DIR/match_false_edges.rs:+3:17: +3:23
     }
 
-    bb10: {
+    bb11: {
         StorageDead(_2);                 // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7
         StorageDead(_1);                 // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7
         _0 = const ();                   // scope 0 at $DIR/match_false_edges.rs:+0:29: +6:2
         return;                          // scope 0 at $DIR/match_false_edges.rs:+6:2: +6:2
     }
 
-    bb11 (cleanup): {
+    bb12 (cleanup): {
         resume;                          // scope 0 at $DIR/match_false_edges.rs:+0:1: +6:2
     }
 }
diff --git a/src/test/mir-opt/match_false_edges.main.PromoteTemps.before.mir b/src/test/mir-opt/building/match_false_edges.main.built.after.mir
index 8f40e8a887f..08c67d39d78 100644
--- a/src/test/mir-opt/match_false_edges.main.PromoteTemps.before.mir
+++ b/src/test/mir-opt/building/match_false_edges.main.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `main` before PromoteTemps
+// MIR for `main` after built
 
 fn main() -> () {
     let mut _0: ();                      // return place in scope 0 at $DIR/match_false_edges.rs:+0:11: +0:11
@@ -43,41 +43,54 @@ fn main() -> () {
     }
 
     bb1: {
-        falseEdge -> [real: bb9, imaginary: bb4]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:11
+        falseEdge -> [real: bb13, imaginary: bb6]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:11
     }
 
     bb2: {
-        falseEdge -> [real: bb5, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:9: +2:17
+        falseEdge -> [real: bb8, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:9: +2:17
     }
 
     bb3: {
+        goto -> bb1;                     // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26
+    }
+
+    bb4: {
+        _3 = discriminant(_2);           // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26
+        switchInt(move _3) -> [1_isize: bb6, otherwise: bb5]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26
+    }
+
+    bb5: {
         StorageLive(_14);                // scope 0 at $DIR/match_false_edges.rs:+5:9: +5:11
         _14 = _2;                        // scope 0 at $DIR/match_false_edges.rs:+5:9: +5:11
         _1 = const 4_i32;                // scope 5 at $DIR/match_false_edges.rs:+5:15: +5:16
         StorageDead(_14);                // scope 0 at $DIR/match_false_edges.rs:+5:15: +5:16
-        goto -> bb14;                    // scope 0 at $DIR/match_false_edges.rs:+5:15: +5:16
+        goto -> bb19;                    // scope 0 at $DIR/match_false_edges.rs:+5:15: +5:16
     }
 
-    bb4: {
-        falseEdge -> [real: bb10, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:+4:9: +4:16
+    bb6: {
+        falseEdge -> [real: bb14, imaginary: bb5]; // scope 0 at $DIR/match_false_edges.rs:+4:9: +4:16
     }
 
-    bb5: {
+    bb7: {
+        goto -> bb5;                     // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26
+    }
+
+    bb8: {
         StorageLive(_7);                 // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:16
         _7 = &((_2 as Some).0: i32);     // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:16
         _5 = &shallow _2;                // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26
         StorageLive(_8);                 // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
-        _8 = guard() -> [return: bb6, unwind: bb15]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
+        _8 = guard() -> [return: bb9, unwind: bb20]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
                                          // mir::Constant
                                          // + span: $DIR/match_false_edges.rs:34:21: 34:26
                                          // + literal: Const { ty: fn() -> bool {guard}, val: Value(<ZST>) }
     }
 
-    bb6: {
-        switchInt(move _8) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
+    bb9: {
+        switchInt(move _8) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
     }
 
-    bb7: {
+    bb10: {
         StorageDead(_8);                 // scope 0 at $DIR/match_false_edges.rs:+2:27: +2:28
         FakeRead(ForMatchGuard, _5);     // scope 0 at $DIR/match_false_edges.rs:+2:27: +2:28
         FakeRead(ForGuardBinding, _7);   // scope 0 at $DIR/match_false_edges.rs:+2:27: +2:28
@@ -86,41 +99,45 @@ fn main() -> () {
         _1 = const 1_i32;                // scope 2 at $DIR/match_false_edges.rs:+2:32: +2:33
         StorageDead(_6);                 // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33
         StorageDead(_7);                 // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33
-        goto -> bb14;                    // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33
+        goto -> bb19;                    // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33
     }
 
-    bb8: {
+    bb11: {
+        goto -> bb12;                    // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
+    }
+
+    bb12: {
         StorageDead(_8);                 // scope 0 at $DIR/match_false_edges.rs:+2:27: +2:28
         StorageDead(_7);                 // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33
-        falseEdge -> [real: bb1, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
+        falseEdge -> [real: bb3, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
     }
 
-    bb9: {
+    bb13: {
         StorageLive(_9);                 // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:11
         _9 = _2;                         // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:11
         _1 = const 2_i32;                // scope 3 at $DIR/match_false_edges.rs:+3:15: +3:16
         StorageDead(_9);                 // scope 0 at $DIR/match_false_edges.rs:+3:15: +3:16
-        goto -> bb14;                    // scope 0 at $DIR/match_false_edges.rs:+3:15: +3:16
+        goto -> bb19;                    // scope 0 at $DIR/match_false_edges.rs:+3:15: +3:16
     }
 
-    bb10: {
+    bb14: {
         StorageLive(_11);                // scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15
         _11 = &((_2 as Some).0: i32);    // scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15
         _5 = &shallow _2;                // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26
         StorageLive(_12);                // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
         StorageLive(_13);                // scope 0 at $DIR/match_false_edges.rs:+4:27: +4:28
         _13 = (*_11);                    // scope 0 at $DIR/match_false_edges.rs:+4:27: +4:28
-        _12 = guard2(move _13) -> [return: bb11, unwind: bb15]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
+        _12 = guard2(move _13) -> [return: bb15, unwind: bb20]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
                                          // mir::Constant
                                          // + span: $DIR/match_false_edges.rs:36:20: 36:26
                                          // + literal: Const { ty: fn(i32) -> bool {guard2}, val: Value(<ZST>) }
     }
 
-    bb11: {
-        switchInt(move _12) -> [false: bb13, otherwise: bb12]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
+    bb15: {
+        switchInt(move _12) -> [false: bb17, otherwise: bb16]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
     }
 
-    bb12: {
+    bb16: {
         StorageDead(_13);                // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29
         StorageDead(_12);                // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29
         FakeRead(ForMatchGuard, _5);     // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29
@@ -130,24 +147,28 @@ fn main() -> () {
         _1 = const 3_i32;                // scope 4 at $DIR/match_false_edges.rs:+4:33: +4:34
         StorageDead(_10);                // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34
         StorageDead(_11);                // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34
-        goto -> bb14;                    // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34
+        goto -> bb19;                    // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34
     }
 
-    bb13: {
+    bb17: {
+        goto -> bb18;                    // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
+    }
+
+    bb18: {
         StorageDead(_13);                // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29
         StorageDead(_12);                // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29
         StorageDead(_11);                // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34
-        falseEdge -> [real: bb3, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
+        falseEdge -> [real: bb7, imaginary: bb5]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
     }
 
-    bb14: {
+    bb19: {
         StorageDead(_2);                 // scope 0 at $DIR/match_false_edges.rs:+6:6: +6:7
         StorageDead(_1);                 // scope 0 at $DIR/match_false_edges.rs:+6:6: +6:7
         _0 = const ();                   // scope 0 at $DIR/match_false_edges.rs:+0:11: +7:2
         return;                          // scope 0 at $DIR/match_false_edges.rs:+7:2: +7:2
     }
 
-    bb15 (cleanup): {
+    bb20 (cleanup): {
         resume;                          // scope 0 at $DIR/match_false_edges.rs:+0:1: +7:2
     }
 }
diff --git a/src/test/mir-opt/match_false_edges.rs b/src/test/mir-opt/building/match_false_edges.rs
index 3603253dafc..ddfcc149319 100644
--- a/src/test/mir-opt/match_false_edges.rs
+++ b/src/test/mir-opt/building/match_false_edges.rs
@@ -8,7 +8,7 @@ fn guard2(_: i32) -> bool {
 
 // no_mangle to make sure this gets instantiated even in an executable.
 #[no_mangle]
-// EMIT_MIR match_false_edges.full_tested_match.PromoteTemps.after.mir
+// EMIT_MIR match_false_edges.full_tested_match.built.after.mir
 pub fn full_tested_match() {
     let _ = match Some(42) {
         Some(x) if guard() => (1, x),
@@ -19,7 +19,7 @@ pub fn full_tested_match() {
 
 // no_mangle to make sure this gets instantiated even in an executable.
 #[no_mangle]
-// EMIT_MIR match_false_edges.full_tested_match2.PromoteTemps.before.mir
+// EMIT_MIR match_false_edges.full_tested_match2.built.after.mir
 pub fn full_tested_match2() {
     let _ = match Some(42) {
         Some(x) if guard() => (1, x),
@@ -28,7 +28,7 @@ pub fn full_tested_match2() {
     };
 }
 
-// EMIT_MIR match_false_edges.main.PromoteTemps.before.mir
+// EMIT_MIR match_false_edges.main.built.after.mir
 fn main() {
     let _ = match Some(1) {
         Some(_w) if guard() => 1,
diff --git a/src/test/mir-opt/receiver-ptr-mutability.rs b/src/test/mir-opt/building/receiver-ptr-mutability.rs
index 8e2ff0451c6..668530968fe 100644
--- a/src/test/mir-opt/receiver-ptr-mutability.rs
+++ b/src/test/mir-opt/building/receiver-ptr-mutability.rs
@@ -1,4 +1,4 @@
-// EMIT_MIR receiver_ptr_mutability.main.mir_map.0.mir
+// EMIT_MIR receiver_ptr_mutability.main.built.after.mir
 
 #![feature(arbitrary_self_types)]
 
diff --git a/src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir b/src/test/mir-opt/building/receiver_ptr_mutability.main.built.after.mir
index 45797ec0607..0192bdc2d5e 100644
--- a/src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir
+++ b/src/test/mir-opt/building/receiver_ptr_mutability.main.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `main` 0 mir_map
+// MIR for `main` after built
 
 | User Type Annotations
 | 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:14:14: 14:23, inferred_ty: *mut Test
diff --git a/src/test/mir-opt/simple-match.rs b/src/test/mir-opt/building/simple-match.rs
index 103033c4e2b..0ef97dde636 100644
--- a/src/test/mir-opt/simple-match.rs
+++ b/src/test/mir-opt/building/simple-match.rs
@@ -1,7 +1,7 @@
 // Test that we don't generate unnecessarily large MIR for very simple matches
 
 
-// EMIT_MIR simple_match.match_bool.mir_map.0.mir
+// EMIT_MIR simple_match.match_bool.built.after.mir
 fn match_bool(x: bool) -> usize {
     match x {
         true => 10,
diff --git a/src/test/mir-opt/simple_match.match_bool.mir_map.0.mir b/src/test/mir-opt/building/simple_match.match_bool.built.after.mir
index 3bef6aa0579..5b101cbdee7 100644
--- a/src/test/mir-opt/simple_match.match_bool.mir_map.0.mir
+++ b/src/test/mir-opt/building/simple_match.match_bool.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `match_bool` 0 mir_map
+// MIR for `match_bool` after built
 
 fn match_bool(_1: bool) -> usize {
     debug x => _1;                       // in scope 0 at $DIR/simple-match.rs:+0:15: +0:16
diff --git a/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir b/src/test/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir
index e50067ea25e..1d3f77e079b 100644
--- a/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir
+++ b/src/test/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `XXX` 0 mir_map
+// MIR for `XXX` after built
 
 static XXX: &Foo = {
     let mut _0: &Foo;                    // return place in scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:13: +0:25
diff --git a/src/test/mir-opt/storage_live_dead_in_statics.rs b/src/test/mir-opt/building/storage_live_dead_in_statics.rs
index b03de8612fc..79f709148e3 100644
--- a/src/test/mir-opt/storage_live_dead_in_statics.rs
+++ b/src/test/mir-opt/building/storage_live_dead_in_statics.rs
@@ -1,7 +1,7 @@
 // Check that when we compile the static `XXX` into MIR, we do not
 // generate `StorageStart` or `StorageEnd` statements.
 
-// EMIT_MIR storage_live_dead_in_statics.XXX.mir_map.0.mir
+// EMIT_MIR storage_live_dead_in_statics.XXX.built.after.mir
 static XXX: &'static Foo = &Foo {
     tup: "hi",
     data: &[
diff --git a/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir b/src/test/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir
index 6a5021139cf..234cd083977 100644
--- a/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir
+++ b/src/test/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `move_out_by_subslice` 0 mir_map
+// MIR for `move_out_by_subslice` after built
 
 fn move_out_by_subslice() -> () {
     let mut _0: ();                      // return place in scope 0 at $DIR/uniform_array_move_out.rs:+0:27: +0:27
diff --git a/src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir b/src/test/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir
index 23a50b22ad1..24a189498d3 100644
--- a/src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir
+++ b/src/test/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `move_out_from_end` 0 mir_map
+// MIR for `move_out_from_end` after built
 
 fn move_out_from_end() -> () {
     let mut _0: ();                      // return place in scope 0 at $DIR/uniform_array_move_out.rs:+0:24: +0:24
diff --git a/src/test/mir-opt/uniform_array_move_out.rs b/src/test/mir-opt/building/uniform_array_move_out.rs
index 35e42552870..e925036ecf6 100644
--- a/src/test/mir-opt/uniform_array_move_out.rs
+++ b/src/test/mir-opt/building/uniform_array_move_out.rs
@@ -1,12 +1,12 @@
 #![feature(box_syntax)]
 
-// EMIT_MIR uniform_array_move_out.move_out_from_end.mir_map.0.mir
+// EMIT_MIR uniform_array_move_out.move_out_from_end.built.after.mir
 fn move_out_from_end() {
     let a = [box 1, box 2];
     let [.., _y] = a;
 }
 
-// EMIT_MIR uniform_array_move_out.move_out_by_subslice.mir_map.0.mir
+// EMIT_MIR uniform_array_move_out.move_out_by_subslice.built.after.mir
 fn move_out_by_subslice() {
     let a = [box 1, box 2];
     let [_y @ ..] = a;
diff --git a/src/test/mir-opt/const-promotion-extern-static.rs b/src/test/mir-opt/const-promotion-extern-static.rs
index a0d4e9b2c65..e4261cfe504 100644
--- a/src/test/mir-opt/const-promotion-extern-static.rs
+++ b/src/test/mir-opt/const-promotion-extern-static.rs
@@ -12,7 +12,7 @@ static mut BAR: *const &i32 = [&Y].as_ptr();
 // EMIT_MIR const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir
 static mut FOO: *const &i32 = [unsafe { &X }].as_ptr();
 
-// EMIT_MIR const_promotion_extern_static.BOP.mir_map.0.mir
+// EMIT_MIR const_promotion_extern_static.BOP.built.after.mir
 static BOP: &i32 = &13;
 
 fn main() {}
diff --git a/src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir b/src/test/mir-opt/const_promotion_extern_static.BOP.built.after.mir
index 90920fbe7f8..5bda86bbd4f 100644
--- a/src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir
+++ b/src/test/mir-opt/const_promotion_extern_static.BOP.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `BOP` 0 mir_map
+// MIR for `BOP` after built
 
 static BOP: &i32 = {
     let mut _0: &i32;                    // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:13: +0:17
diff --git a/src/test/mir-opt/graphviz.main.mir_map.0.dot b/src/test/mir-opt/graphviz.main.built.after.dot
index 8d1da7f1b96..8d1da7f1b96 100644
--- a/src/test/mir-opt/graphviz.main.mir_map.0.dot
+++ b/src/test/mir-opt/graphviz.main.built.after.dot
diff --git a/src/test/mir-opt/graphviz.rs b/src/test/mir-opt/graphviz.rs
index 074dba2c373..6906b86c2a5 100644
--- a/src/test/mir-opt/graphviz.rs
+++ b/src/test/mir-opt/graphviz.rs
@@ -1,5 +1,5 @@
 // Test graphviz output
 // compile-flags: -Z dump-mir-graphviz
 
-// EMIT_MIR graphviz.main.mir_map.0.dot
+// EMIT_MIR graphviz.main.built.after.dot
 fn main() {}
diff --git a/src/test/mir-opt/issue-72181-1.rs b/src/test/mir-opt/issue-72181-1.rs
index 91e98adbe80..8ae2599ec73 100644
--- a/src/test/mir-opt/issue-72181-1.rs
+++ b/src/test/mir-opt/issue-72181-1.rs
@@ -6,12 +6,12 @@
 
 enum Void {}
 
-// EMIT_MIR issue_72181_1.f.mir_map.0.mir
+// EMIT_MIR issue_72181_1.f.built.after.mir
 fn f(v: Void) -> ! {
     match v {}
 }
 
-// EMIT_MIR issue_72181_1.main.mir_map.0.mir
+// EMIT_MIR issue_72181_1.main.built.after.mir
 fn main() {
     let v: Void = unsafe {
         std::mem::transmute::<(), Void>(())
diff --git a/src/test/mir-opt/issue-72181.rs b/src/test/mir-opt/issue-72181.rs
index ebb5f5042fc..6a32d4bbee2 100644
--- a/src/test/mir-opt/issue-72181.rs
+++ b/src/test/mir-opt/issue-72181.rs
@@ -12,14 +12,14 @@ union Foo {
 }
 
 
-// EMIT_MIR issue_72181.foo.mir_map.0.mir
+// EMIT_MIR issue_72181.foo.built.after.mir
 fn foo(xs: [(Never, u32); 1]) -> u32 { xs[0].1 }
 
-// EMIT_MIR issue_72181.bar.mir_map.0.mir
+// EMIT_MIR issue_72181.bar.built.after.mir
 fn bar([(_, x)]: [(Never, u32); 1]) -> u32 { x }
 
 
-// EMIT_MIR issue_72181.main.mir_map.0.mir
+// EMIT_MIR issue_72181.main.built.after.mir
 fn main() {
     let _ = mem::size_of::<Foo>();
 
diff --git a/src/test/mir-opt/issue-91633.rs b/src/test/mir-opt/issue-91633.rs
index 8f66019857f..9127cacc97c 100644
--- a/src/test/mir-opt/issue-91633.rs
+++ b/src/test/mir-opt/issue-91633.rs
@@ -1,5 +1,5 @@
 // compile-flags: -Z mir-opt-level=0
-// EMIT_MIR issue_91633.hey.mir_map.0.mir
+// EMIT_MIR issue_91633.hey.built.after.mir
 fn hey<T> (it: &[T])
  where
      [T] : std::ops::Index<usize>,
@@ -7,7 +7,7 @@ fn hey<T> (it: &[T])
      let _ = &it[0];
  }
 
-// EMIT_MIR issue_91633.bar.mir_map.0.mir
+// EMIT_MIR issue_91633.bar.built.after.mir
 fn bar<T> (it: Box<[T]>)
  where
      [T] : std::ops::Index<usize>,
@@ -15,14 +15,14 @@ fn bar<T> (it: Box<[T]>)
      let _ = it[0];
  }
 
-// EMIT_MIR issue_91633.fun.mir_map.0.mir
+// EMIT_MIR issue_91633.fun.built.after.mir
 fn fun<T> (it: &[T]) -> &T
  {
      let f = &it[0];
      f
  }
 
-// EMIT_MIR issue_91633.foo.mir_map.0.mir
+// EMIT_MIR issue_91633.foo.built.after.mir
 fn foo<T: Clone> (it: Box<[T]>) -> T
  {
      let f = it[0].clone();
diff --git a/src/test/mir-opt/issue-99325.rs b/src/test/mir-opt/issue-99325.rs
index b79946ea8b5..fe819cddb2c 100644
--- a/src/test/mir-opt/issue-99325.rs
+++ b/src/test/mir-opt/issue-99325.rs
@@ -5,7 +5,7 @@ pub fn function_with_bytes<const BYTES: &'static [u8; 4]>() -> &'static [u8] {
     BYTES
 }
 
-// EMIT_MIR issue_99325.main.mir_map.0.mir
+// EMIT_MIR issue_99325.main.built.after.mir
 pub fn main() {
     assert_eq!(function_with_bytes::<b"AAAA">(), &[0x41, 0x41, 0x41, 0x41]);
     assert_eq!(function_with_bytes::<{ &[0x41, 0x41, 0x41, 0x41] }>(), b"AAAA");
diff --git a/src/test/mir-opt/issue_72181.bar.mir_map.0.mir b/src/test/mir-opt/issue_72181.bar.built.after.mir
index 972ce1d5078..aa9c9986aac 100644
--- a/src/test/mir-opt/issue_72181.bar.mir_map.0.mir
+++ b/src/test/mir-opt/issue_72181.bar.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `bar` 0 mir_map
+// MIR for `bar` after built
 
 fn bar(_1: [(Never, u32); 1]) -> u32 {
     let mut _0: u32;                     // return place in scope 0 at $DIR/issue-72181.rs:+0:40: +0:43
diff --git a/src/test/mir-opt/issue_72181.foo.mir_map.0.mir b/src/test/mir-opt/issue_72181.foo.built.after.mir
index 534f131ea93..1d771ad3656 100644
--- a/src/test/mir-opt/issue_72181.foo.mir_map.0.mir
+++ b/src/test/mir-opt/issue_72181.foo.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `foo` 0 mir_map
+// MIR for `foo` after built
 
 fn foo(_1: [(Never, u32); 1]) -> u32 {
     debug xs => _1;                      // in scope 0 at $DIR/issue-72181.rs:+0:8: +0:10
diff --git a/src/test/mir-opt/issue_72181.main.mir_map.0.mir b/src/test/mir-opt/issue_72181.main.built.after.mir
index 425906f84fc..afa09b16fe9 100644
--- a/src/test/mir-opt/issue_72181.main.mir_map.0.mir
+++ b/src/test/mir-opt/issue_72181.main.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `main` 0 mir_map
+// MIR for `main` after built
 
 fn main() -> () {
     let mut _0: ();                      // return place in scope 0 at $DIR/issue-72181.rs:+0:11: +0:11
diff --git a/src/test/mir-opt/issue_72181_1.f.mir_map.0.mir b/src/test/mir-opt/issue_72181_1.f.built.after.mir
index e1a35d88bf1..31e997f9b33 100644
--- a/src/test/mir-opt/issue_72181_1.f.mir_map.0.mir
+++ b/src/test/mir-opt/issue_72181_1.f.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `f` 0 mir_map
+// MIR for `f` after built
 
 fn f(_1: Void) -> ! {
     debug v => _1;                       // in scope 0 at $DIR/issue-72181-1.rs:+0:6: +0:7
diff --git a/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir b/src/test/mir-opt/issue_72181_1.main.built.after.mir
index 336693337fb..65177a81b03 100644
--- a/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir
+++ b/src/test/mir-opt/issue_72181_1.main.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `main` 0 mir_map
+// MIR for `main` after built
 
 | User Type Annotations
 | 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(Void) }, span: $DIR/issue-72181-1.rs:16:12: 16:16, inferred_ty: Void
diff --git a/src/test/mir-opt/issue_91633.bar.mir_map.0.mir b/src/test/mir-opt/issue_91633.bar.built.after.mir
index 625f6c7361a..19b1b6fe12b 100644
--- a/src/test/mir-opt/issue_91633.bar.mir_map.0.mir
+++ b/src/test/mir-opt/issue_91633.bar.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `bar` 0 mir_map
+// MIR for `bar` after built
 
 fn bar(_1: Box<[T]>) -> () {
     debug it => _1;                      // in scope 0 at $DIR/issue-91633.rs:+0:12: +0:14
diff --git a/src/test/mir-opt/issue_91633.foo.mir_map.0.mir b/src/test/mir-opt/issue_91633.foo.built.after.mir
index 9903e203a23..1a6eee93d36 100644
--- a/src/test/mir-opt/issue_91633.foo.mir_map.0.mir
+++ b/src/test/mir-opt/issue_91633.foo.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `foo` 0 mir_map
+// MIR for `foo` after built
 
 fn foo(_1: Box<[T]>) -> T {
     debug it => _1;                      // in scope 0 at $DIR/issue-91633.rs:+0:19: +0:21
diff --git a/src/test/mir-opt/issue_91633.fun.mir_map.0.mir b/src/test/mir-opt/issue_91633.fun.built.after.mir
index ded9a4cf7e3..b3eea600330 100644
--- a/src/test/mir-opt/issue_91633.fun.mir_map.0.mir
+++ b/src/test/mir-opt/issue_91633.fun.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `fun` 0 mir_map
+// MIR for `fun` after built
 
 fn fun(_1: &[T]) -> &T {
     debug it => _1;                      // in scope 0 at $DIR/issue-91633.rs:+0:12: +0:14
diff --git a/src/test/mir-opt/issue_91633.hey.mir_map.0.mir b/src/test/mir-opt/issue_91633.hey.built.after.mir
index 37c3b3fcaca..e7e31ad33c1 100644
--- a/src/test/mir-opt/issue_91633.hey.mir_map.0.mir
+++ b/src/test/mir-opt/issue_91633.hey.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `hey` 0 mir_map
+// MIR for `hey` after built
 
 fn hey(_1: &[T]) -> () {
     debug it => _1;                      // in scope 0 at $DIR/issue-91633.rs:+0:12: +0:14
diff --git a/src/test/mir-opt/issue_99325.main.mir_map.0.mir b/src/test/mir-opt/issue_99325.main.built.after.mir
index 165efa9df41..f588f06b7e4 100644
--- a/src/test/mir-opt/issue_99325.main.mir_map.0.mir
+++ b/src/test/mir-opt/issue_99325.main.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `main` 0 mir_map
+// MIR for `main` after built
 
 | User Type Annotations
 | 0: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Value(Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)])) }], user_self_ty: None }) }, span: $DIR/issue-99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
diff --git a/src/test/mir-opt/spanview-block.rs b/src/test/mir-opt/spanview-block.rs
index fc1d6e0ede6..0ecf35ad6a2 100644
--- a/src/test/mir-opt/spanview-block.rs
+++ b/src/test/mir-opt/spanview-block.rs
@@ -1,5 +1,5 @@
 // Test spanview block output
 // compile-flags: -Z dump-mir-spanview=block
 
-// EMIT_MIR spanview_block.main.mir_map.0.html
+// EMIT_MIR spanview_block.main.built.after.html
 fn main() {}
diff --git a/src/test/mir-opt/spanview-statement.rs b/src/test/mir-opt/spanview-statement.rs
index a43ad5e71a3..457052617b7 100644
--- a/src/test/mir-opt/spanview-statement.rs
+++ b/src/test/mir-opt/spanview-statement.rs
@@ -1,5 +1,5 @@
 // Test spanview output (the default value for `-Z dump-mir-spanview` is "statement")
 // compile-flags: -Z dump-mir-spanview
 
-// EMIT_MIR spanview_statement.main.mir_map.0.html
+// EMIT_MIR spanview_statement.main.built.after.html
 fn main() {}
diff --git a/src/test/mir-opt/spanview-terminator.rs b/src/test/mir-opt/spanview-terminator.rs
index 92e1411eadb..76fced188f1 100644
--- a/src/test/mir-opt/spanview-terminator.rs
+++ b/src/test/mir-opt/spanview-terminator.rs
@@ -1,5 +1,5 @@
 // Test spanview terminator output
 // compile-flags: -Z dump-mir-spanview=terminator
 
-// EMIT_MIR spanview_terminator.main.mir_map.0.html
+// EMIT_MIR spanview_terminator.main.built.after.html
 fn main() {}
diff --git a/src/test/mir-opt/spanview_block.main.mir_map.0.html b/src/test/mir-opt/spanview_block.main.built.after.html
index 8e5268043e7..fbf751d6d30 100644
--- a/src/test/mir-opt/spanview_block.main.mir_map.0.html
+++ b/src/test/mir-opt/spanview_block.main.built.after.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html>
 <head>
-<title>spanview_block.main.mir_map.0</title>
+<title>spanview_block.main.built.after</title>
 <style>
     .line {
         counter-increment: line;
diff --git a/src/test/mir-opt/spanview_statement.main.mir_map.0.html b/src/test/mir-opt/spanview_statement.main.built.after.html
index abbff2270b7..02b2720feef 100644
--- a/src/test/mir-opt/spanview_statement.main.mir_map.0.html
+++ b/src/test/mir-opt/spanview_statement.main.built.after.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html>
 <head>
-<title>spanview_statement.main.mir_map.0</title>
+<title>spanview_statement.main.built.after</title>
 <style>
     .line {
         counter-increment: line;
diff --git a/src/test/mir-opt/spanview_terminator.main.mir_map.0.html b/src/test/mir-opt/spanview_terminator.main.built.after.html
index 55fafd90b0a..a4cda7dd67e 100644
--- a/src/test/mir-opt/spanview_terminator.main.mir_map.0.html
+++ b/src/test/mir-opt/spanview_terminator.main.built.after.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html>
 <head>
-<title>spanview_terminator.main.mir_map.0</title>
+<title>spanview_terminator.main.built.after</title>
 <style>
     .line {
         counter-increment: line;
diff --git a/src/test/mir-opt/unusual-item-types.rs b/src/test/mir-opt/unusual-item-types.rs
index 9ef3d86472d..6dad636416f 100644
--- a/src/test/mir-opt/unusual-item-types.rs
+++ b/src/test/mir-opt/unusual-item-types.rs
@@ -5,19 +5,19 @@
 
 struct A;
 
-// EMIT_MIR unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.mir
+// EMIT_MIR unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir
 impl A {
     const ASSOCIATED_CONSTANT: i32 = 2;
 }
 
 // See #59021
-// EMIT_MIR unusual_item_types.Test-X-{constructor#0}.mir_map.0.mir
+// EMIT_MIR unusual_item_types.Test-X-{constructor#0}.built.after.mir
 enum Test {
     X(usize),
     Y { a: usize },
 }
 
-// EMIT_MIR unusual_item_types.E-V-{constant#0}.mir_map.0.mir
+// EMIT_MIR unusual_item_types.E-V-{constant#0}.built.after.mir
 enum E {
     V = 5,
 }
diff --git a/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.mir b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.built.after.mir
index a72e00ecde7..c8b0f8e41b7 100644
--- a/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.mir
+++ b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `E::V::{constant#0}` 0 mir_map
+// MIR for `E::V::{constant#0}` after built
 
 E::V::{constant#0}: isize = {
     let mut _0: isize;                   // return place in scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
diff --git a/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.mir b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.built.after.mir
index 0686af46ed5..a46e6017377 100644
--- a/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.mir
+++ b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `Test::X` 0 mir_map
+// MIR for `Test::X` after built
 
 fn Test::X(_1: usize) -> Test {
     let mut _0: Test;                    // return place in scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
diff --git a/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.mir b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir
index 5579d25a14f..7cb9050bc4b 100644
--- a/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.mir
+++ b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `<impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT` 0 mir_map
+// MIR for `<impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT` after built
 
 const <impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT: i32 = {
     let mut _0: i32;                     // return place in scope 0 at $DIR/unusual-item-types.rs:+0:32: +0:35
diff --git a/src/test/run-make-fulldeps/foreign-rust-exceptions/Makefile b/src/test/run-make-fulldeps/foreign-rust-exceptions/Makefile
new file mode 100644
index 00000000000..50fca7f24e6
--- /dev/null
+++ b/src/test/run-make-fulldeps/foreign-rust-exceptions/Makefile
@@ -0,0 +1,11 @@
+# ignore-i686-pc-windows-gnu
+
+# This test doesn't work on 32-bit MinGW as cdylib has its own copy of unwinder
+# so cross-DLL unwinding does not work.
+
+include ../tools.mk
+
+all:
+	$(RUSTC) bar.rs --crate-type=cdylib
+	$(RUSTC) foo.rs
+	$(call RUN,foo) 2>&1 | $(CGREP) "Rust cannot catch foreign exceptions"
diff --git a/src/test/run-make-fulldeps/foreign-rust-exceptions/bar.rs b/src/test/run-make-fulldeps/foreign-rust-exceptions/bar.rs
new file mode 100644
index 00000000000..5f9efe32360
--- /dev/null
+++ b/src/test/run-make-fulldeps/foreign-rust-exceptions/bar.rs
@@ -0,0 +1,7 @@
+#![crate_type = "cdylib"]
+#![feature(c_unwind)]
+
+#[no_mangle]
+extern "C-unwind" fn panic() {
+    panic!();
+}
diff --git a/src/test/run-make-fulldeps/foreign-rust-exceptions/foo.rs b/src/test/run-make-fulldeps/foreign-rust-exceptions/foo.rs
new file mode 100644
index 00000000000..266987c5b6d
--- /dev/null
+++ b/src/test/run-make-fulldeps/foreign-rust-exceptions/foo.rs
@@ -0,0 +1,13 @@
+#![feature(c_unwind)]
+
+#[cfg_attr(not(windows), link(name = "bar"))]
+#[cfg_attr(windows, link(name = "bar.dll"))]
+extern "C-unwind" {
+    fn panic();
+}
+
+fn main() {
+    let _ = std::panic::catch_unwind(|| {
+        unsafe { panic() };
+    });
+}
diff --git a/src/test/run-make-fulldeps/obtain-borrowck/driver.rs b/src/test/run-make-fulldeps/obtain-borrowck/driver.rs
index 8f78bda033e..a6c60df83a6 100644
--- a/src/test/run-make-fulldeps/obtain-borrowck/driver.rs
+++ b/src/test/run-make-fulldeps/obtain-borrowck/driver.rs
@@ -69,25 +69,25 @@ impl rustc_driver::Callbacks for CompilerCalls {
 
             let crate_items = tcx.hir_crate_items(());
             for id in crate_items.items() {
-                if matches!(tcx.def_kind(id.def_id), DefKind::Fn) {
-                    bodies.push(id.def_id);
+                if matches!(tcx.def_kind(id.owner_id), DefKind::Fn) {
+                    bodies.push(id.owner_id);
                 }
             }
 
             for id in crate_items.trait_items() {
-                if matches!(tcx.def_kind(id.def_id), DefKind::AssocFn) {
+                if matches!(tcx.def_kind(id.owner_id), DefKind::AssocFn) {
                     let trait_item = hir.trait_item(id);
                     if let rustc_hir::TraitItemKind::Fn(_, trait_fn) = &trait_item.kind {
                         if let rustc_hir::TraitFn::Provided(_) = trait_fn {
-                            bodies.push(trait_item.def_id);
+                            bodies.push(trait_item.owner_id);
                         }
                     }
                 }
             }
 
             for id in crate_items.impl_items() {
-                if matches!(tcx.def_kind(id.def_id), DefKind::AssocFn) {
-                    bodies.push(id.def_id);
+                if matches!(tcx.def_kind(id.owner_id), DefKind::AssocFn) {
+                    bodies.push(id.owner_id);
                 }
             }
 
diff --git a/src/test/run-make/test-benches/Makefile b/src/test/run-make/test-benches/Makefile
new file mode 100644
index 00000000000..8fc122515d0
--- /dev/null
+++ b/src/test/run-make/test-benches/Makefile
@@ -0,0 +1,11 @@
+include ../../run-make-fulldeps/tools.mk
+
+# ignore-cross-compile
+
+all:
+	# Smoke-test that `#[bench]` isn't entirely broken.
+	$(RUSTC) --test smokebench.rs -O
+	$(call RUN,smokebench --bench)
+	$(call RUN,smokebench --bench noiter)
+	$(call RUN,smokebench --bench yesiter)
+	$(call RUN,smokebench)
diff --git a/src/test/run-make/test-benches/smokebench.rs b/src/test/run-make/test-benches/smokebench.rs
new file mode 100644
index 00000000000..ef5e5a62068
--- /dev/null
+++ b/src/test/run-make/test-benches/smokebench.rs
@@ -0,0 +1,14 @@
+#![feature(test)]
+extern crate test;
+
+#[bench]
+fn smoke_yesiter(b: &mut test::Bencher) {
+    let mut i = 0usize;
+    b.iter(|| {
+        i = i.wrapping_add(1);
+        i
+    })
+}
+
+#[bench]
+fn smoke_noiter(_: &mut test::Bencher) {}
diff --git a/src/test/rustdoc-gui/source-code-page.goml b/src/test/rustdoc-gui/source-code-page.goml
index 29d65fc7ebc..a2dac2aa681 100644
--- a/src/test/rustdoc-gui/source-code-page.goml
+++ b/src/test/rustdoc-gui/source-code-page.goml
@@ -1,5 +1,6 @@
 // Checks that the interactions with the source code pages are working as expected.
 goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
+show-text: true
 // Check that we can click on the line number.
 click: ".src-line-numbers > span:nth-child(4)" // This is the span for line 4.
 // Ensure that the page URL was updated.
@@ -12,6 +13,48 @@ assert-attribute: (".src-line-numbers > span:nth-child(4)", {"class": "line-high
 assert-attribute: (".src-line-numbers > span:nth-child(5)", {"class": "line-highlighted"})
 assert-attribute: (".src-line-numbers > span:nth-child(6)", {"class": "line-highlighted"})
 assert-attribute-false: (".src-line-numbers > span:nth-child(7)", {"class": "line-highlighted"})
+
+define-function: (
+    "check-colors",
+    (theme, color, background_color, highlight_color, highlight_background_color),
+    [
+        ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+        ("reload"),
+        ("assert-css", (
+            ".src-line-numbers > span:not(.line-highlighted)",
+            {"color": |color|, "background-color": |background_color|},
+            ALL,
+        )),
+        ("assert-css", (
+            ".src-line-numbers > span.line-highlighted",
+            {"color": |highlight_color|, "background-color": |highlight_background_color|},
+            ALL,
+        )),
+    ],
+)
+
+call-function: ("check-colors", {
+    "theme": "ayu",
+    "color": "rgb(92, 103, 115)",
+    "background_color": "rgba(0, 0, 0, 0)",
+    "highlight_color": "rgb(112, 128, 144)",
+    "highlight_background_color": "rgba(255, 236, 164, 0.06)",
+})
+call-function: ("check-colors", {
+    "theme": "dark",
+    "color": "rgb(59, 145, 226)",
+    "background_color": "rgba(0, 0, 0, 0)",
+    "highlight_color": "rgb(59, 145, 226)",
+    "highlight_background_color": "rgb(10, 4, 47)",
+})
+call-function: ("check-colors", {
+    "theme": "light",
+    "color": "rgb(198, 126, 45)",
+    "background_color": "rgba(0, 0, 0, 0)",
+    "highlight_color": "rgb(198, 126, 45)",
+    "highlight_background_color": "rgb(253, 255, 211)",
+})
+
 // This is to ensure that the content is correctly align with the line numbers.
 compare-elements-position: ("//*[@id='1']", ".rust > code > span", ("y"))
 
@@ -20,7 +63,6 @@ assert-css: (".src-line-numbers", {"text-align": "right"})
 
 // Now let's check that clicking on something else than the line number doesn't
 // do anything (and certainly not add a `#NaN` to the URL!).
-show-text: true
 goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
 // We use this assert-position to know where we will click.
 assert-position: ("//*[@id='1']", {"x": 104, "y": 112})
diff --git a/src/test/rustdoc-js/reexport.js b/src/test/rustdoc-js/reexport.js
new file mode 100644
index 00000000000..871e75d9b2b
--- /dev/null
+++ b/src/test/rustdoc-js/reexport.js
@@ -0,0 +1,17 @@
+// exact-check
+
+const QUERY = ['Subscriber', 'AnotherOne'];
+
+const EXPECTED = [
+    {
+        'others': [
+            { 'path': 'reexport::fmt', 'name': 'Subscriber' },
+            { 'path': 'reexport', 'name': 'FmtSubscriber' },
+        ],
+    },
+    {
+        'others': [
+            { 'path': 'reexport', 'name': 'AnotherOne' },
+        ],
+    },
+];
diff --git a/src/test/rustdoc-js/reexport.rs b/src/test/rustdoc-js/reexport.rs
new file mode 100644
index 00000000000..d69b2901edd
--- /dev/null
+++ b/src/test/rustdoc-js/reexport.rs
@@ -0,0 +1,11 @@
+// This test enforces that the (renamed) reexports are present in the search results.
+
+pub mod fmt {
+    pub struct Subscriber;
+}
+mod foo {
+    pub struct AnotherOne;
+}
+
+pub use foo::AnotherOne;
+pub use fmt::Subscriber as FmtSubscriber;
diff --git a/src/test/rustdoc-json/reexport/reexport_method_from_private_module.rs b/src/test/rustdoc-json/reexport/reexport_method_from_private_module.rs
new file mode 100644
index 00000000000..239b1a23b43
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/reexport_method_from_private_module.rs
@@ -0,0 +1,28 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/102583>.
+
+// @set impl_S = "$.index[*][?(@.docs=='impl S')].id"
+// @has "$.index[*][?(@.name=='S')].inner.impls[*]" $impl_S
+// @set is_present = "$.index[*][?(@.name=='is_present')].id"
+// @is "$.index[*][?(@.docs=='impl S')].inner.items[*]" $is_present
+// @!has "$.index[*][?(@.name=='hidden_impl')]"
+// @!has "$.index[*][?(@.name=='hidden_fn')]"
+
+#![no_std]
+
+mod private_mod {
+    pub struct S;
+
+    /// impl S
+    impl S {
+        pub fn is_present() {}
+        #[doc(hidden)]
+        pub fn hidden_fn() {}
+    }
+
+    #[doc(hidden)]
+    impl S {
+        pub fn hidden_impl() {}
+    }
+}
+
+pub use private_mod::*;
diff --git a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr
index e7b4c43e790..19e541736bd 100644
--- a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr
+++ b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr
@@ -4,7 +4,7 @@ error: unknown disambiguator `foo`
 LL | //! Linking to [foo@banana] and [`bar@banana!()`].
    |                 ^^^
    |
-   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 note: the lint level is defined here
   --> $DIR/unknown-disambiguator.rs:2:9
    |
@@ -18,7 +18,7 @@ error: unknown disambiguator `bar`
 LL | //! Linking to [foo@banana] and [`bar@banana!()`].
    |                                   ^^^
    |
-   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
 error: unknown disambiguator `foo`
   --> $DIR/unknown-disambiguator.rs:10:34
@@ -26,7 +26,7 @@ error: unknown disambiguator `foo`
 LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello].
    |                                  ^^^
    |
-   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
 error: unknown disambiguator `foo`
   --> $DIR/unknown-disambiguator.rs:10:48
@@ -34,7 +34,7 @@ error: unknown disambiguator `foo`
 LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello].
    |                                                ^^^
    |
-   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
 error: unknown disambiguator ``
   --> $DIR/unknown-disambiguator.rs:7:31
@@ -42,7 +42,7 @@ error: unknown disambiguator ``
 LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()).
    |                               ^
    |
-   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
 error: unknown disambiguator ``
   --> $DIR/unknown-disambiguator.rs:7:57
@@ -50,7 +50,7 @@ error: unknown disambiguator ``
 LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()).
    |                                                         ^
    |
-   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/rustdoc/auxiliary/incoherent-impl-types.rs b/src/test/rustdoc/auxiliary/incoherent-impl-types.rs
new file mode 100644
index 00000000000..fc51e42e500
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/incoherent-impl-types.rs
@@ -0,0 +1,7 @@
+#![feature(rustc_attrs)]
+
+#[rustc_has_incoherent_inherent_impls]
+pub trait FooTrait {}
+
+#[rustc_has_incoherent_inherent_impls]
+pub struct FooStruct;
diff --git a/src/test/rustdoc/auxiliary/masked.rs b/src/test/rustdoc/auxiliary/masked.rs
index f289359e52a..3d722d5e0c2 100644
--- a/src/test/rustdoc/auxiliary/masked.rs
+++ b/src/test/rustdoc/auxiliary/masked.rs
@@ -8,3 +8,7 @@ pub trait MaskedTrait {
 impl MaskedTrait for String {
     fn masked_method() {}
 }
+
+pub trait MaskedBlanketTrait {}
+
+impl<T> MaskedBlanketTrait for T {}
diff --git a/src/test/rustdoc/auxiliary/reexport-doc-aux.rs b/src/test/rustdoc/auxiliary/reexport-doc-aux.rs
new file mode 100644
index 00000000000..3400717eba1
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/reexport-doc-aux.rs
@@ -0,0 +1,5 @@
+pub struct Foo;
+
+impl Foo {
+    pub fn foo() {}
+}
diff --git a/src/test/rustdoc/masked.rs b/src/test/rustdoc/masked.rs
index 80d5b99c0b0..875c026fd05 100644
--- a/src/test/rustdoc/masked.rs
+++ b/src/test/rustdoc/masked.rs
@@ -10,6 +10,7 @@ extern crate masked;
 // @!hasraw 'search-index.js' 'masked_method'
 
 // @!hasraw 'foo/struct.String.html' 'MaskedTrait'
+// @!hasraw 'foo/struct.String.html' 'MaskedBlanketTrait'
 // @!hasraw 'foo/struct.String.html' 'masked_method'
 pub use std::string::String;
 
diff --git a/src/test/rustdoc/reexport-doc.rs b/src/test/rustdoc/reexport-doc.rs
new file mode 100644
index 00000000000..df2c889b4d5
--- /dev/null
+++ b/src/test/rustdoc/reexport-doc.rs
@@ -0,0 +1,8 @@
+// aux-build:reexport-doc-aux.rs
+
+extern crate reexport_doc_aux as dep;
+
+// @has 'reexport_doc/struct.Foo.html'
+// @count - '//p' 'These are the docs for Foo.' 1
+/// These are the docs for Foo.
+pub use dep::Foo;
diff --git a/src/test/rustdoc/rustc-incoherent-impls.rs b/src/test/rustdoc/rustc-incoherent-impls.rs
new file mode 100644
index 00000000000..3fdefbecc54
--- /dev/null
+++ b/src/test/rustdoc/rustc-incoherent-impls.rs
@@ -0,0 +1,28 @@
+// aux-build:incoherent-impl-types.rs
+// build-aux-docs
+
+#![crate_name = "foo"]
+#![feature(rustc_attrs)]
+
+extern crate incoherent_impl_types;
+
+// The only way this actually shows up is if the type gets inlined.
+#[doc(inline)]
+pub use incoherent_impl_types::FooTrait;
+
+// @has foo/trait.FooTrait.html
+// @count - '//section[@id="method.do_something"]' 1
+impl dyn FooTrait {
+    #[rustc_allow_incoherent_impl]
+    pub fn do_something() {}
+}
+
+#[doc(inline)]
+pub use incoherent_impl_types::FooStruct;
+
+// @has foo/struct.FooStruct.html
+// @count - '//section[@id="method.do_something"]' 1
+impl FooStruct {
+    #[rustc_allow_incoherent_impl]
+    pub fn do_something() {}
+}
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr
index cc156016212..77841780f62 100644
--- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr
+++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr
@@ -15,19 +15,19 @@ LL |     let a = bar(f, x);
    = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
 
 error: lifetime may not live long enough
-  --> $DIR/project-fn-ret-invariant.rs:40:13
+  --> $DIR/project-fn-ret-invariant.rs:42:13
    |
 LL | fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
    |        --  -- lifetime `'b` defined here
    |        |
    |        lifetime `'a` defined here
-LL |     let f = foo; // <-- No consistent type can be inferred for `f` here.
-LL |     let a = bar(f, x);
+...
+LL |     let b = bar(f, y);
    |             ^^^^^^^^^ argument requires that `'b` must outlive `'a`
    |
    = help: consider adding the following bound: `'b: 'a`
-   = note: requirement occurs because of a function pointer to `foo`
-   = note: the function `foo` is invariant over the parameter `'a`
+   = note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
+   = note: the struct `Type<'a>` is invariant over the parameter `'a`
    = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
 
 help: `'a` and `'b` must be the same: replace one with the other
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs b/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs
index 1075fd6e092..e043379133a 100644
--- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs
+++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs
@@ -39,8 +39,8 @@ fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
     let f = foo; // <-- No consistent type can be inferred for `f` here.
     let a = bar(f, x);
     //[oneuse]~^ ERROR lifetime may not live long enough
-    //[oneuse]~| ERROR lifetime may not live long enough
     let b = bar(f, y);
+    //[oneuse]~^ ERROR lifetime may not live long enough
     (a, b)
 }
 
diff --git a/src/test/ui/async-await/in-trait/async-associated-types.rs b/src/test/ui/async-await/in-trait/async-associated-types.rs
new file mode 100644
index 00000000000..a6f928f3b1b
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-associated-types.rs
@@ -0,0 +1,24 @@
+// check-fail
+// known-bug: #102682
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+trait MyTrait<'a, 'b, T> where Self: 'a, T: Debug + Sized + 'b {
+    type MyAssoc;
+
+    async fn foo(&'a self, key: &'b T) -> Self::MyAssoc;
+}
+
+impl<'a, 'b, T: Debug + Sized + 'b, U: 'a> MyTrait<'a, 'b, T> for U {
+    type MyAssoc = (&'a U, &'b T);
+
+    async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
+        (self, key)
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-associated-types.stderr b/src/test/ui/async-await/in-trait/async-associated-types.stderr
new file mode 100644
index 00000000000..0985150eee0
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-associated-types.stderr
@@ -0,0 +1,57 @@
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
+  --> $DIR/async-associated-types.rs:19:43
+   |
+LL |     async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
+   |                                           ^^^^^^^^^^^^^^
+   |
+note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
+  --> $DIR/async-associated-types.rs:16:6
+   |
+LL | impl<'a, 'b, T: Debug + Sized + 'b, U: 'a> MyTrait<'a, 'b, T> for U {
+   |      ^^
+note: ...so that the types are compatible
+  --> $DIR/async-associated-types.rs:19:43
+   |
+LL |     async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
+   |                                           ^^^^^^^^^^^^^^
+   = note: expected `(&'a U, &'b T)`
+              found `(&U, &T)`
+   = note: but, the lifetime must be valid for the static lifetime...
+note: ...so that the types are compatible
+  --> $DIR/async-associated-types.rs:19:43
+   |
+LL |     async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
+   |                                           ^^^^^^^^^^^^^^
+   = note: expected `MyTrait<'static, 'static, T>`
+              found `MyTrait<'_, '_, T>`
+
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'b` due to conflicting requirements
+  --> $DIR/async-associated-types.rs:19:43
+   |
+LL |     async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
+   |                                           ^^^^^^^^^^^^^^
+   |
+note: first, the lifetime cannot outlive the lifetime `'b` as defined here...
+  --> $DIR/async-associated-types.rs:16:10
+   |
+LL | impl<'a, 'b, T: Debug + Sized + 'b, U: 'a> MyTrait<'a, 'b, T> for U {
+   |          ^^
+note: ...so that the types are compatible
+  --> $DIR/async-associated-types.rs:19:43
+   |
+LL |     async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
+   |                                           ^^^^^^^^^^^^^^
+   = note: expected `(&'a U, &'b T)`
+              found `(&U, &T)`
+   = note: but, the lifetime must be valid for the static lifetime...
+note: ...so that the types are compatible
+  --> $DIR/async-associated-types.rs:19:43
+   |
+LL |     async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
+   |                                           ^^^^^^^^^^^^^^
+   = note: expected `MyTrait<'static, 'static, T>`
+              found `MyTrait<'_, '_, T>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/async-await/in-trait/async-associated-types2.rs b/src/test/ui/async-await/in-trait/async-associated-types2.rs
new file mode 100644
index 00000000000..e546a0579c6
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-associated-types2.rs
@@ -0,0 +1,30 @@
+// check-pass
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![feature(type_alias_impl_trait)]
+#![allow(incomplete_features)]
+
+use std::future::Future;
+
+trait MyTrait {
+    type Fut<'a>: Future<Output = i32>
+    where
+        Self: 'a;
+
+    fn foo<'a>(&'a self) -> Self::Fut<'a>;
+}
+
+impl MyTrait for i32 {
+    type Fut<'a> = impl Future<Output = i32> + 'a
+    where
+        Self: 'a;
+
+    fn foo<'a>(&'a self) -> Self::Fut<'a> {
+        async {
+            *self
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs b/src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs
new file mode 100644
index 00000000000..38ba297189c
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs
@@ -0,0 +1,21 @@
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::future::Future;
+use std::pin::Pin;
+
+trait MyTrait {
+    fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>>;
+}
+
+impl MyTrait for i32 {
+    async fn foo(&self) -> i32 {
+        //~^ ERROR method `foo` has an incompatible type for trait
+        *self
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr b/src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr
new file mode 100644
index 00000000000..22d2928f2f5
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr
@@ -0,0 +1,17 @@
+error[E0053]: method `foo` has an incompatible type for trait
+  --> $DIR/async-example-desugared-boxed-in-trait.rs:15:28
+   |
+LL |     async fn foo(&self) -> i32 {
+   |                            ^^^ expected struct `Pin`, found opaque type
+   |
+note: type in trait
+  --> $DIR/async-example-desugared-boxed-in-trait.rs:11:22
+   |
+LL |     fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>>;
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: expected fn pointer `fn(&i32) -> Pin<Box<dyn Future<Output = i32>>>`
+              found fn pointer `fn(&i32) -> impl Future<Output = i32>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0053`.
diff --git a/src/test/ui/async-await/in-trait/async-example-desugared-boxed.rs b/src/test/ui/async-await/in-trait/async-example-desugared-boxed.rs
new file mode 100644
index 00000000000..61d7e2520ea
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-example-desugared-boxed.rs
@@ -0,0 +1,24 @@
+// check-pass
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::future::Future;
+use std::pin::Pin;
+
+trait MyTrait {
+    async fn foo(&self) -> i32;
+}
+
+impl MyTrait for i32 {
+    // This will break once a PR that implements #102745 is merged
+    fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>> {
+        Box::pin(async {
+            *self
+        })
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-example-desugared-in-trait.rs b/src/test/ui/async-await/in-trait/async-example-desugared-in-trait.rs
new file mode 100644
index 00000000000..feeda719e03
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-example-desugared-in-trait.rs
@@ -0,0 +1,21 @@
+// check-pass
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::future::Future;
+
+trait MyTrait {
+    fn foo(&self) -> impl Future<Output = i32> + '_;
+}
+
+impl MyTrait for i32 {
+    // This will break once a PR that implements #102745 is merged
+    async fn foo(&self) -> i32 {
+        *self
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-example-desugared.rs b/src/test/ui/async-await/in-trait/async-example-desugared.rs
new file mode 100644
index 00000000000..1313c9edd86
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-example-desugared.rs
@@ -0,0 +1,23 @@
+// check-pass
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::future::Future;
+
+trait MyTrait {
+    async fn foo(&self) -> i32;
+}
+
+impl MyTrait for i32 {
+    // This will break once a PR that implements #102745 is merged
+    fn foo(&self) -> impl Future<Output = i32> + '_ {
+        async {
+            *self
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-example.rs b/src/test/ui/async-await/in-trait/async-example.rs
new file mode 100644
index 00000000000..abf94ef7450
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-example.rs
@@ -0,0 +1,32 @@
+// check-pass
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+trait MyTrait {
+    async fn foo(&self) -> i32;
+    async fn bar(&self) -> i32;
+}
+
+impl MyTrait for i32 {
+    async fn foo(&self) -> i32 {
+        *self
+    }
+
+    async fn bar(&self) -> i32 {
+        self.foo().await
+    }
+}
+
+fn main() {
+    let x = 5;
+    // Calling from non-async context
+    let _ = x.foo();
+    let _ = x.bar();
+    // Calling from async block in non-async context
+    async {
+        let _: i32 = x.foo().await;
+        let _: i32 = x.bar().await;
+    };
+}
diff --git a/src/test/ui/async-await/in-trait/async-generics-and-bounds.rs b/src/test/ui/async-await/in-trait/async-generics-and-bounds.rs
new file mode 100644
index 00000000000..a73d55adfec
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-generics-and-bounds.rs
@@ -0,0 +1,21 @@
+// check-fail
+// known-bug: #102682
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+use std::hash::Hash;
+
+trait MyTrait<T, U> {
+    async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
+}
+
+impl<T, U> MyTrait<T, U> for (T, U) {
+    async fn foo(&self) -> &(T, U) {
+        self
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr b/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr
new file mode 100644
index 00000000000..5c8d64fc6cb
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr
@@ -0,0 +1,37 @@
+error[E0311]: the parameter type `U` may not live long enough
+  --> $DIR/async-generics-and-bounds.rs:12:28
+   |
+LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
+   |                            ^^^^^^^
+   |
+note: the parameter type `U` must be valid for the anonymous lifetime as defined here...
+  --> $DIR/async-generics-and-bounds.rs:12:18
+   |
+LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
+   |                  ^
+note: ...so that the reference type `&(T, U)` does not outlive the data it points at
+  --> $DIR/async-generics-and-bounds.rs:12:28
+   |
+LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
+   |                            ^^^^^^^
+
+error[E0311]: the parameter type `T` may not live long enough
+  --> $DIR/async-generics-and-bounds.rs:12:28
+   |
+LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
+   |                            ^^^^^^^
+   |
+note: the parameter type `T` must be valid for the anonymous lifetime as defined here...
+  --> $DIR/async-generics-and-bounds.rs:12:18
+   |
+LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
+   |                  ^
+note: ...so that the reference type `&(T, U)` does not outlive the data it points at
+  --> $DIR/async-generics-and-bounds.rs:12:28
+   |
+LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
+   |                            ^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0311`.
diff --git a/src/test/ui/async-await/in-trait/async-generics.rs b/src/test/ui/async-await/in-trait/async-generics.rs
new file mode 100644
index 00000000000..67000e5770e
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-generics.rs
@@ -0,0 +1,18 @@
+// check-fail
+// known-bug: #102682
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+trait MyTrait<T, U> {
+    async fn foo(&self) -> &(T, U);
+}
+
+impl<T, U> MyTrait<T, U> for (T, U) {
+    async fn foo(&self) -> &(T, U) {
+        self
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-generics.stderr b/src/test/ui/async-await/in-trait/async-generics.stderr
new file mode 100644
index 00000000000..6ae73d9e3a6
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-generics.stderr
@@ -0,0 +1,37 @@
+error[E0311]: the parameter type `U` may not live long enough
+  --> $DIR/async-generics.rs:9:28
+   |
+LL |     async fn foo(&self) -> &(T, U);
+   |                            ^^^^^^^
+   |
+note: the parameter type `U` must be valid for the anonymous lifetime as defined here...
+  --> $DIR/async-generics.rs:9:18
+   |
+LL |     async fn foo(&self) -> &(T, U);
+   |                  ^
+note: ...so that the reference type `&(T, U)` does not outlive the data it points at
+  --> $DIR/async-generics.rs:9:28
+   |
+LL |     async fn foo(&self) -> &(T, U);
+   |                            ^^^^^^^
+
+error[E0311]: the parameter type `T` may not live long enough
+  --> $DIR/async-generics.rs:9:28
+   |
+LL |     async fn foo(&self) -> &(T, U);
+   |                            ^^^^^^^
+   |
+note: the parameter type `T` must be valid for the anonymous lifetime as defined here...
+  --> $DIR/async-generics.rs:9:18
+   |
+LL |     async fn foo(&self) -> &(T, U);
+   |                  ^
+note: ...so that the reference type `&(T, U)` does not outlive the data it points at
+  --> $DIR/async-generics.rs:9:28
+   |
+LL |     async fn foo(&self) -> &(T, U);
+   |                            ^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0311`.
diff --git a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs
new file mode 100644
index 00000000000..3f7448cecd1
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs
@@ -0,0 +1,20 @@
+// check-fail
+// known-bug: #102682
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+trait MyTrait<'a, 'b, T> {
+    async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T) where T: Debug + Sized;
+}
+
+impl<'a, 'b, T, U> MyTrait<'a, 'b, T> for U {
+    async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
+        (self, key)
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr
new file mode 100644
index 00000000000..0f024202743
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr
@@ -0,0 +1,23 @@
+error[E0309]: the parameter type `Self` may not live long enough
+  --> $DIR/async-lifetimes-and-bounds.rs:11:43
+   |
+LL |     async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T) where T: Debug + Sized;
+   |                                           ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding an explicit lifetime bound `Self: 'a`...
+   = note: ...so that the reference type `&'a Self` does not outlive the data it points at
+
+error[E0309]: the parameter type `T` may not live long enough
+  --> $DIR/async-lifetimes-and-bounds.rs:11:43
+   |
+LL |     async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T) where T: Debug + Sized;
+   |                                           ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'b T` does not outlive the data it points at
+   |
+help: consider adding an explicit lifetime bound...
+   |
+LL | trait MyTrait<'a, 'b, T: 'b> {
+   |                        ++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0309`.
diff --git a/src/test/ui/async-await/in-trait/async-lifetimes.rs b/src/test/ui/async-await/in-trait/async-lifetimes.rs
new file mode 100644
index 00000000000..acbac471cf7
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-lifetimes.rs
@@ -0,0 +1,18 @@
+// check-fail
+// known-bug: #102682
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+trait MyTrait<'a, 'b, T> {
+    async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T);
+}
+
+impl<'a, 'b, T, U> MyTrait<'a, 'b, T> for U {
+    async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
+        (self, key)
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-lifetimes.stderr b/src/test/ui/async-await/in-trait/async-lifetimes.stderr
new file mode 100644
index 00000000000..9a7d294bb17
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-lifetimes.stderr
@@ -0,0 +1,23 @@
+error[E0309]: the parameter type `Self` may not live long enough
+  --> $DIR/async-lifetimes.rs:9:43
+   |
+LL |     async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T);
+   |                                           ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding an explicit lifetime bound `Self: 'a`...
+   = note: ...so that the reference type `&'a Self` does not outlive the data it points at
+
+error[E0309]: the parameter type `T` may not live long enough
+  --> $DIR/async-lifetimes.rs:9:43
+   |
+LL |     async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T);
+   |                                           ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'b T` does not outlive the data it points at
+   |
+help: consider adding an explicit lifetime bound...
+   |
+LL | trait MyTrait<'a, 'b, T: 'b> {
+   |                        ++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0309`.
diff --git a/src/test/ui/async-await/in-trait/async-recursive-generic.rs b/src/test/ui/async-await/in-trait/async-recursive-generic.rs
new file mode 100644
index 00000000000..6839abd381c
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-recursive-generic.rs
@@ -0,0 +1,21 @@
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+trait MyTrait<T> {
+    async fn foo_recursive(&self, n: usize) -> T;
+}
+
+impl<T> MyTrait<T> for T where T: Copy {
+    async fn foo_recursive(&self, n: usize) -> T {
+        //~^ ERROR recursion in an `async fn` requires boxing
+        if n > 0 {
+            self.foo_recursive(n - 1).await
+        } else {
+            *self
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-recursive-generic.stderr b/src/test/ui/async-await/in-trait/async-recursive-generic.stderr
new file mode 100644
index 00000000000..cab173bdd5b
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-recursive-generic.stderr
@@ -0,0 +1,12 @@
+error[E0733]: recursion in an `async fn` requires boxing
+  --> $DIR/async-recursive-generic.rs:11:48
+   |
+LL |     async fn foo_recursive(&self, n: usize) -> T {
+   |                                                ^ recursive `async fn`
+   |
+   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
+   = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0733`.
diff --git a/src/test/ui/async-await/in-trait/async-recursive.rs b/src/test/ui/async-await/in-trait/async-recursive.rs
new file mode 100644
index 00000000000..61119f8095b
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-recursive.rs
@@ -0,0 +1,21 @@
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+trait MyTrait {
+    async fn foo_recursive(&self, n: usize) -> i32;
+}
+
+impl MyTrait for i32 {
+    async fn foo_recursive(&self, n: usize) -> i32 {
+        //~^ ERROR recursion in an `async fn` requires boxing
+        if n > 0 {
+            self.foo_recursive(n - 1).await
+        } else {
+            *self
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-recursive.stderr b/src/test/ui/async-await/in-trait/async-recursive.stderr
new file mode 100644
index 00000000000..9feff37b3fe
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-recursive.stderr
@@ -0,0 +1,12 @@
+error[E0733]: recursion in an `async fn` requires boxing
+  --> $DIR/async-recursive.rs:11:48
+   |
+LL |     async fn foo_recursive(&self, n: usize) -> i32 {
+   |                                                ^^^ recursive `async fn`
+   |
+   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
+   = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0733`.
diff --git a/src/test/ui/async-await/in-trait/fn-not-async-err.rs b/src/test/ui/async-await/in-trait/fn-not-async-err.rs
new file mode 100644
index 00000000000..f94d32145a2
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/fn-not-async-err.rs
@@ -0,0 +1,17 @@
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+trait MyTrait {
+    async fn foo(&self) -> i32;
+}
+
+impl MyTrait for i32 {
+    fn foo(&self) -> i32 {
+        //~^ ERROR: `i32` is not a future [E0277]
+        *self
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/fn-not-async-err.stderr b/src/test/ui/async-await/in-trait/fn-not-async-err.stderr
new file mode 100644
index 00000000000..03321dc5b5a
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/fn-not-async-err.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `i32` is not a future
+  --> $DIR/fn-not-async-err.rs:11:22
+   |
+LL |     fn foo(&self) -> i32 {
+   |                      ^^^ `i32` is not a future
+   |
+   = help: the trait `Future` is not implemented for `i32`
+   = note: i32 must be a future or must implement `IntoFuture` to be awaited
+note: required by a bound in `MyTrait::foo::{opaque#0}`
+  --> $DIR/fn-not-async-err.rs:7:28
+   |
+LL |     async fn foo(&self) -> i32;
+   |                            ^^^ required by this bound in `MyTrait::foo::{opaque#0}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/in-trait/fn-not-async-err2.rs b/src/test/ui/async-await/in-trait/fn-not-async-err2.rs
new file mode 100644
index 00000000000..594baa91ad8
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/fn-not-async-err2.rs
@@ -0,0 +1,21 @@
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+use std::future::Future;
+
+trait MyTrait {
+    async fn foo(&self) -> i32;
+}
+
+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]
+        async {
+            *self
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/fn-not-async-err2.stderr b/src/test/ui/async-await/in-trait/fn-not-async-err2.stderr
new file mode 100644
index 00000000000..f591f184772
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/fn-not-async-err2.stderr
@@ -0,0 +1,12 @@
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return
+  --> $DIR/fn-not-async-err2.rs:13:22
+   |
+LL |     fn foo(&self) -> impl Future<Output = i32> {
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0562`.
diff --git a/src/test/ui/async-await/issue-98634.rs b/src/test/ui/async-await/issue-98634.rs
new file mode 100644
index 00000000000..b0d38687f01
--- /dev/null
+++ b/src/test/ui/async-await/issue-98634.rs
@@ -0,0 +1,50 @@
+// edition: 2021
+
+use std::{
+    future::Future,
+    pin::Pin,
+    task::{Context, Poll, Waker},
+};
+
+pub struct StructAsync<F: Fn() -> Pin<Box<dyn Future<Output = ()>>>> {
+    pub callback: F,
+}
+
+impl<F> Future for StructAsync<F>
+where
+    F: Fn() -> Pin<Box<dyn Future<Output = ()>>>,
+{
+    type Output = ();
+
+    fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
+        Poll::Pending
+    }
+}
+
+async fn callback() {}
+
+struct Runtime;
+
+fn waker() -> &'static Waker {
+    todo!()
+}
+
+impl Runtime {
+    #[track_caller]
+    pub fn block_on<F: Future>(&self, mut future: F) -> F::Output {
+        loop {
+            unsafe {
+                Pin::new_unchecked(&mut future).poll(&mut Context::from_waker(waker()));
+            }
+        }
+    }
+}
+
+fn main() {
+    Runtime.block_on(async {
+        StructAsync { callback }.await;
+        //~^ ERROR expected `fn() -> impl Future<Output = ()> {callback}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
+        //~| ERROR expected `fn() -> impl Future<Output = ()> {callback}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
+        //~| ERROR expected `fn() -> impl Future<Output = ()> {callback}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
+    });
+}
diff --git a/src/test/ui/async-await/issue-98634.stderr b/src/test/ui/async-await/issue-98634.stderr
new file mode 100644
index 00000000000..5160e48d88a
--- /dev/null
+++ b/src/test/ui/async-await/issue-98634.stderr
@@ -0,0 +1,60 @@
+error[E0271]: expected `fn() -> impl Future<Output = ()> {callback}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
+  --> $DIR/issue-98634.rs:45:23
+   |
+LL |         StructAsync { callback }.await;
+   |                       ^^^^^^^^ expected struct `Pin`, found opaque type
+   |
+note: while checking the return type of the `async fn`
+  --> $DIR/issue-98634.rs:24:21
+   |
+LL | async fn callback() {}
+   |                     ^ checked the `Output` of this `async fn`, found opaque type
+   = note:   expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>`
+           found opaque type `impl Future<Output = ()>`
+note: required by a bound in `StructAsync`
+  --> $DIR/issue-98634.rs:9:35
+   |
+LL | pub struct StructAsync<F: Fn() -> Pin<Box<dyn Future<Output = ()>>>> {
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StructAsync`
+
+error[E0271]: expected `fn() -> impl Future<Output = ()> {callback}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
+  --> $DIR/issue-98634.rs:45:9
+   |
+LL |         StructAsync { callback }.await;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Pin`, found opaque type
+   |
+note: while checking the return type of the `async fn`
+  --> $DIR/issue-98634.rs:24:21
+   |
+LL | async fn callback() {}
+   |                     ^ checked the `Output` of this `async fn`, found opaque type
+   = note:   expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>`
+           found opaque type `impl Future<Output = ()>`
+note: required by a bound in `StructAsync`
+  --> $DIR/issue-98634.rs:9:35
+   |
+LL | pub struct StructAsync<F: Fn() -> Pin<Box<dyn Future<Output = ()>>>> {
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StructAsync`
+
+error[E0271]: expected `fn() -> impl Future<Output = ()> {callback}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
+  --> $DIR/issue-98634.rs:45:33
+   |
+LL |         StructAsync { callback }.await;
+   |                                 ^^^^^^ expected struct `Pin`, found opaque type
+   |
+note: while checking the return type of the `async fn`
+  --> $DIR/issue-98634.rs:24:21
+   |
+LL | async fn callback() {}
+   |                     ^ checked the `Output` of this `async fn`, found opaque type
+   = note:   expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>`
+           found opaque type `impl Future<Output = ()>`
+note: required by a bound in `StructAsync`
+  --> $DIR/issue-98634.rs:9:35
+   |
+LL | pub struct StructAsync<F: Fn() -> Pin<Box<dyn Future<Output = ()>>>> {
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StructAsync`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/async-await/issues/issue-72312.stderr b/src/test/ui/async-await/issues/issue-72312.stderr
index 5e5a980adb9..aa947b69003 100644
--- a/src/test/ui/async-await/issues/issue-72312.stderr
+++ b/src/test/ui/async-await/issues/issue-72312.stderr
@@ -1,5 +1,5 @@
 error[E0521]: borrowed data escapes outside of associated function
-  --> $DIR/issue-72312.rs:12:24
+  --> $DIR/issue-72312.rs:12:9
    |
 LL |       pub async fn start(&self) {
    |                          -----
@@ -7,17 +7,16 @@ LL |       pub async fn start(&self) {
    |                          `self` is a reference that is only valid in the associated function body
    |                          let's call the lifetime of this reference `'1`
 ...
-LL |           require_static(async move {
-   |  ________________________^
+LL | /         require_static(async move {
 LL | |
 LL | |
 LL | |
 LL | |             &self;
 LL | |         });
-   | |         ^
-   | |         |
-   | |_________`self` escapes the associated function body here
-   |           argument requires that `'1` must outlive `'static`
+   | |          ^
+   | |          |
+   | |__________`self` escapes the associated function body here
+   |            argument requires that `'1` must outlive `'static`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/issue-103624.rs b/src/test/ui/borrowck/issue-103624.rs
new file mode 100644
index 00000000000..f1fa95f9246
--- /dev/null
+++ b/src/test/ui/borrowck/issue-103624.rs
@@ -0,0 +1,31 @@
+// edition:2021
+
+struct StructA {
+    b: StructB,
+}
+
+async fn spawn_blocking<T>(f: impl (Fn() -> T) + Send + Sync + 'static) -> T {
+    todo!()
+}
+
+impl StructA {
+    async fn foo(&self) {
+        let bar = self.b.bar().await;
+        spawn_blocking(move || {
+            //~^ ERROR borrowed data escapes outside of associated function
+            self.b;
+            //~^ ERROR cannot move out of `self.b`, as `self` is a captured variable in an `Fn` closure
+        })
+        .await;
+    }
+}
+
+struct StructB {}
+
+impl StructB {
+    async fn bar(&self) -> Option<u8> {
+        None
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/borrowck/issue-103624.stderr b/src/test/ui/borrowck/issue-103624.stderr
new file mode 100644
index 00000000000..e6a35dd8801
--- /dev/null
+++ b/src/test/ui/borrowck/issue-103624.stderr
@@ -0,0 +1,35 @@
+error[E0507]: cannot move out of `self.b`, as `self` is a captured variable in an `Fn` closure
+  --> $DIR/issue-103624.rs:16:13
+   |
+LL |     async fn foo(&self) {
+   |                  ----- captured outer variable
+LL |         let bar = self.b.bar().await;
+LL |         spawn_blocking(move || {
+   |                        ------- captured by this `Fn` closure
+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
+  --> $DIR/issue-103624.rs:14:9
+   |
+LL |       async fn foo(&self) {
+   |                    -----
+   |                    |
+   |                    `self` is a reference that is only valid in the associated function body
+   |                    let's call the lifetime of this reference `'1`
+LL |           let bar = self.b.bar().await;
+LL | /         spawn_blocking(move || {
+LL | |
+LL | |             self.b;
+LL | |
+LL | |         })
+   | |          ^
+   | |          |
+   | |__________`self` escapes the associated function body here
+   |            argument requires that `'1` must outlive `'static`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0507, E0521.
+For more information about an error, try `rustc --explain E0507`.
diff --git a/src/test/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs b/src/test/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs
new file mode 100644
index 00000000000..087743e505d
--- /dev/null
+++ b/src/test/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs
@@ -0,0 +1,19 @@
+#![feature(abi_efiapi)]
+
+fn efiapi(f: extern "efiapi" fn(usize, ...)) {
+    //~^ ERROR: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
+    //~^^ ERROR: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
+    f(22, 44);
+}
+fn sysv(f: extern "sysv64" fn(usize, ...)) {
+    //~^ ERROR: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
+    //~^^ ERROR: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
+    f(22, 44);
+}
+fn win(f: extern "win64" fn(usize, ...)) {
+    //~^ ERROR: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
+    //~^^ ERROR: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
+    f(22, 44);
+}
+
+fn main() {}
diff --git a/src/test/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr b/src/test/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr
new file mode 100644
index 00000000000..007d7d7953c
--- /dev/null
+++ b/src/test/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr
@@ -0,0 +1,49 @@
+error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
+  --> $DIR/feature-gate-extended_varargs_abi_support.rs:3:14
+   |
+LL | fn efiapi(f: extern "efiapi" fn(usize, ...)) {
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #100189 <https://github.com/rust-lang/rust/issues/100189> for more information
+   = help: add `#![feature(extended_varargs_abi_support)]` to the crate attributes to enable
+
+error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
+  --> $DIR/feature-gate-extended_varargs_abi_support.rs:3:14
+   |
+LL | fn efiapi(f: extern "efiapi" fn(usize, ...)) {
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
+
+error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
+  --> $DIR/feature-gate-extended_varargs_abi_support.rs:8:12
+   |
+LL | fn sysv(f: extern "sysv64" fn(usize, ...)) {
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #100189 <https://github.com/rust-lang/rust/issues/100189> for more information
+   = help: add `#![feature(extended_varargs_abi_support)]` to the crate attributes to enable
+
+error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
+  --> $DIR/feature-gate-extended_varargs_abi_support.rs:8:12
+   |
+LL | fn sysv(f: extern "sysv64" fn(usize, ...)) {
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
+
+error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
+  --> $DIR/feature-gate-extended_varargs_abi_support.rs:13:11
+   |
+LL | fn win(f: extern "win64" fn(usize, ...)) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #100189 <https://github.com/rust-lang/rust/issues/100189> for more information
+   = help: add `#![feature(extended_varargs_abi_support)]` to the crate attributes to enable
+
+error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
+  --> $DIR/feature-gate-extended_varargs_abi_support.rs:13:11
+   |
+LL | fn win(f: extern "win64" fn(usize, ...)) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0045, E0658.
+For more information about an error, try `rustc --explain E0045`.
diff --git a/src/test/ui/c-variadic/variadic-ffi-1.rs b/src/test/ui/c-variadic/variadic-ffi-1.rs
index a76efd9a205..24407a71ce6 100644
--- a/src/test/ui/c-variadic/variadic-ffi-1.rs
+++ b/src/test/ui/c-variadic/variadic-ffi-1.rs
@@ -6,7 +6,9 @@
 trait Sized { }
 
 extern "stdcall" {
-    fn printf(_: *const u8, ...); //~ ERROR: variadic function must have C or cdecl calling
+    fn printf(_: *const u8, ...);
+    //~^ ERROR: C-variadic function must have a compatible calling convention,
+    // like C, cdecl, win64, sysv64 or efiapi
 }
 
 extern "C" {
diff --git a/src/test/ui/c-variadic/variadic-ffi-1.stderr b/src/test/ui/c-variadic/variadic-ffi-1.stderr
index 2ffb80f7ef6..4beea83d8a5 100644
--- a/src/test/ui/c-variadic/variadic-ffi-1.stderr
+++ b/src/test/ui/c-variadic/variadic-ffi-1.stderr
@@ -1,17 +1,17 @@
-error[E0045]: C-variadic function must have C or cdecl calling convention
+error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
   --> $DIR/variadic-ffi-1.rs:9:5
    |
 LL |     fn printf(_: *const u8, ...);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadics require C or cdecl calling convention
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
 
 error[E0060]: this function takes at least 2 arguments but 0 arguments were supplied
-  --> $DIR/variadic-ffi-1.rs:20:9
+  --> $DIR/variadic-ffi-1.rs:22:9
    |
 LL |         foo();
    |         ^^^-- two arguments of type `isize` and `u8` are missing
    |
 note: function defined here
-  --> $DIR/variadic-ffi-1.rs:13:8
+  --> $DIR/variadic-ffi-1.rs:15:8
    |
 LL |     fn foo(f: isize, x: u8, ...);
    |        ^^^
@@ -21,13 +21,13 @@ LL |         foo(/* isize */, /* u8 */);
    |            ~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0060]: this function takes at least 2 arguments but 1 argument was supplied
-  --> $DIR/variadic-ffi-1.rs:21:9
+  --> $DIR/variadic-ffi-1.rs:23:9
    |
 LL |         foo(1);
    |         ^^^--- an argument of type `u8` is missing
    |
 note: function defined here
-  --> $DIR/variadic-ffi-1.rs:13:8
+  --> $DIR/variadic-ffi-1.rs:15:8
    |
 LL |     fn foo(f: isize, x: u8, ...);
    |        ^^^
@@ -37,7 +37,7 @@ LL |         foo(1, /* u8 */);
    |            ~~~~~~~~~~~~~
 
 error[E0308]: mismatched types
-  --> $DIR/variadic-ffi-1.rs:23:56
+  --> $DIR/variadic-ffi-1.rs:25:56
    |
 LL |         let x: unsafe extern "C" fn(f: isize, x: u8) = foo;
    |                -------------------------------------   ^^^ expected non-variadic fn, found variadic function
@@ -48,7 +48,7 @@ LL |         let x: unsafe extern "C" fn(f: isize, x: u8) = foo;
                  found fn item `unsafe extern "C" fn(_, _, ...) {foo}`
 
 error[E0308]: mismatched types
-  --> $DIR/variadic-ffi-1.rs:24:54
+  --> $DIR/variadic-ffi-1.rs:26:54
    |
 LL |         let y: extern "C" fn(f: isize, x: u8, ...) = bar;
    |                -----------------------------------   ^^^ expected variadic fn, found non-variadic function
@@ -59,37 +59,37 @@ LL |         let y: extern "C" fn(f: isize, x: u8, ...) = bar;
                  found fn item `extern "C" fn(_, _) {bar}`
 
 error[E0617]: can't pass `f32` to variadic function
-  --> $DIR/variadic-ffi-1.rs:26:19
+  --> $DIR/variadic-ffi-1.rs:28:19
    |
 LL |         foo(1, 2, 3f32);
    |                   ^^^^ help: cast the value to `c_double`: `3f32 as c_double`
 
 error[E0617]: can't pass `bool` to variadic function
-  --> $DIR/variadic-ffi-1.rs:27:19
+  --> $DIR/variadic-ffi-1.rs:29:19
    |
 LL |         foo(1, 2, true);
    |                   ^^^^ help: cast the value to `c_int`: `true as c_int`
 
 error[E0617]: can't pass `i8` to variadic function
-  --> $DIR/variadic-ffi-1.rs:28:19
+  --> $DIR/variadic-ffi-1.rs:30:19
    |
 LL |         foo(1, 2, 1i8);
    |                   ^^^ help: cast the value to `c_int`: `1i8 as c_int`
 
 error[E0617]: can't pass `u8` to variadic function
-  --> $DIR/variadic-ffi-1.rs:29:19
+  --> $DIR/variadic-ffi-1.rs:31:19
    |
 LL |         foo(1, 2, 1u8);
    |                   ^^^ help: cast the value to `c_uint`: `1u8 as c_uint`
 
 error[E0617]: can't pass `i16` to variadic function
-  --> $DIR/variadic-ffi-1.rs:30:19
+  --> $DIR/variadic-ffi-1.rs:32:19
    |
 LL |         foo(1, 2, 1i16);
    |                   ^^^^ help: cast the value to `c_int`: `1i16 as c_int`
 
 error[E0617]: can't pass `u16` to variadic function
-  --> $DIR/variadic-ffi-1.rs:31:19
+  --> $DIR/variadic-ffi-1.rs:33:19
    |
 LL |         foo(1, 2, 1u16);
    |                   ^^^^ help: cast the value to `c_uint`: `1u16 as c_uint`
diff --git a/src/test/ui/c-variadic/variadic-ffi-2.rs b/src/test/ui/c-variadic/variadic-ffi-2.rs
index 224ac16f458..96cea87546e 100644
--- a/src/test/ui/c-variadic/variadic-ffi-2.rs
+++ b/src/test/ui/c-variadic/variadic-ffi-2.rs
@@ -1,7 +1,20 @@
 // ignore-arm stdcall isn't supported
+#![feature(extended_varargs_abi_support)]
+#![feature(abi_efiapi)]
 
 fn baz(f: extern "stdcall" fn(usize, ...)) {
-    //~^ ERROR: variadic function must have C or cdecl calling convention
+    //~^ ERROR: C-variadic function must have a compatible calling convention,
+    // like C, cdecl, win64, sysv64 or efiapi
+    f(22, 44);
+}
+
+fn sysv(f: extern "sysv64" fn(usize, ...)) {
+    f(22, 44);
+}
+fn win(f: extern "win64" fn(usize, ...)) {
+    f(22, 44);
+}
+fn efiapi(f: extern "efiapi" fn(usize, ...)) {
     f(22, 44);
 }
 
diff --git a/src/test/ui/c-variadic/variadic-ffi-2.stderr b/src/test/ui/c-variadic/variadic-ffi-2.stderr
index 4c8b8d2b2e1..4e74c9d9227 100644
--- a/src/test/ui/c-variadic/variadic-ffi-2.stderr
+++ b/src/test/ui/c-variadic/variadic-ffi-2.stderr
@@ -1,8 +1,8 @@
-error[E0045]: C-variadic function must have C or cdecl calling convention
-  --> $DIR/variadic-ffi-2.rs:3:11
+error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `win64`, `sysv64` or `efiapi`
+  --> $DIR/variadic-ffi-2.rs:5:11
    |
 LL | fn baz(f: extern "stdcall" fn(usize, ...)) {
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadics require C or cdecl calling convention
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coercion/coerce-block-tail-26978.rs b/src/test/ui/coercion/coerce-block-tail-26978.rs
new file mode 100644
index 00000000000..01c8ab5a839
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-26978.rs
@@ -0,0 +1,11 @@
+// check-fail
+fn f(_: &i32) {}
+
+fn main() {
+    let x = Box::new(1i32);
+
+    f(&x);
+    f(&(x));
+    f(&{x});
+    //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/coercion/coerce-block-tail-26978.stderr b/src/test/ui/coercion/coerce-block-tail-26978.stderr
new file mode 100644
index 00000000000..384debd487c
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-26978.stderr
@@ -0,0 +1,16 @@
+error[E0308]: mismatched types
+  --> $DIR/coerce-block-tail-26978.rs:9:9
+   |
+LL |     f(&{x});
+   |         ^ expected `i32`, found struct `Box`
+   |
+   = note: expected type `i32`
+            found struct `Box<i32>`
+help: consider unboxing the value
+   |
+LL |     f(&{*x});
+   |         +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/coercion/coerce-block-tail-57749.rs b/src/test/ui/coercion/coerce-block-tail-57749.rs
new file mode 100644
index 00000000000..79b5b33233b
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-57749.rs
@@ -0,0 +1,35 @@
+// check-fail
+use std::ops::Deref;
+
+fn main() {
+    fn save(who: &str) {
+        println!("I'll save you, {}!", who);
+    }
+
+    struct Madoka;
+
+    impl Deref for Madoka {
+        type Target = str;
+        fn deref(&self) -> &Self::Target {
+            "Madoka"
+        }
+    }
+
+    save(&{ Madoka });
+
+    fn reset(how: &u32) {
+        println!("Reset {} times", how);
+    }
+
+    struct Homura;
+
+    impl Deref for Homura {
+        type Target = u32;
+        fn deref(&self) -> &Self::Target {
+            &42
+        }
+    }
+
+    reset(&{ Homura });
+    //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/coercion/coerce-block-tail-57749.stderr b/src/test/ui/coercion/coerce-block-tail-57749.stderr
new file mode 100644
index 00000000000..d5660c81dbd
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-57749.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/coerce-block-tail-57749.rs:33:14
+   |
+LL |     reset(&{ Homura });
+   |              ^^^^^^ expected `u32`, found struct `Homura`
+   |
+help: consider dereferencing the type
+   |
+LL |     reset(&{ *Homura });
+   |              +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/coercion/coerce-block-tail-83783.rs b/src/test/ui/coercion/coerce-block-tail-83783.rs
new file mode 100644
index 00000000000..18c8ae3bbba
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-83783.rs
@@ -0,0 +1,13 @@
+// check-fail
+// edition:2018
+fn _consume_reference<T: ?Sized>(_: &T) {}
+
+async fn _foo() {
+    _consume_reference::<i32>(&Box::new(7_i32));
+    _consume_reference::<i32>(&async { Box::new(7_i32) }.await);
+    //~^ ERROR mismatched types
+    _consume_reference::<[i32]>(&vec![7_i32]);
+    _consume_reference::<[i32]>(&async { vec![7_i32] }.await);
+}
+
+fn main() { }
diff --git a/src/test/ui/coercion/coerce-block-tail-83783.stderr b/src/test/ui/coercion/coerce-block-tail-83783.stderr
new file mode 100644
index 00000000000..5f53606ce22
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-83783.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/coerce-block-tail-83783.rs:7:32
+   |
+LL |     _consume_reference::<i32>(&async { Box::new(7_i32) }.await);
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found struct `Box`
+   |
+   = note: expected type `i32`
+            found struct `Box<i32>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/coercion/coerce-block-tail-83850.rs b/src/test/ui/coercion/coerce-block-tail-83850.rs
new file mode 100644
index 00000000000..77fdf999833
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-83850.rs
@@ -0,0 +1,7 @@
+// check-fail
+fn f(_: &[i32]) {}
+
+fn main() {
+    f(&Box::new([1, 2]));
+    //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/coercion/coerce-block-tail-83850.stderr b/src/test/ui/coercion/coerce-block-tail-83850.stderr
new file mode 100644
index 00000000000..bbf60754370
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-83850.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+  --> $DIR/coerce-block-tail-83850.rs:5:7
+   |
+LL |     f(&Box::new([1, 2]));
+   |     - ^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found struct `Box`
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected reference `&[i32]`
+              found reference `&Box<[{integer}; 2]>`
+note: function defined here
+  --> $DIR/coerce-block-tail-83850.rs:2:4
+   |
+LL | fn f(_: &[i32]) {}
+   |    ^ ---------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/coercion/coerce-block-tail.rs b/src/test/ui/coercion/coerce-block-tail.rs
new file mode 100644
index 00000000000..dcbcd376286
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail.rs
@@ -0,0 +1,6 @@
+// check-fail
+fn main() {
+    let _: &str = & { String::from("hahah")};
+    let _: &i32 = & { Box::new(1i32) };
+    //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/coercion/coerce-block-tail.stderr b/src/test/ui/coercion/coerce-block-tail.stderr
new file mode 100644
index 00000000000..318cf75867b
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail.stderr
@@ -0,0 +1,16 @@
+error[E0308]: mismatched types
+  --> $DIR/coerce-block-tail.rs:4:23
+   |
+LL |     let _: &i32 = & { Box::new(1i32) };
+   |                       ^^^^^^^^^^^^^^ expected `i32`, found struct `Box`
+   |
+   = note: expected type `i32`
+            found struct `Box<i32>`
+help: consider unboxing the value
+   |
+LL |     let _: &i32 = & { *Box::new(1i32) };
+   |                       +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/coercion/issue-36007.rs b/src/test/ui/coercion/issue-36007.rs
new file mode 100644
index 00000000000..78812df870d
--- /dev/null
+++ b/src/test/ui/coercion/issue-36007.rs
@@ -0,0 +1,20 @@
+// check-pass
+#![feature(coerce_unsized, unsize)]
+
+use std::marker::Unsize;
+use std::ops::CoerceUnsized;
+
+struct Foo<T: ?Sized>(Box<T>);
+
+impl<T> CoerceUnsized<Foo<dyn Baz>> for Foo<T> where T: Unsize<dyn Baz> {}
+
+struct Bar;
+
+trait Baz {}
+
+impl Baz for Bar {}
+
+fn main() {
+    let foo = Foo(Box::new(Bar));
+    let foobar: Foo<Bar> = foo;
+}
diff --git a/src/test/ui/coherence/coherence-default-trait-impl.stderr b/src/test/ui/coherence/coherence-default-trait-impl.stderr
index b08ccb087d9..63201878272 100644
--- a/src/test/ui/coherence/coherence-default-trait-impl.stderr
+++ b/src/test/ui/coherence/coherence-default-trait-impl.stderr
@@ -3,12 +3,24 @@ error[E0199]: implementing the trait `MySafeTrait` is not unsafe
    |
 LL | unsafe impl MySafeTrait for Foo {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove `unsafe` from this trait implementation
+   |
+LL - unsafe impl MySafeTrait for Foo {}
+LL + impl MySafeTrait for Foo {}
+   |
 
 error[E0200]: the trait `MyUnsafeTrait` requires an `unsafe impl` declaration
   --> $DIR/coherence-default-trait-impl.rs:13:1
    |
 LL | impl MyUnsafeTrait for Foo {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the trait `MyUnsafeTrait` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword
+help: add `unsafe` to this trait implementation
+   |
+LL | unsafe impl MyUnsafeTrait for Foo {}
+   | ++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/coherence/strict-coherence-needs-negative-coherence.rs b/src/test/ui/coherence/strict-coherence-needs-negative-coherence.rs
new file mode 100644
index 00000000000..221683dd56f
--- /dev/null
+++ b/src/test/ui/coherence/strict-coherence-needs-negative-coherence.rs
@@ -0,0 +1,7 @@
+#![feature(rustc_attrs)]
+
+#[rustc_strict_coherence]
+trait Foo {}
+//~^ ERROR to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled
+
+fn main() {}
diff --git a/src/test/ui/coherence/strict-coherence-needs-negative-coherence.stderr b/src/test/ui/coherence/strict-coherence-needs-negative-coherence.stderr
new file mode 100644
index 00000000000..b5472928778
--- /dev/null
+++ b/src/test/ui/coherence/strict-coherence-needs-negative-coherence.stderr
@@ -0,0 +1,10 @@
+error: to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled
+  --> $DIR/strict-coherence-needs-negative-coherence.rs:4:1
+   |
+LL | #[rustc_strict_coherence]
+   | ------------------------- due to this attribute
+LL | trait Foo {}
+   | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr b/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr
index 49e55be1b49..82169ee01be 100644
--- a/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr
+++ b/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr
@@ -8,6 +8,12 @@ LL | |     // (unsafe to access self.1  due to #[may_dangle] on A)
 LL | |     fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); }
 LL | | }
    | |_^
+   |
+   = note: the trait `Drop` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword
+help: add `unsafe` to this trait implementation
+   |
+LL | unsafe impl<#[may_dangle] A, B: fmt::Debug> Drop for Pt<A, B> {
+   | ++++++
 
 error[E0569]: requires an `unsafe impl` declaration due to `#[may_dangle]` attribute
   --> $DIR/dropck-eyepatch-implies-unsafe-impl.rs:27:1
@@ -19,6 +25,12 @@ LL | |     // (unsafe to access self.1 due to #[may_dangle] on 'a)
 LL | |     fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); }
 LL | | }
    | |_^
+   |
+   = note: the trait `Drop` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword
+help: add `unsafe` to this trait implementation
+   |
+LL | unsafe impl<#[may_dangle] 'a, 'b, B: fmt::Debug> Drop for Pr<'a, 'b, B> {
+   | ++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/dyn-star/no-explicit-dyn-star-cast.rs b/src/test/ui/dyn-star/no-explicit-dyn-star-cast.rs
new file mode 100644
index 00000000000..67240c8e8da
--- /dev/null
+++ b/src/test/ui/dyn-star/no-explicit-dyn-star-cast.rs
@@ -0,0 +1,13 @@
+use std::fmt::Debug;
+
+fn make_dyn_star() {
+    let i = 42usize;
+    let dyn_i: dyn* Debug = i as dyn* Debug;
+    //~^ ERROR casting `usize` as `dyn* Debug` is invalid
+    //~| ERROR dyn* trait objects are unstable
+    //~| ERROR dyn* trait objects are unstable
+}
+
+fn main() {
+    make_dyn_star();
+}
diff --git a/src/test/ui/dyn-star/no-explicit-dyn-star-cast.stderr b/src/test/ui/dyn-star/no-explicit-dyn-star-cast.stderr
new file mode 100644
index 00000000000..687d7db0464
--- /dev/null
+++ b/src/test/ui/dyn-star/no-explicit-dyn-star-cast.stderr
@@ -0,0 +1,28 @@
+error[E0658]: dyn* trait objects are unstable
+  --> $DIR/no-explicit-dyn-star-cast.rs:5:16
+   |
+LL |     let dyn_i: dyn* Debug = i as dyn* Debug;
+   |                ^^^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = help: add `#![feature(dyn_star)]` to the crate attributes to enable
+
+error[E0658]: dyn* trait objects are unstable
+  --> $DIR/no-explicit-dyn-star-cast.rs:5:34
+   |
+LL |     let dyn_i: dyn* Debug = i as dyn* Debug;
+   |                                  ^^^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = help: add `#![feature(dyn_star)]` to the crate attributes to enable
+
+error[E0606]: casting `usize` as `dyn* Debug` is invalid
+  --> $DIR/no-explicit-dyn-star-cast.rs:5:29
+   |
+LL |     let dyn_i: dyn* Debug = i as dyn* Debug;
+   |                             ^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0606, E0658.
+For more information about an error, try `rustc --explain E0606`.
diff --git a/src/test/ui/dyn-star/no-explicit-dyn-star.rs b/src/test/ui/dyn-star/no-explicit-dyn-star.rs
new file mode 100644
index 00000000000..4f726b7c6a6
--- /dev/null
+++ b/src/test/ui/dyn-star/no-explicit-dyn-star.rs
@@ -0,0 +1,8 @@
+// aux-build:dyn-star-foreign.rs
+
+extern crate dyn_star_foreign;
+
+fn main() {
+    dyn_star_foreign::require_dyn_star_display(1usize as _);
+    //~^ ERROR casting `usize` as `dyn* std::fmt::Display` is invalid
+}
diff --git a/src/test/ui/dyn-star/no-explicit-dyn-star.stderr b/src/test/ui/dyn-star/no-explicit-dyn-star.stderr
new file mode 100644
index 00000000000..49706fae19e
--- /dev/null
+++ b/src/test/ui/dyn-star/no-explicit-dyn-star.stderr
@@ -0,0 +1,9 @@
+error[E0606]: casting `usize` as `dyn* std::fmt::Display` is invalid
+  --> $DIR/no-explicit-dyn-star.rs:6:48
+   |
+LL |     dyn_star_foreign::require_dyn_star_display(1usize as _);
+   |                                                ^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0606`.
diff --git a/src/test/ui/error-codes/E0045.stderr b/src/test/ui/error-codes/E0045.stderr
index d163128bc8b..fcc613b11b8 100644
--- a/src/test/ui/error-codes/E0045.stderr
+++ b/src/test/ui/error-codes/E0045.stderr
@@ -1,8 +1,8 @@
-error[E0045]: C-variadic function must have C or cdecl calling convention
+error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
   --> $DIR/E0045.rs:1:17
    |
 LL | extern "Rust" { fn foo(x: u8, ...); }
-   |                 ^^^^^^^^^^^^^^^^^^^ C-variadics require C or cdecl calling convention
+   |                 ^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0199.stderr b/src/test/ui/error-codes/E0199.stderr
index 3632d26cd32..99d808c0d4b 100644
--- a/src/test/ui/error-codes/E0199.stderr
+++ b/src/test/ui/error-codes/E0199.stderr
@@ -3,6 +3,12 @@ error[E0199]: implementing the trait `Bar` is not unsafe
    |
 LL | unsafe impl Bar for Foo { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove `unsafe` from this trait implementation
+   |
+LL - unsafe impl Bar for Foo { }
+LL + impl Bar for Foo { }
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0200.stderr b/src/test/ui/error-codes/E0200.stderr
index 677271aad44..1fd86aecee1 100644
--- a/src/test/ui/error-codes/E0200.stderr
+++ b/src/test/ui/error-codes/E0200.stderr
@@ -3,6 +3,12 @@ error[E0200]: the trait `Bar` requires an `unsafe impl` declaration
    |
 LL | impl Bar for Foo { }
    | ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the trait `Bar` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword
+help: add `unsafe` to this trait implementation
+   |
+LL | unsafe impl Bar for Foo { }
+   | ++++++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.rs b/src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.rs
new file mode 100644
index 00000000000..0db8088f7ee
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.rs
@@ -0,0 +1,6 @@
+fn f() -> impl Fn() -> impl Sized { || () }
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
+fn g() -> &'static dyn Fn() -> impl Sized { &|| () }
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr b/src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr
new file mode 100644
index 00000000000..c485bc5c3ab
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr
@@ -0,0 +1,15 @@
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
+  --> $DIR/feature-gate-impl_trait_in_fn_trait_return.rs:1:24
+   |
+LL | fn f() -> impl Fn() -> impl Sized { || () }
+   |                        ^^^^^^^^^^
+
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
+  --> $DIR/feature-gate-impl_trait_in_fn_trait_return.rs:3:32
+   |
+LL | fn g() -> &'static dyn Fn() -> impl Sized { &|| () }
+   |                                ^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0562`.
diff --git a/src/test/ui/generic-associated-types/issue-87258_a.stderr b/src/test/ui/generic-associated-types/issue-87258_a.stderr
index fa0748a280b..eae9bd9b16f 100644
--- a/src/test/ui/generic-associated-types/issue-87258_a.stderr
+++ b/src/test/ui/generic-associated-types/issue-87258_a.stderr
@@ -4,7 +4,7 @@ error: unconstrained opaque type
 LL |     type FooFuture<'a> = impl Trait1;
    |                          ^^^^^^^^^^^
    |
-   = note: `FooFuture` must be used in combination with a concrete type within the same module
+   = note: `FooFuture` must be used in combination with a concrete type within the same impl
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-trait/impl-fn-hrtb-bounds-2.rs b/src/test/ui/impl-trait/impl-fn-hrtb-bounds-2.rs
new file mode 100644
index 00000000000..b0aeded0ef7
--- /dev/null
+++ b/src/test/ui/impl-trait/impl-fn-hrtb-bounds-2.rs
@@ -0,0 +1,8 @@
+#![feature(impl_trait_in_fn_trait_return)]
+use std::fmt::Debug;
+
+fn a() -> impl Fn(&u8) -> impl Debug {
+    |x| x //~ ERROR hidden type for `impl Debug` captures lifetime that does not appear in bounds
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/impl-fn-hrtb-bounds-2.stderr b/src/test/ui/impl-trait/impl-fn-hrtb-bounds-2.stderr
new file mode 100644
index 00000000000..433b76b7afa
--- /dev/null
+++ b/src/test/ui/impl-trait/impl-fn-hrtb-bounds-2.stderr
@@ -0,0 +1,11 @@
+error[E0700]: hidden type for `impl Debug` captures lifetime that does not appear in bounds
+  --> $DIR/impl-fn-hrtb-bounds-2.rs:5:9
+   |
+LL |     |x| x
+   |     --- ^
+   |     |
+   |     hidden type `&u8` captures the anonymous lifetime #1 defined here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/impl-trait/impl-fn-hrtb-bounds.rs b/src/test/ui/impl-trait/impl-fn-hrtb-bounds.rs
new file mode 100644
index 00000000000..527a4586fd7
--- /dev/null
+++ b/src/test/ui/impl-trait/impl-fn-hrtb-bounds.rs
@@ -0,0 +1,24 @@
+#![feature(impl_trait_in_fn_trait_return)]
+use std::fmt::Debug;
+
+fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
+    //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+    |x| x
+}
+
+fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
+    //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+    |x| x
+}
+
+fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
+    //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+    |x| x
+}
+
+fn d() -> impl Fn() -> (impl Debug + '_) {
+    //~^ ERROR missing lifetime specifier
+    || ()
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/impl-fn-hrtb-bounds.stderr b/src/test/ui/impl-trait/impl-fn-hrtb-bounds.stderr
new file mode 100644
index 00000000000..443ffeb55cd
--- /dev/null
+++ b/src/test/ui/impl-trait/impl-fn-hrtb-bounds.stderr
@@ -0,0 +1,51 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/impl-fn-hrtb-bounds.rs:19:38
+   |
+LL | fn d() -> impl Fn() -> (impl Debug + '_) {
+   |                                      ^^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL | fn d() -> impl Fn() -> (impl Debug + 'static) {
+   |                                      ~~~~~~~
+
+error: higher kinded lifetime bounds on nested opaque types are not supported yet
+  --> $DIR/impl-fn-hrtb-bounds.rs:4:41
+   |
+LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
+   |                                         ^^
+   |
+note: lifetime declared here
+  --> $DIR/impl-fn-hrtb-bounds.rs:4:19
+   |
+LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
+   |                   ^
+
+error: higher kinded lifetime bounds on nested opaque types are not supported yet
+  --> $DIR/impl-fn-hrtb-bounds.rs:9:52
+   |
+LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
+   |                                                    ^^
+   |
+note: lifetime declared here
+  --> $DIR/impl-fn-hrtb-bounds.rs:9:20
+   |
+LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
+   |                    ^^
+
+error: higher kinded lifetime bounds on nested opaque types are not supported yet
+  --> $DIR/impl-fn-hrtb-bounds.rs:14:52
+   |
+LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
+   |                                                    ^^
+   |
+note: lifetime declared here
+  --> $DIR/impl-fn-hrtb-bounds.rs:14:20
+   |
+LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
+   |                    ^^
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.rs b/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.rs
new file mode 100644
index 00000000000..3e760710797
--- /dev/null
+++ b/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.rs
@@ -0,0 +1,15 @@
+#![feature(impl_trait_in_fn_trait_return)]
+use std::fmt::Debug;
+
+fn a() -> impl Fn(&u8) -> impl Debug + '_ {
+    //~^ ERROR ambiguous `+` in a type
+    //~^^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+    |x| x
+}
+
+fn b() -> impl Fn() -> impl Debug + Send {
+    //~^ ERROR ambiguous `+` in a type
+    || ()
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.stderr b/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.stderr
new file mode 100644
index 00000000000..cf6e5ef7bac
--- /dev/null
+++ b/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.stderr
@@ -0,0 +1,26 @@
+error: ambiguous `+` in a type
+  --> $DIR/impl-fn-parsing-ambiguities.rs:4:27
+   |
+LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ {
+   |                           ^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + '_)`
+
+error: ambiguous `+` in a type
+  --> $DIR/impl-fn-parsing-ambiguities.rs:10:24
+   |
+LL | fn b() -> impl Fn() -> impl Debug + Send {
+   |                        ^^^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + Send)`
+
+error: higher kinded lifetime bounds on nested opaque types are not supported yet
+  --> $DIR/impl-fn-parsing-ambiguities.rs:4:40
+   |
+LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ {
+   |                                        ^^
+   |
+note: lifetime declared here
+  --> $DIR/impl-fn-parsing-ambiguities.rs:4:19
+   |
+LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ {
+   |                   ^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/impl-trait/impl-fn-predefined-lifetimes.rs b/src/test/ui/impl-trait/impl-fn-predefined-lifetimes.rs
new file mode 100644
index 00000000000..15778662375
--- /dev/null
+++ b/src/test/ui/impl-trait/impl-fn-predefined-lifetimes.rs
@@ -0,0 +1,15 @@
+#![feature(impl_trait_in_fn_trait_return)]
+use std::fmt::Debug;
+
+fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
+    //~^ ERROR cannot resolve opaque type
+
+    |x| x
+    //~^ ERROR concrete type differs from previous defining opaque type use
+}
+
+fn _b<'a>() -> impl Fn(&'a u8) -> (impl Debug + 'a) {
+    a()
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/impl-fn-predefined-lifetimes.stderr b/src/test/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
new file mode 100644
index 00000000000..7747319c153
--- /dev/null
+++ b/src/test/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
@@ -0,0 +1,24 @@
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/impl-fn-predefined-lifetimes.rs:7:9
+   |
+LL |     |x| x
+   |         ^ expected `impl Debug + '_`, got `&u8`
+   |
+note: previous use here
+  --> $DIR/impl-fn-predefined-lifetimes.rs:7:5
+   |
+LL |     |x| x
+   |     ^^^^^
+
+error[E0720]: cannot resolve opaque type
+  --> $DIR/impl-fn-predefined-lifetimes.rs:4:35
+   |
+LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
+   |                                   ^^^^^^^^^^^^^^^ recursive opaque type
+...
+LL |     |x| x
+   |     ----- returning here with type `[closure@$DIR/impl-fn-predefined-lifetimes.rs:7:5: 7:8]`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0720`.
diff --git a/src/test/ui/impl-trait/impl_fn_associativity.rs b/src/test/ui/impl-trait/impl_fn_associativity.rs
new file mode 100644
index 00000000000..71a8f9c7796
--- /dev/null
+++ b/src/test/ui/impl-trait/impl_fn_associativity.rs
@@ -0,0 +1,26 @@
+// run-pass
+#![feature(impl_trait_in_fn_trait_return)]
+use std::fmt::Debug;
+
+fn f_debug() -> impl Fn() -> impl Debug {
+    || ()
+}
+
+fn ff_debug() -> impl Fn() -> impl Fn() -> impl Debug {
+    || f_debug()
+}
+
+fn multi() -> impl Fn() -> (impl Debug + Send) {
+    || ()
+}
+
+fn main() {
+    // Check that `ff_debug` is `() -> (() -> Debug)` and not `(() -> ()) -> Debug`
+    let debug = ff_debug()()();
+    assert_eq!(format!("{:?}", debug), "()");
+
+    let x = multi()();
+    assert_eq!(format!("{:?}", x), "()");
+    fn assert_send(_: &impl Send) {}
+    assert_send(&x);
+}
diff --git a/src/test/ui/impl-trait/in-trait/early.rs b/src/test/ui/impl-trait/in-trait/early.rs
new file mode 100644
index 00000000000..9c1c2b50339
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/early.rs
@@ -0,0 +1,23 @@
+// check-pass
+// edition:2021
+
+#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+pub trait Foo {
+    async fn bar<'a: 'a>(&'a mut self);
+}
+
+impl Foo for () {
+    async fn bar<'a: 'a>(&'a mut self) {}
+}
+
+pub trait Foo2 {
+    fn bar<'a: 'a>(&'a mut self) -> impl Sized + 'a;
+}
+
+impl Foo2 for () {
+    fn bar<'a: 'a>(&'a mut self) -> impl Sized + 'a {}
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/nested_impl_trait.rs b/src/test/ui/impl-trait/nested_impl_trait.rs
index 85c6f8c462c..e95fab3b650 100644
--- a/src/test/ui/impl-trait/nested_impl_trait.rs
+++ b/src/test/ui/impl-trait/nested_impl_trait.rs
@@ -1,3 +1,4 @@
+#![feature(impl_trait_in_fn_trait_return)]
 use std::fmt::Debug;
 
 fn fine(x: impl Into<u32>) -> impl Into<u32> { x }
@@ -25,8 +26,7 @@ fn allowed_in_assoc_type() -> impl Iterator<Item=impl Fn()> {
 }
 
 fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
-//~^ `impl Trait` only allowed in function and inherent method return types
-    || 5
+    || 5u8
 }
 
 fn main() {}
diff --git a/src/test/ui/impl-trait/nested_impl_trait.stderr b/src/test/ui/impl-trait/nested_impl_trait.stderr
index 3291cad6882..9a8f5a34068 100644
--- a/src/test/ui/impl-trait/nested_impl_trait.stderr
+++ b/src/test/ui/impl-trait/nested_impl_trait.stderr
@@ -1,5 +1,5 @@
 error[E0666]: nested `impl Trait` is not allowed
-  --> $DIR/nested_impl_trait.rs:5:56
+  --> $DIR/nested_impl_trait.rs:6:56
    |
 LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
    |                                              ----------^^^^^^^^^^-
@@ -8,7 +8,7 @@ LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
    |                                              outer `impl Trait`
 
 error[E0666]: nested `impl Trait` is not allowed
-  --> $DIR/nested_impl_trait.rs:9:42
+  --> $DIR/nested_impl_trait.rs:10:42
    |
 LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
    |                                ----------^^^^^^^^^^-
@@ -17,7 +17,7 @@ LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
    |                                outer `impl Trait`
 
 error[E0666]: nested `impl Trait` is not allowed
-  --> $DIR/nested_impl_trait.rs:13:37
+  --> $DIR/nested_impl_trait.rs:14:37
    |
 LL | fn bad_in_arg_position(_: impl Into<impl Debug>) { }
    |                           ----------^^^^^^^^^^-
@@ -26,7 +26,7 @@ LL | fn bad_in_arg_position(_: impl Into<impl Debug>) { }
    |                           outer `impl Trait`
 
 error[E0666]: nested `impl Trait` is not allowed
-  --> $DIR/nested_impl_trait.rs:18:44
+  --> $DIR/nested_impl_trait.rs:19:44
    |
 LL |     fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
    |                                  ----------^^^^^^^^^^-
@@ -35,19 +35,13 @@ LL |     fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
    |                                  outer `impl Trait`
 
 error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
-  --> $DIR/nested_impl_trait.rs:9:32
+  --> $DIR/nested_impl_trait.rs:10:32
    |
 LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
    |                                ^^^^^^^^^^^^^^^^^^^^^
 
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
-  --> $DIR/nested_impl_trait.rs:27:42
-   |
-LL | fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
-   |                                          ^^^^^^^^^^^^^^
-
 error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
-  --> $DIR/nested_impl_trait.rs:5:46
+  --> $DIR/nested_impl_trait.rs:6:46
    |
 LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
    |                                              ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
@@ -56,7 +50,7 @@ LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
    = note: required for `impl Into<u32>` to implement `Into<impl Debug>`
 
 error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
-  --> $DIR/nested_impl_trait.rs:18:34
+  --> $DIR/nested_impl_trait.rs:19:34
    |
 LL |     fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
    |                                  ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
@@ -64,7 +58,7 @@ LL |     fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
    = help: the trait `Into<U>` is implemented for `T`
    = note: required for `impl Into<u32>` to implement `Into<impl Debug>`
 
-error: aborting due to 8 previous errors
+error: aborting due to 7 previous errors
 
 Some errors have detailed explanations: E0277, E0562, E0666.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/impl-trait/where-allowed.rs b/src/test/ui/impl-trait/where-allowed.rs
index c1dd46c7ff7..ff63b04c268 100644
--- a/src/test/ui/impl-trait/where-allowed.rs
+++ b/src/test/ui/impl-trait/where-allowed.rs
@@ -1,5 +1,6 @@
 //! A simple test for testing many permutations of allowedness of
 //! impl Trait
+#![feature(impl_trait_in_fn_trait_return)]
 use std::fmt::Debug;
 
 // Allowed
@@ -39,9 +40,8 @@ fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() }
 fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
 //~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
-// Disallowed
+// Allowed
 fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
-//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
@@ -57,9 +57,8 @@ fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
 //~^ ERROR `impl Trait` only allowed in function and inherent method return types
 //~| ERROR nested `impl Trait` is not allowed
 
-// Disallowed
+// Allowed
 fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
-//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
diff --git a/src/test/ui/impl-trait/where-allowed.stderr b/src/test/ui/impl-trait/where-allowed.stderr
index 2e7c7ca40dd..3ad0a9f9d5c 100644
--- a/src/test/ui/impl-trait/where-allowed.stderr
+++ b/src/test/ui/impl-trait/where-allowed.stderr
@@ -17,7 +17,7 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic
    |                                                 outer `impl Trait`
 
 error[E0658]: `impl Trait` in type aliases is unstable
-  --> $DIR/where-allowed.rs:119:16
+  --> $DIR/where-allowed.rs:118:16
    |
 LL |     type Out = impl Debug;
    |                ^^^^^^^^^^
@@ -26,7 +26,7 @@ LL |     type Out = impl Debug;
    = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
 
 error[E0658]: `impl Trait` in type aliases is unstable
-  --> $DIR/where-allowed.rs:154:23
+  --> $DIR/where-allowed.rs:153:23
    |
 LL | type InTypeAlias<R> = impl Debug;
    |                       ^^^^^^^^^^
@@ -35,7 +35,7 @@ LL | type InTypeAlias<R> = impl Debug;
    = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
 
 error[E0658]: `impl Trait` in type aliases is unstable
-  --> $DIR/where-allowed.rs:157:39
+  --> $DIR/where-allowed.rs:156:39
    |
 LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    |                                       ^^^^^^^^^^
@@ -44,53 +44,47 @@ LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    = 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
-  --> $DIR/where-allowed.rs:15:40
+  --> $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
-  --> $DIR/where-allowed.rs:19:42
+  --> $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
-  --> $DIR/where-allowed.rs:23:38
+  --> $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
-  --> $DIR/where-allowed.rs:27:40
+  --> $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
-  --> $DIR/where-allowed.rs:31:49
+  --> $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
-  --> $DIR/where-allowed.rs:35:51
+  --> $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
-  --> $DIR/where-allowed.rs:39:55
+  --> $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 return
-  --> $DIR/where-allowed.rs:43:57
-   |
-LL | fn in_dyn_Fn_return_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
   --> $DIR/where-allowed.rs:47:51
    |
@@ -109,56 +103,50 @@ error[E0562]: `impl Trait` only allowed in function and inherent method return t
 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 return
-  --> $DIR/where-allowed.rs:61:59
-   |
-LL | fn in_impl_Fn_return_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
-  --> $DIR/where-allowed.rs:65:38
+  --> $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
-  --> $DIR/where-allowed.rs:69:40
+  --> $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 type
-  --> $DIR/where-allowed.rs:82:32
+  --> $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 path
-  --> $DIR/where-allowed.rs:86:41
+  --> $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 type
-  --> $DIR/where-allowed.rs:90:27
+  --> $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 type
-  --> $DIR/where-allowed.rs:95:25
+  --> $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 type
-  --> $DIR/where-allowed.rs:97:20
+  --> $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
-  --> $DIR/where-allowed.rs:108:23
+  --> $DIR/where-allowed.rs:107:23
    |
 LL |     fn in_return() -> impl Debug;
    |                       ^^^^^^^^^^
@@ -167,7 +155,7 @@ LL |     fn in_return() -> impl Debug;
    = 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
-  --> $DIR/where-allowed.rs:125:34
+  --> $DIR/where-allowed.rs:124:34
    |
 LL |     fn in_trait_impl_return() -> impl Debug { () }
    |                                  ^^^^^^^^^^
@@ -176,127 +164,127 @@ LL |     fn in_trait_impl_return() -> impl Debug { () }
    = 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
-  --> $DIR/where-allowed.rs:138:33
+  --> $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
-  --> $DIR/where-allowed.rs:141:31
+  --> $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
-  --> $DIR/where-allowed.rs:157:39
+  --> $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
-  --> $DIR/where-allowed.rs:162:16
+  --> $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 type
-  --> $DIR/where-allowed.rs:167:24
+  --> $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 type
-  --> $DIR/where-allowed.rs:172:6
+  --> $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 type
-  --> $DIR/where-allowed.rs:178:24
+  --> $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 type
-  --> $DIR/where-allowed.rs:184:11
+  --> $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 type
-  --> $DIR/where-allowed.rs:191:15
+  --> $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
-  --> $DIR/where-allowed.rs:198:24
+  --> $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
-  --> $DIR/where-allowed.rs:205:17
+  --> $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
-  --> $DIR/where-allowed.rs:212:22
+  --> $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 type
-  --> $DIR/where-allowed.rs:218:40
+  --> $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 type
-  --> $DIR/where-allowed.rs:222:36
+  --> $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 type
-  --> $DIR/where-allowed.rs:226:38
+  --> $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 type
-  --> $DIR/where-allowed.rs:230:41
+  --> $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 type
-  --> $DIR/where-allowed.rs:234:11
+  --> $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 type
-  --> $DIR/where-allowed.rs:241:40
+  --> $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
-  --> $DIR/where-allowed.rs:247:29
+  --> $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
-  --> $DIR/where-allowed.rs:249:46
+  --> $DIR/where-allowed.rs:248:46
    |
 LL |     let _in_return_in_local_variable = || -> impl Fn() { || {} };
    |                                              ^^^^^^^^^
 
 error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/where-allowed.rs:234:7
+  --> $DIR/where-allowed.rs:233:7
    |
 LL | impl <T = impl Debug> T {}
    |       ^^^^^^^^^^^^^^
@@ -306,7 +294,7 @@ LL | impl <T = impl Debug> T {}
    = note: `#[deny(invalid_type_param_default)]` on by default
 
 error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/where-allowed.rs:241:36
+  --> $DIR/where-allowed.rs:240:36
    |
 LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    |                                    ^^^^^^^^^^^^^^
@@ -315,14 +303,14 @@ LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
 
 error[E0118]: no nominal type found for inherent implementation
-  --> $DIR/where-allowed.rs:234:23
+  --> $DIR/where-allowed.rs:233:23
    |
 LL | impl <T = impl Debug> T {}
    |                       ^ impl requires a nominal type
    |
    = note: either implement a trait on it or create a newtype to wrap it instead
 
-error: aborting due to 49 previous errors
+error: aborting due to 47 previous errors
 
 Some errors have detailed explanations: E0118, E0562, E0658, E0666.
 For more information about an error, try `rustc --explain E0118`.
diff --git a/src/test/ui/let-else/let-else-irrefutable.rs b/src/test/ui/let-else/let-else-irrefutable.rs
index 1cb68ecb8a6..f4b338eb0af 100644
--- a/src/test/ui/let-else/let-else-irrefutable.rs
+++ b/src/test/ui/let-else/let-else-irrefutable.rs
@@ -1,7 +1,11 @@
 // check-pass
 
-
-
 fn main() {
     let x = 1 else { return }; //~ WARN irrefutable `let...else` pattern
+
+    // Multiline else blocks should not get printed
+    let x = 1 else { //~ WARN irrefutable `let...else` pattern
+        eprintln!("problem case encountered");
+        return
+    };
 }
diff --git a/src/test/ui/let-else/let-else-irrefutable.stderr b/src/test/ui/let-else/let-else-irrefutable.stderr
index e0581f4d9ab..73d4e5f3483 100644
--- a/src/test/ui/let-else/let-else-irrefutable.stderr
+++ b/src/test/ui/let-else/let-else-irrefutable.stderr
@@ -1,12 +1,21 @@
 warning: irrefutable `let...else` pattern
-  --> $DIR/let-else-irrefutable.rs:6:5
+  --> $DIR/let-else-irrefutable.rs:4:5
    |
 LL |     let x = 1 else { return };
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^
    |
    = note: this pattern will always match, so the `else` clause is useless
    = help: consider removing the `else` clause
    = note: `#[warn(irrefutable_let_patterns)]` on by default
 
-warning: 1 warning emitted
+warning: irrefutable `let...else` pattern
+  --> $DIR/let-else-irrefutable.rs:7:5
+   |
+LL |     let x = 1 else {
+   |     ^^^^^^^^^
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+
+warning: 2 warnings emitted
 
diff --git a/src/test/ui/lexical-scopes.stderr b/src/test/ui/lexical-scopes.stderr
index 53598545223..f0eaa1a5c64 100644
--- a/src/test/ui/lexical-scopes.stderr
+++ b/src/test/ui/lexical-scopes.stderr
@@ -2,7 +2,7 @@ error[E0574]: expected struct, variant or union type, found type parameter `T`
   --> $DIR/lexical-scopes.rs:3:13
    |
 LL | struct T { i: i32 }
-   | ------------------- you might have meant to refer to this struct
+   |        - you might have meant to refer to this struct
 LL | fn f<T>() {
    |      - found this type parameter
 LL |     let t = T { i: 0 };
diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs
index 7a2eba518fe..d0a8fe795ef 100644
--- a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs
+++ b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs
@@ -42,4 +42,10 @@ fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &isize {
     panic!()
 }
 
+fn l<'a>(_: &'a str, _: &'a str) -> &str { "" }
+//~^ ERROR missing lifetime specifier
+
+// This is ok because both `'a` are for the same parameter.
+fn m<'a>(_: &'a Foo<'a>) -> &str { "" }
+
 fn main() {}
diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
index d0775487955..5eee953ef18 100644
--- a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
+++ b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
@@ -70,6 +70,18 @@ help: consider using the `'a` lifetime
 LL | fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &'a isize {
    |                                                  ++
 
-error: aborting due to 6 previous errors
+error[E0106]: missing lifetime specifier
+  --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:45:37
+   |
+LL | fn l<'a>(_: &'a str, _: &'a str) -> &str { "" }
+   |             -------     -------     ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
+help: consider using the `'a` lifetime
+   |
+LL | fn l<'a>(_: &'a str, _: &'a str) -> &'a str { "" }
+   |                                      ++
+
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/lint/inline-trait-and-foreign-items.stderr b/src/test/ui/lint/inline-trait-and-foreign-items.stderr
index 27399746bed..2f1fb4c46c0 100644
--- a/src/test/ui/lint/inline-trait-and-foreign-items.stderr
+++ b/src/test/ui/lint/inline-trait-and-foreign-items.stderr
@@ -67,7 +67,7 @@ error: unconstrained opaque type
 LL |     type U = impl Trait;
    |              ^^^^^^^^^^
    |
-   = note: `U` must be used in combination with a concrete type within the same module
+   = note: `U` must be used in combination with a concrete type within the same impl
 
 error: aborting due to 6 previous errors; 2 warnings emitted
 
diff --git a/src/test/ui/lint/issue-103317.fixed b/src/test/ui/lint/issue-103317.fixed
new file mode 100644
index 00000000000..5a987423e5b
--- /dev/null
+++ b/src/test/ui/lint/issue-103317.fixed
@@ -0,0 +1,14 @@
+// check-pass
+// run-rustfix
+
+#[warn(unreachable_pub)]
+mod inner {
+    #[allow(unused)]
+    pub(crate) enum T {
+        //~^ WARN unreachable `pub` item
+        A(u8),
+        X { a: f32, b: () },
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/issue-103317.rs b/src/test/ui/lint/issue-103317.rs
new file mode 100644
index 00000000000..c2ba939e13c
--- /dev/null
+++ b/src/test/ui/lint/issue-103317.rs
@@ -0,0 +1,14 @@
+// check-pass
+// run-rustfix
+
+#[warn(unreachable_pub)]
+mod inner {
+    #[allow(unused)]
+    pub enum T {
+        //~^ WARN unreachable `pub` item
+        A(u8),
+        X { a: f32, b: () },
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/issue-103317.stderr b/src/test/ui/lint/issue-103317.stderr
new file mode 100644
index 00000000000..9c982ddc346
--- /dev/null
+++ b/src/test/ui/lint/issue-103317.stderr
@@ -0,0 +1,17 @@
+warning: unreachable `pub` item
+  --> $DIR/issue-103317.rs:7:5
+   |
+LL |     pub enum T {
+   |     ---^^^^^^^
+   |     |
+   |     help: consider restricting its visibility: `pub(crate)`
+   |
+   = help: or consider exporting it for use by other crates
+note: the lint level is defined here
+  --> $DIR/issue-103317.rs:4:8
+   |
+LL | #[warn(unreachable_pub)]
+   |        ^^^^^^^^^^^^^^^
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/lint/no-coverage.stderr b/src/test/ui/lint/no-coverage.stderr
index 8452ccc7a03..404efbeac1e 100644
--- a/src/test/ui/lint/no-coverage.stderr
+++ b/src/test/ui/lint/no-coverage.stderr
@@ -94,7 +94,7 @@ error: unconstrained opaque type
 LL |     type U = impl Trait;
    |              ^^^^^^^^^^
    |
-   = note: `U` must be used in combination with a concrete type within the same module
+   = note: `U` must be used in combination with a concrete type within the same impl
 
 error: aborting due to 7 previous errors; 6 warnings emitted
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
index da4bc499c7e..01293379700 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
@@ -53,14 +53,15 @@ LL | fn case2() {
 error[E0597]: `a` does not live long enough
   --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:30:26
    |
-LL |     let cell = Cell::new(&a);
-   |                ----------^^-
-   |                |         |
-   |                |         borrowed value does not live long enough
-   |                argument requires that `a` is borrowed for `'static`
+LL |       let cell = Cell::new(&a);
+   |                            ^^ borrowed value does not live long enough
 ...
-LL | }
-   | - `a` dropped here while still borrowed
+LL | /     foo(cell, |cell_a, cell_x| {
+LL | |         cell_x.set(cell_a.get()); // forces 'a: 'x, implies 'a = 'static -> borrow error
+LL | |     })
+   | |______- argument requires that `a` is borrowed for `'static`
+LL |   }
+   |   - `a` dropped here while still borrowed
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/nll/user-annotations/adt-nullary-enums.stderr b/src/test/ui/nll/user-annotations/adt-nullary-enums.stderr
index bb703412228..3326fa521fc 100644
--- a/src/test/ui/nll/user-annotations/adt-nullary-enums.stderr
+++ b/src/test/ui/nll/user-annotations/adt-nullary-enums.stderr
@@ -1,14 +1,14 @@
 error[E0597]: `c` does not live long enough
   --> $DIR/adt-nullary-enums.rs:33:41
    |
-LL |         SomeEnum::SomeVariant(Cell::new(&c)),
-   |                               ----------^^-
-   |                               |         |
-   |                               |         borrowed value does not live long enough
-   |                               argument requires that `c` is borrowed for `'static`
-...
-LL | }
-   | - `c` dropped here while still borrowed
+LL | /     combine(
+LL | |         SomeEnum::SomeVariant(Cell::new(&c)),
+   | |                                         ^^ borrowed value does not live long enough
+LL | |         SomeEnum::SomeOtherVariant::<Cell<&'static u32>>,
+LL | |     );
+   | |_____- argument requires that `c` is borrowed for `'static`
+LL |   }
+   |   - `c` dropped here while still borrowed
 
 error[E0597]: `c` does not live long enough
   --> $DIR/adt-nullary-enums.rs:41:41
diff --git a/src/test/ui/privacy/access_levels.rs b/src/test/ui/privacy/access_levels.rs
deleted file mode 100644
index 6bca7161886..00000000000
--- a/src/test/ui/privacy/access_levels.rs
+++ /dev/null
@@ -1,75 +0,0 @@
-#![feature(rustc_attrs)]
-
-#[rustc_effective_visibility]
-mod outer { //~ ERROR Public: pub(crate), Exported: pub(crate), Reachable: pub(crate), ReachableFromImplTrait: pub(crate)
-    #[rustc_effective_visibility]
-    pub mod inner1 { //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-
-        #[rustc_effective_visibility]
-        extern "C" {} //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-
-        #[rustc_effective_visibility]
-        pub trait PubTrait { //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-            #[rustc_effective_visibility]
-            const A: i32; //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-            #[rustc_effective_visibility]
-            type B; //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-        }
-
-        #[rustc_effective_visibility]
-        struct PrivStruct; //~ ERROR not in the table
-
-        #[rustc_effective_visibility]
-        pub union PubUnion { //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-            #[rustc_effective_visibility]
-            a: u8, //~ ERROR not in the table
-            #[rustc_effective_visibility]
-            pub b: u8, //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-        }
-
-        #[rustc_effective_visibility]
-        pub enum Enum { //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-            #[rustc_effective_visibility]
-            A( //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-                #[rustc_effective_visibility]
-                PubUnion,  //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-            ),
-        }
-    }
-
-    #[rustc_effective_visibility]
-    macro_rules! none_macro { //~ ERROR Public: pub(crate), Exported: pub(crate), Reachable: pub(crate), ReachableFromImplTrait: pub(crate)
-        () => {};
-    }
-
-    #[macro_export]
-    #[rustc_effective_visibility]
-    macro_rules! public_macro { //~ ERROR Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-        () => {};
-    }
-
-    #[rustc_effective_visibility]
-    pub struct ReachableStruct { //~ ERROR Public: pub(crate), Exported: pub(crate), Reachable: pub, ReachableFromImplTrait: pub
-        #[rustc_effective_visibility]
-        pub a: u8, //~ ERROR Public: pub(crate), Exported: pub(crate), Reachable: pub, ReachableFromImplTrait: pub
-    }
-}
-
-#[rustc_effective_visibility]
-pub use outer::inner1; //~ ERROR Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-
-pub fn foo() -> outer::ReachableStruct { outer::ReachableStruct {a: 0} }
-
-mod half_public_import {
-    #[rustc_effective_visibility]
-    pub type HalfPublicImport = u8; //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-    #[rustc_effective_visibility]
-    #[allow(non_upper_case_globals)]
-    pub(crate) const HalfPublicImport: u8 = 0; //~ ERROR Public: pub(crate), Exported: pub(crate), Reachable: pub(crate), ReachableFromImplTrait: pub(crate)
-}
-
-#[rustc_effective_visibility]
-pub use half_public_import::HalfPublicImport; //~ ERROR Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-                                              //~^ ERROR Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-
-fn main() {}
diff --git a/src/test/ui/privacy/access_levels.stderr b/src/test/ui/privacy/access_levels.stderr
deleted file mode 100644
index 07c4d436ff0..00000000000
--- a/src/test/ui/privacy/access_levels.stderr
+++ /dev/null
@@ -1,134 +0,0 @@
-error: Public: pub(crate), Exported: pub(crate), Reachable: pub(crate), ReachableFromImplTrait: pub(crate)
-  --> $DIR/access_levels.rs:4:1
-   |
-LL | mod outer {
-   | ^^^^^^^^^
-
-error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-  --> $DIR/access_levels.rs:6:5
-   |
-LL |     pub mod inner1 {
-   |     ^^^^^^^^^^^^^^
-
-error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-  --> $DIR/access_levels.rs:9:9
-   |
-LL |         extern "C" {}
-   |         ^^^^^^^^^^^^^
-
-error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-  --> $DIR/access_levels.rs:12:9
-   |
-LL |         pub trait PubTrait {
-   |         ^^^^^^^^^^^^^^^^^^
-
-error: not in the table
-  --> $DIR/access_levels.rs:20:9
-   |
-LL |         struct PrivStruct;
-   |         ^^^^^^^^^^^^^^^^^
-
-error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-  --> $DIR/access_levels.rs:23:9
-   |
-LL |         pub union PubUnion {
-   |         ^^^^^^^^^^^^^^^^^^
-
-error: not in the table
-  --> $DIR/access_levels.rs:25:13
-   |
-LL |             a: u8,
-   |             ^^^^^
-
-error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-  --> $DIR/access_levels.rs:27:13
-   |
-LL |             pub b: u8,
-   |             ^^^^^^^^^
-
-error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-  --> $DIR/access_levels.rs:31:9
-   |
-LL |         pub enum Enum {
-   |         ^^^^^^^^^^^^^
-
-error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-  --> $DIR/access_levels.rs:33:13
-   |
-LL |             A(
-   |             ^
-
-error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-  --> $DIR/access_levels.rs:35:17
-   |
-LL |                 PubUnion,
-   |                 ^^^^^^^^
-
-error: Public: pub(crate), Exported: pub(crate), Reachable: pub(crate), ReachableFromImplTrait: pub(crate)
-  --> $DIR/access_levels.rs:41:5
-   |
-LL |     macro_rules! none_macro {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
-
-error: Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-  --> $DIR/access_levels.rs:47:5
-   |
-LL |     macro_rules! public_macro {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: Public: pub(crate), Exported: pub(crate), Reachable: pub, ReachableFromImplTrait: pub
-  --> $DIR/access_levels.rs:52:5
-   |
-LL |     pub struct ReachableStruct {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: Public: pub(crate), Exported: pub(crate), Reachable: pub, ReachableFromImplTrait: pub
-  --> $DIR/access_levels.rs:54:9
-   |
-LL |         pub a: u8,
-   |         ^^^^^^^^^
-
-error: Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-  --> $DIR/access_levels.rs:59:9
-   |
-LL | pub use outer::inner1;
-   |         ^^^^^^^^^^^^^
-
-error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-  --> $DIR/access_levels.rs:65:5
-   |
-LL |     pub type HalfPublicImport = u8;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: Public: pub(crate), Exported: pub(crate), Reachable: pub(crate), ReachableFromImplTrait: pub(crate)
-  --> $DIR/access_levels.rs:68:5
-   |
-LL |     pub(crate) const HalfPublicImport: u8 = 0;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-  --> $DIR/access_levels.rs:72:9
-   |
-LL | pub use half_public_import::HalfPublicImport;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-  --> $DIR/access_levels.rs:72:9
-   |
-LL | pub use half_public_import::HalfPublicImport;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-  --> $DIR/access_levels.rs:14:13
-   |
-LL |             const A: i32;
-   |             ^^^^^^^^^^^^
-
-error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
-  --> $DIR/access_levels.rs:16:13
-   |
-LL |             type B;
-   |             ^^^^^^
-
-error: aborting due to 22 previous errors
-
diff --git a/src/test/ui/privacy/effective_visibilities.rs b/src/test/ui/privacy/effective_visibilities.rs
new file mode 100644
index 00000000000..1d806a1d1d1
--- /dev/null
+++ b/src/test/ui/privacy/effective_visibilities.rs
@@ -0,0 +1,75 @@
+#![feature(rustc_attrs)]
+
+#[rustc_effective_visibility]
+mod outer { //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
+    #[rustc_effective_visibility]
+    pub mod inner1 { //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+
+        #[rustc_effective_visibility]
+        extern "C" {} //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+
+        #[rustc_effective_visibility]
+        pub trait PubTrait { //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+            #[rustc_effective_visibility]
+            const A: i32; //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+            #[rustc_effective_visibility]
+            type B; //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+        }
+
+        #[rustc_effective_visibility]
+        struct PrivStruct; //~ ERROR not in the table
+
+        #[rustc_effective_visibility]
+        pub union PubUnion { //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+            #[rustc_effective_visibility]
+            a: u8, //~ ERROR not in the table
+            #[rustc_effective_visibility]
+            pub b: u8, //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+        }
+
+        #[rustc_effective_visibility]
+        pub enum Enum { //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+            #[rustc_effective_visibility]
+            A( //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+                #[rustc_effective_visibility]
+                PubUnion,  //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+            ),
+        }
+    }
+
+    #[rustc_effective_visibility]
+    macro_rules! none_macro { //~ Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
+        () => {};
+    }
+
+    #[macro_export]
+    #[rustc_effective_visibility]
+    macro_rules! public_macro { //~ Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+        () => {};
+    }
+
+    #[rustc_effective_visibility]
+    pub struct ReachableStruct { //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub
+        #[rustc_effective_visibility]
+        pub a: u8, //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub
+    }
+}
+
+#[rustc_effective_visibility]
+pub use outer::inner1; //~ ERROR Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+
+pub fn foo() -> outer::ReachableStruct { outer::ReachableStruct {a: 0} }
+
+mod half_public_import {
+    #[rustc_effective_visibility]
+    pub type HalfPublicImport = u8; //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+    #[rustc_effective_visibility]
+    #[allow(non_upper_case_globals)]
+    pub(crate) const HalfPublicImport: u8 = 0; //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
+}
+
+#[rustc_effective_visibility]
+pub use half_public_import::HalfPublicImport; //~ ERROR Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+                                              //~^ ERROR Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+
+fn main() {}
diff --git a/src/test/ui/privacy/effective_visibilities.stderr b/src/test/ui/privacy/effective_visibilities.stderr
new file mode 100644
index 00000000000..1c6201600b6
--- /dev/null
+++ b/src/test/ui/privacy/effective_visibilities.stderr
@@ -0,0 +1,134 @@
+error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
+  --> $DIR/effective_visibilities.rs:4:1
+   |
+LL | mod outer {
+   | ^^^^^^^^^
+
+error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+  --> $DIR/effective_visibilities.rs:6:5
+   |
+LL |     pub mod inner1 {
+   |     ^^^^^^^^^^^^^^
+
+error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+  --> $DIR/effective_visibilities.rs:9:9
+   |
+LL |         extern "C" {}
+   |         ^^^^^^^^^^^^^
+
+error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+  --> $DIR/effective_visibilities.rs:12:9
+   |
+LL |         pub trait PubTrait {
+   |         ^^^^^^^^^^^^^^^^^^
+
+error: not in the table
+  --> $DIR/effective_visibilities.rs:20:9
+   |
+LL |         struct PrivStruct;
+   |         ^^^^^^^^^^^^^^^^^
+
+error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+  --> $DIR/effective_visibilities.rs:23:9
+   |
+LL |         pub union PubUnion {
+   |         ^^^^^^^^^^^^^^^^^^
+
+error: not in the table
+  --> $DIR/effective_visibilities.rs:25:13
+   |
+LL |             a: u8,
+   |             ^^^^^
+
+error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+  --> $DIR/effective_visibilities.rs:27:13
+   |
+LL |             pub b: u8,
+   |             ^^^^^^^^^
+
+error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+  --> $DIR/effective_visibilities.rs:31:9
+   |
+LL |         pub enum Enum {
+   |         ^^^^^^^^^^^^^
+
+error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+  --> $DIR/effective_visibilities.rs:33:13
+   |
+LL |             A(
+   |             ^
+
+error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+  --> $DIR/effective_visibilities.rs:35:17
+   |
+LL |                 PubUnion,
+   |                 ^^^^^^^^
+
+error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
+  --> $DIR/effective_visibilities.rs:41:5
+   |
+LL |     macro_rules! none_macro {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+  --> $DIR/effective_visibilities.rs:47:5
+   |
+LL |     macro_rules! public_macro {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub
+  --> $DIR/effective_visibilities.rs:52:5
+   |
+LL |     pub struct ReachableStruct {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub
+  --> $DIR/effective_visibilities.rs:54:9
+   |
+LL |         pub a: u8,
+   |         ^^^^^^^^^
+
+error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+  --> $DIR/effective_visibilities.rs:59:9
+   |
+LL | pub use outer::inner1;
+   |         ^^^^^^^^^^^^^
+
+error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+  --> $DIR/effective_visibilities.rs:65:5
+   |
+LL |     pub type HalfPublicImport = u8;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
+  --> $DIR/effective_visibilities.rs:68:5
+   |
+LL |     pub(crate) const HalfPublicImport: u8 = 0;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+  --> $DIR/effective_visibilities.rs:72:9
+   |
+LL | pub use half_public_import::HalfPublicImport;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+  --> $DIR/effective_visibilities.rs:72:9
+   |
+LL | pub use half_public_import::HalfPublicImport;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+  --> $DIR/effective_visibilities.rs:14:13
+   |
+LL |             const A: i32;
+   |             ^^^^^^^^^^^^
+
+error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+  --> $DIR/effective_visibilities.rs:16:13
+   |
+LL |             type B;
+   |             ^^^^^^
+
+error: aborting due to 22 previous errors
+
diff --git a/src/test/ui/resolve/issue-23305.rs b/src/test/ui/resolve/issue-23305.rs
index 95635e12a63..6d7fe7c50a2 100644
--- a/src/test/ui/resolve/issue-23305.rs
+++ b/src/test/ui/resolve/issue-23305.rs
@@ -3,6 +3,6 @@ pub trait ToNbt<T> {
 }
 
 impl dyn ToNbt<Self> {}
-//~^ ERROR cycle detected
+//~^ ERROR `Self` is not valid in the self type of an impl block
 
 fn main() {}
diff --git a/src/test/ui/resolve/issue-23305.stderr b/src/test/ui/resolve/issue-23305.stderr
index 20aeb7b995a..aad1b583a32 100644
--- a/src/test/ui/resolve/issue-23305.stderr
+++ b/src/test/ui/resolve/issue-23305.stderr
@@ -1,22 +1,10 @@
-error[E0391]: cycle detected when computing type of `<impl at $DIR/issue-23305.rs:5:1: 5:21>`
+error: `Self` is not valid in the self type of an impl block
   --> $DIR/issue-23305.rs:5:16
    |
 LL | impl dyn ToNbt<Self> {}
    |                ^^^^
    |
-   = note: ...which immediately requires computing type of `<impl at $DIR/issue-23305.rs:5:1: 5:21>` again
-note: cycle used when collecting item types in top-level module
-  --> $DIR/issue-23305.rs:1:1
-   |
-LL | / pub trait ToNbt<T> {
-LL | |     fn new(val: T) -> Self;
-LL | | }
-LL | |
-...  |
-LL | |
-LL | | fn main() {}
-   | |____________^
+   = note: replace `Self` with a different type
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr b/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr
index eb26cd9cabb..5790e425c0a 100644
--- a/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr
+++ b/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr
@@ -1,16 +1,14 @@
 error[E0574]: expected struct, variant or union type, found type parameter `Baz`
   --> $DIR/point-at-type-parameter-shadowing-another-type.rs:16:13
    |
-LL | / struct Baz {
-LL | |     num: usize,
-LL | | }
-   | |_- you might have meant to refer to this struct
-LL |
-LL |   impl<Baz> Foo<Baz> for Bar {
-   |        --- found this type parameter
+LL | struct Baz {
+   |        --- you might have meant to refer to this struct
 ...
-LL |               Baz { num } => num,
-   |               ^^^ not a struct, variant or union type
+LL | impl<Baz> Foo<Baz> for Bar {
+   |      --- found this type parameter
+...
+LL |             Baz { num } => num,
+   |             ^^^ not a struct, variant or union type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/resolve/resolve-self-in-impl.rs b/src/test/ui/resolve/resolve-self-in-impl.rs
index 024fdc51ea3..d0872d1b76f 100644
--- a/src/test/ui/resolve/resolve-self-in-impl.rs
+++ b/src/test/ui/resolve/resolve-self-in-impl.rs
@@ -11,10 +11,11 @@ impl Tr for S where Self: Copy {} // OK
 impl Tr for S where S<Self>: Copy {} // OK
 impl Tr for S where Self::A: Copy {} // OK
 
-impl Tr for Self {} //~ ERROR cycle detected
-impl Tr for S<Self> {} //~ ERROR cycle detected
-impl Self {} //~ ERROR cycle detected
-impl S<Self> {} //~ ERROR cycle detected
+impl Tr for Self {} //~ ERROR `Self` is not valid in the self type of an impl block
+impl Tr for S<Self> {} //~ ERROR `Self` is not valid in the self type of an impl block
+impl Self {} //~ ERROR `Self` is not valid in the self type of an impl block
+impl S<Self> {} //~ ERROR `Self` is not valid in the self type of an impl block
+impl (Self, Self) {} //~ ERROR `Self` is not valid in the self type of an impl block
 impl Tr<Self::A> for S {} //~ ERROR cycle detected
 
 fn main() {}
diff --git a/src/test/ui/resolve/resolve-self-in-impl.stderr b/src/test/ui/resolve/resolve-self-in-impl.stderr
index aa99c1a3335..9f9ed68898f 100644
--- a/src/test/ui/resolve/resolve-self-in-impl.stderr
+++ b/src/test/ui/resolve/resolve-self-in-impl.stderr
@@ -1,86 +1,50 @@
-error[E0391]: cycle detected when computing type of `<impl at $DIR/resolve-self-in-impl.rs:14:1: 14:17>`
+error: `Self` is not valid in the self type of an impl block
   --> $DIR/resolve-self-in-impl.rs:14:13
    |
 LL | impl Tr for Self {}
    |             ^^^^
    |
-   = note: ...which immediately requires computing type of `<impl at $DIR/resolve-self-in-impl.rs:14:1: 14:17>` again
-note: cycle used when collecting item types in top-level module
-  --> $DIR/resolve-self-in-impl.rs:1:1
-   |
-LL | / #![feature(associated_type_defaults)]
-LL | |
-LL | | struct S<T = u8>(T);
-LL | | trait Tr<T = u8> {
-...  |
-LL | |
-LL | | fn main() {}
-   | |____________^
+   = note: replace `Self` with a different type
 
-error[E0391]: cycle detected when computing type of `<impl at $DIR/resolve-self-in-impl.rs:15:1: 15:20>`
+error: `Self` is not valid in the self type of an impl block
   --> $DIR/resolve-self-in-impl.rs:15:15
    |
 LL | impl Tr for S<Self> {}
    |               ^^^^
    |
-   = note: ...which immediately requires computing type of `<impl at $DIR/resolve-self-in-impl.rs:15:1: 15:20>` again
-note: cycle used when collecting item types in top-level module
-  --> $DIR/resolve-self-in-impl.rs:1:1
-   |
-LL | / #![feature(associated_type_defaults)]
-LL | |
-LL | | struct S<T = u8>(T);
-LL | | trait Tr<T = u8> {
-...  |
-LL | |
-LL | | fn main() {}
-   | |____________^
+   = note: replace `Self` with a different type
 
-error[E0391]: cycle detected when computing type of `<impl at $DIR/resolve-self-in-impl.rs:16:1: 16:10>`
+error: `Self` is not valid in the self type of an impl block
   --> $DIR/resolve-self-in-impl.rs:16:6
    |
 LL | impl Self {}
    |      ^^^^
    |
-   = note: ...which immediately requires computing type of `<impl at $DIR/resolve-self-in-impl.rs:16:1: 16:10>` again
-note: cycle used when collecting item types in top-level module
-  --> $DIR/resolve-self-in-impl.rs:1:1
-   |
-LL | / #![feature(associated_type_defaults)]
-LL | |
-LL | | struct S<T = u8>(T);
-LL | | trait Tr<T = u8> {
-...  |
-LL | |
-LL | | fn main() {}
-   | |____________^
+   = note: replace `Self` with a different type
 
-error[E0391]: cycle detected when computing type of `<impl at $DIR/resolve-self-in-impl.rs:17:1: 17:13>`
+error: `Self` is not valid in the self type of an impl block
   --> $DIR/resolve-self-in-impl.rs:17:8
    |
 LL | impl S<Self> {}
    |        ^^^^
    |
-   = note: ...which immediately requires computing type of `<impl at $DIR/resolve-self-in-impl.rs:17:1: 17:13>` again
-note: cycle used when collecting item types in top-level module
-  --> $DIR/resolve-self-in-impl.rs:1:1
+   = note: replace `Self` with a different type
+
+error: `Self` is not valid in the self type of an impl block
+  --> $DIR/resolve-self-in-impl.rs:18:7
    |
-LL | / #![feature(associated_type_defaults)]
-LL | |
-LL | | struct S<T = u8>(T);
-LL | | trait Tr<T = u8> {
-...  |
-LL | |
-LL | | fn main() {}
-   | |____________^
+LL | impl (Self, Self) {}
+   |       ^^^^  ^^^^
+   |
+   = note: replace `Self` with a different type
 
-error[E0391]: cycle detected when computing trait implemented by `<impl at $DIR/resolve-self-in-impl.rs:18:1: 18:23>`
-  --> $DIR/resolve-self-in-impl.rs:18:1
+error[E0391]: cycle detected when computing trait implemented by `<impl at $DIR/resolve-self-in-impl.rs:19:1: 19:23>`
+  --> $DIR/resolve-self-in-impl.rs:19:1
    |
 LL | impl Tr<Self::A> for S {}
    | ^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: ...which immediately requires computing trait implemented by `<impl at $DIR/resolve-self-in-impl.rs:18:1: 18:23>` again
+   = note: ...which immediately requires computing trait implemented by `<impl at $DIR/resolve-self-in-impl.rs:19:1: 19:23>` again
 note: cycle used when collecting item types in top-level module
   --> $DIR/resolve-self-in-impl.rs:1:1
    |
@@ -93,6 +57,6 @@ LL | |
 LL | | fn main() {}
    | |____________^
 
-error: aborting due to 5 previous errors
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/issue-103677.rs b/src/test/ui/rfc-2632-const-trait-impl/issue-103677.rs
new file mode 100644
index 00000000000..d81724a3685
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/issue-103677.rs
@@ -0,0 +1,5 @@
+// check-pass
+
+const _: fn(&String) = |s| { &*s as &str; };
+
+fn main() {}
diff --git a/src/test/ui/save-analysis/issue-68621.stderr b/src/test/ui/save-analysis/issue-68621.stderr
index 4a4bf9a6996..4452ee7915b 100644
--- a/src/test/ui/save-analysis/issue-68621.stderr
+++ b/src/test/ui/save-analysis/issue-68621.stderr
@@ -4,7 +4,7 @@ error: unconstrained opaque type
 LL |     type Future = impl Trait;
    |                   ^^^^^^^^^^
    |
-   = note: `Future` must be used in combination with a concrete type within the same module
+   = note: `Future` must be used in combination with a concrete type within the same impl
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/issue-35987.stderr b/src/test/ui/span/issue-35987.stderr
index d8fddc8007f..057d40ac0cb 100644
--- a/src/test/ui/span/issue-35987.stderr
+++ b/src/test/ui/span/issue-35987.stderr
@@ -1,6 +1,9 @@
 error[E0404]: expected trait, found type parameter `Add`
   --> $DIR/issue-35987.rs:5:21
    |
+LL | use std::ops::Add;
+   |               --- you might have meant to refer to this trait
+LL |
 LL | impl<T: Clone, Add> Add for Foo<T> {
    |                ---  ^^^ not a trait
    |                |
diff --git a/src/test/ui/suggestions/issue-102354.rs b/src/test/ui/suggestions/issue-102354.rs
new file mode 100644
index 00000000000..f881feb0060
--- /dev/null
+++ b/src/test/ui/suggestions/issue-102354.rs
@@ -0,0 +1,10 @@
+trait Trait {
+    fn func() {}
+}
+
+impl Trait for i32 {}
+
+fn main() {
+    let x: i32 = 123;
+    x.func(); //~ERROR no method
+}
diff --git a/src/test/ui/suggestions/issue-102354.stderr b/src/test/ui/suggestions/issue-102354.stderr
new file mode 100644
index 00000000000..4f76c5f2e75
--- /dev/null
+++ b/src/test/ui/suggestions/issue-102354.stderr
@@ -0,0 +1,24 @@
+error[E0599]: no method named `func` found for type `i32` in the current scope
+  --> $DIR/issue-102354.rs:9:7
+   |
+LL |     x.func();
+   |       ^^^^ this is an associated function, not a method
+   |
+   = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in the trait `Trait`
+  --> $DIR/issue-102354.rs:2:5
+   |
+LL |     fn func() {}
+   |     ^^^^^^^^^
+help: use associated function syntax instead
+   |
+LL |     i32::func();
+   |     ~~~~~~~~~
+help: disambiguate the associated function for the candidate
+   |
+LL |     <i32 as Trait>::func(x);
+   |     ~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/traits/safety-trait-impl-cc.stderr b/src/test/ui/traits/safety-trait-impl-cc.stderr
index 5a0f8d3b8ca..0b1fb30478f 100644
--- a/src/test/ui/traits/safety-trait-impl-cc.stderr
+++ b/src/test/ui/traits/safety-trait-impl-cc.stderr
@@ -7,6 +7,12 @@ LL | |         panic!();
 LL | |     }
 LL | | }
    | |_^
+   |
+   = note: the trait `Foo` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword
+help: add `unsafe` to this trait implementation
+   |
+LL | unsafe impl lib::Foo for Bar {
+   | ++++++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/safety-trait-impl.stderr b/src/test/ui/traits/safety-trait-impl.stderr
index fc0f6c69308..721e2b48b95 100644
--- a/src/test/ui/traits/safety-trait-impl.stderr
+++ b/src/test/ui/traits/safety-trait-impl.stderr
@@ -3,12 +3,24 @@ error[E0200]: the trait `UnsafeTrait` requires an `unsafe impl` declaration
    |
 LL | impl UnsafeTrait for u16 { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the trait `UnsafeTrait` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword
+help: add `unsafe` to this trait implementation
+   |
+LL | unsafe impl UnsafeTrait for u16 { }
+   | ++++++
 
 error[E0199]: implementing the trait `SafeTrait` is not unsafe
   --> $DIR/safety-trait-impl.rs:16:1
    |
 LL | unsafe impl SafeTrait for u32 { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove `unsafe` from this trait implementation
+   |
+LL - unsafe impl SafeTrait for u32 { }
+LL + impl SafeTrait for u32 { }
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/type-alias-impl-trait/issue-101750.rs b/src/test/ui/type-alias-impl-trait/issue-101750.rs
new file mode 100644
index 00000000000..f564f4fa702
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-101750.rs
@@ -0,0 +1,37 @@
+#![feature(type_alias_impl_trait)]
+
+// check-pass
+
+trait Trait {}
+
+type TAIT = impl Trait;
+
+struct Concrete;
+impl Trait for Concrete {}
+
+fn tait() -> TAIT {
+    Concrete
+}
+
+trait OuterTrait {
+    type Item;
+}
+struct Dummy<T> {
+    t: T,
+}
+impl<T> OuterTrait for Dummy<T> {
+    type Item = T;
+}
+
+fn tait_and_impl_trait() -> impl OuterTrait<Item = (TAIT, impl Trait)> {
+    Dummy {
+        t: (tait(), Concrete),
+    }
+}
+
+fn tait_and_dyn_trait() -> impl OuterTrait<Item = (TAIT, Box<dyn Trait>)> {
+    let b: Box<dyn Trait> = Box::new(Concrete);
+    Dummy { t: (tait(), b) }
+}
+
+fn main() {}
diff --git a/src/test/ui/type/issue-94187-verbose-type-name.rs b/src/test/ui/type/issue-94187-verbose-type-name.rs
index 902ef5ade2b..64f0c09e89b 100644
--- a/src/test/ui/type/issue-94187-verbose-type-name.rs
+++ b/src/test/ui/type/issue-94187-verbose-type-name.rs
@@ -1,13 +1,19 @@
-// Check to insure that the output of `std::any::type_name` does not change based on -Zverbose
-// when printing constants
+// Check to insure that the output of `std::any::type_name` does not change based on `-Zverbose`
 // run-pass
 // edition: 2018
 // revisions: normal verbose
 // [verbose]compile-flags:-Zverbose
 
-struct Wrapper<const VALUE: usize>;
+use std::any::type_name;
 
 fn main() {
-    assert_eq!(std::any::type_name::<[u32; 0]>(), "[u32; 0]");
-    assert_eq!(std::any::type_name::<Wrapper<0>>(), "issue_94187_verbose_type_name::Wrapper<0>");
+    assert_eq!(type_name::<[u32; 0]>(), "[u32; 0]");
+
+    struct Wrapper<const VALUE: usize>;
+    assert_eq!(type_name::<Wrapper<0>>(), "issue_94187_verbose_type_name::main::Wrapper<0>");
+
+    assert_eq!(
+        type_name::<dyn Fn(u32) -> u32>(),
+        "dyn core::ops::function::Fn<(u32,)>+Output = u32"
+    );
 }
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 9210810d1fd7b51ae0439a0a363cc50e3696345
+Subproject 7e484fc1a766f56dbc95380f45719698e0c8274
diff --git a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
index c2b9253ec35..b9509ca656f 100644
--- a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
@@ -26,7 +26,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: Option<RustcVer
             (Mutability::Not, Mutability::Not) | (Mutability::Mut, Mutability::Mut));
         // The `U` in `pointer::cast` have to be `Sized`
         // as explained here: https://github.com/rust-lang/rust/issues/60602.
-        if to_pointee_ty.is_sized(cx.tcx.at(expr.span), cx.param_env);
+        if to_pointee_ty.is_sized(cx.tcx, cx.param_env);
         then {
             let mut applicability = Applicability::MachineApplicable;
             let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, "_", &mut applicability);
diff --git a/src/tools/clippy/clippy_lints/src/copy_iterator.rs b/src/tools/clippy/clippy_lints/src/copy_iterator.rs
index 026683f6006..e38f7726853 100644
--- a/src/tools/clippy/clippy_lints/src/copy_iterator.rs
+++ b/src/tools/clippy/clippy_lints/src/copy_iterator.rs
@@ -43,7 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for CopyIterator {
                 of_trait: Some(ref trait_ref),
                 ..
             }) = item.kind;
-            let ty = cx.tcx.type_of(item.def_id);
+            let ty = cx.tcx.type_of(item.owner_id);
             if is_copy(cx, ty);
             if let Some(trait_id) = trait_ref.trait_def_id();
             if cx.tcx.is_diagnostic_item(sym::Iterator, trait_id);
diff --git a/src/tools/clippy/clippy_lints/src/default_union_representation.rs b/src/tools/clippy/clippy_lints/src/default_union_representation.rs
index 741edc13196..dec357ab75c 100644
--- a/src/tools/clippy/clippy_lints/src/default_union_representation.rs
+++ b/src/tools/clippy/clippy_lints/src/default_union_representation.rs
@@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultUnionRepresentation {
                 None,
                 &format!(
                     "consider annotating `{}` with `#[repr(C)]` to explicitly specify memory layout",
-                    cx.tcx.def_path_str(item.def_id.to_def_id())
+                    cx.tcx.def_path_str(item.owner_id.to_def_id())
                 ),
             );
         }
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index a95d9f5390d..a37ee82d4c8 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -29,7 +29,7 @@ use rustc_middle::ty::{
 };
 use rustc_semver::RustcVersion;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
-use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP};
+use rustc_span::{symbol::sym, Span, Symbol};
 use rustc_trait_selection::infer::InferCtxtExt as _;
 use rustc_trait_selection::traits::{query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause};
 use std::collections::VecDeque;
@@ -715,47 +715,47 @@ fn walk_parents<'tcx>(
             },
             Node::Item(&Item {
                 kind: ItemKind::Static(..) | ItemKind::Const(..),
-                def_id,
+                owner_id,
                 span,
                 ..
             })
             | Node::TraitItem(&TraitItem {
                 kind: TraitItemKind::Const(..),
-                def_id,
+                owner_id,
                 span,
                 ..
             })
             | Node::ImplItem(&ImplItem {
                 kind: ImplItemKind::Const(..),
-                def_id,
+                owner_id,
                 span,
                 ..
             }) if span.ctxt() == ctxt => {
-                let ty = cx.tcx.type_of(def_id.def_id);
+                let ty = cx.tcx.type_of(owner_id.def_id);
                 Some(ty_auto_deref_stability(cx, ty, precedence).position_for_result(cx))
             },
 
             Node::Item(&Item {
                 kind: ItemKind::Fn(..),
-                def_id,
+                owner_id,
                 span,
                 ..
             })
             | Node::TraitItem(&TraitItem {
                 kind: TraitItemKind::Fn(..),
-                def_id,
+                owner_id,
                 span,
                 ..
             })
             | Node::ImplItem(&ImplItem {
                 kind: ImplItemKind::Fn(..),
-                def_id,
+                owner_id,
                 span,
                 ..
             }) if span.ctxt() == ctxt => {
                 let output = cx
                     .tcx
-                    .erase_late_bound_regions(cx.tcx.fn_sig(def_id.to_def_id()).output());
+                    .erase_late_bound_regions(cx.tcx.fn_sig(owner_id.to_def_id()).output());
                 Some(ty_auto_deref_stability(cx, output, precedence).position_for_result(cx))
             },
 
@@ -990,7 +990,7 @@ fn binding_ty_auto_deref_stability<'tcx>(
                                 cx.typeck_results().node_type(ty.ty.hir_id),
                                 binder_args,
                             ))
-                            .is_sized(cx.tcx.at(DUMMY_SP), cx.param_env.without_caller_bounds()),
+                            .is_sized(cx.tcx, cx.param_env.without_caller_bounds()),
                     )
                 }
             },
@@ -1005,7 +1005,7 @@ fn binding_ty_auto_deref_stability<'tcx>(
                         cx.typeck_results().node_type(ty.ty.hir_id),
                         binder_args,
                     ))
-                    .is_sized(cx.tcx.at(DUMMY_SP), cx.param_env.without_caller_bounds()),
+                    .is_sized(cx.tcx, cx.param_env.without_caller_bounds()),
             ),
             TyKind::OpaqueDef(..) | TyKind::Infer | TyKind::Typeof(..) | TyKind::TraitObject(..) | TyKind::Err => {
                 Position::ReborrowStable(precedence)
@@ -1297,7 +1297,7 @@ impl<'tcx> TyPosition<'tcx> {
     fn position_for_result(self, cx: &LateContext<'tcx>) -> Position {
         match (self.position, self.ty) {
             (Position::ReborrowStable(precedence), Some(ty)) => {
-                Position::DerefStable(precedence, ty.is_sized(cx.tcx.at(DUMMY_SP), cx.param_env))
+                Position::DerefStable(precedence, ty.is_sized(cx.tcx, cx.param_env))
             },
             (position, _) => position,
         }
@@ -1348,7 +1348,7 @@ fn ty_auto_deref_stability<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, precedenc
             | ty::Tuple(_)
             | ty::Projection(_) => Position::DerefStable(
                 precedence,
-                ty.is_sized(cx.tcx.at(DUMMY_SP), cx.param_env.without_caller_bounds()),
+                ty.is_sized(cx.tcx, cx.param_env.without_caller_bounds()),
             )
             .into(),
         };
diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
index 06ae5abeaeb..ae8f6b79449 100644
--- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
@@ -70,7 +70,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
                 self_ty,
                 ..
             }) = item.kind;
-            if !cx.tcx.has_attr(item.def_id.to_def_id(), sym::automatically_derived);
+            if !cx.tcx.has_attr(item.owner_id.to_def_id(), sym::automatically_derived);
             if !item.span.from_expansion();
             if let Some(def_id) = trait_ref.trait_def_id();
             if cx.tcx.is_diagnostic_item(sym::Default, def_id);
@@ -78,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
             if let Some(Node::ImplItem(impl_item)) = cx.tcx.hir().find(impl_item_hir);
             if let ImplItemKind::Fn(_, b) = &impl_item.kind;
             if let Body { value: func_expr, .. } = cx.tcx.hir().body(*b);
-            if let Some(adt_def) = cx.tcx.type_of(item.def_id).ty_adt_def();
+            if let Some(adt_def) = cx.tcx.type_of(item.owner_id).ty_adt_def();
             if let attrs = cx.tcx.hir().attrs(item.hir_id());
             if !attrs.iter().any(|attr| attr.doc_str().is_some());
             if let child_attrs = cx.tcx.hir().attrs(impl_item_hir);
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index fad984d05ca..102a02138bc 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -210,8 +210,8 @@ impl<'tcx> LateLintPass<'tcx> for Derive {
             ..
         }) = item.kind
         {
-            let ty = cx.tcx.type_of(item.def_id);
-            let is_automatically_derived = cx.tcx.has_attr(item.def_id.to_def_id(), sym::automatically_derived);
+            let ty = cx.tcx.type_of(item.owner_id);
+            let is_automatically_derived = cx.tcx.has_attr(item.owner_id.to_def_id(), sym::automatically_derived);
 
             check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived);
             check_ord_partial_ord(cx, item.span, trait_ref, ty, is_automatically_derived);
diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs
index 36dc7e3396b..24d6a6951af 100644
--- a/src/tools/clippy/clippy_lints/src/doc.rs
+++ b/src/tools/clippy/clippy_lints/src/doc.rs
@@ -257,17 +257,17 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
         let headers = check_attrs(cx, &self.valid_idents, attrs);
         match item.kind {
             hir::ItemKind::Fn(ref sig, _, body_id) => {
-                if !(is_entrypoint_fn(cx, item.def_id.to_def_id()) || in_external_macro(cx.tcx.sess, item.span)) {
+                if !(is_entrypoint_fn(cx, item.owner_id.to_def_id()) || in_external_macro(cx.tcx.sess, item.span)) {
                     let body = cx.tcx.hir().body(body_id);
                     let mut fpu = FindPanicUnwrap {
                         cx,
-                        typeck_results: cx.tcx.typeck(item.def_id.def_id),
+                        typeck_results: cx.tcx.typeck(item.owner_id.def_id),
                         panic_span: None,
                     };
                     fpu.visit_expr(body.value);
                     lint_for_missing_headers(
                         cx,
-                        item.def_id.def_id,
+                        item.owner_id.def_id,
                         item.span,
                         sig,
                         headers,
@@ -304,7 +304,7 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
         let headers = check_attrs(cx, &self.valid_idents, attrs);
         if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind {
             if !in_external_macro(cx.tcx.sess, item.span) {
-                lint_for_missing_headers(cx, item.def_id.def_id, item.span, sig, headers, None, None);
+                lint_for_missing_headers(cx, item.owner_id.def_id, item.span, sig, headers, None, None);
             }
         }
     }
@@ -319,13 +319,13 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
             let body = cx.tcx.hir().body(body_id);
             let mut fpu = FindPanicUnwrap {
                 cx,
-                typeck_results: cx.tcx.typeck(item.def_id.def_id),
+                typeck_results: cx.tcx.typeck(item.owner_id.def_id),
                 panic_span: None,
             };
             fpu.visit_expr(body.value);
             lint_for_missing_headers(
                 cx,
-                item.def_id.def_id,
+                item.owner_id.def_id,
                 item.span,
                 sig,
                 headers,
@@ -345,7 +345,7 @@ fn lint_for_missing_headers<'tcx>(
     body_id: Option<hir::BodyId>,
     panic_span: Option<Span>,
 ) {
-    if !cx.access_levels.is_exported(def_id) {
+    if !cx.effective_visibilities.is_exported(def_id) {
         return; // Private functions do not require doc comments
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/empty_enum.rs b/src/tools/clippy/clippy_lints/src/empty_enum.rs
index bbebc024414..0570c2a1013 100644
--- a/src/tools/clippy/clippy_lints/src/empty_enum.rs
+++ b/src/tools/clippy/clippy_lints/src/empty_enum.rs
@@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for EmptyEnum {
         }
 
         if let ItemKind::Enum(..) = item.kind {
-            let ty = cx.tcx.type_of(item.def_id);
+            let ty = cx.tcx.type_of(item.owner_id);
             let adt = ty.ty_adt_def().expect("already checked whether this is an enum");
             if adt.variants().is_empty() {
                 span_lint_and_help(
diff --git a/src/tools/clippy/clippy_lints/src/enum_variants.rs b/src/tools/clippy/clippy_lints/src/enum_variants.rs
index b019d07d53d..223545fa798 100644
--- a/src/tools/clippy/clippy_lints/src/enum_variants.rs
+++ b/src/tools/clippy/clippy_lints/src/enum_variants.rs
@@ -265,7 +265,7 @@ impl LateLintPass<'_> for EnumVariantNames {
                     }
                     // The `module_name_repetitions` lint should only trigger if the item has the module in its
                     // name. Having the same name is accepted.
-                    if cx.tcx.visibility(item.def_id).is_public() && item_camel.len() > mod_camel.len() {
+                    if cx.tcx.visibility(item.owner_id).is_public() && item_camel.len() > mod_camel.len() {
                         let matching = count_match_start(mod_camel, &item_camel);
                         let rmatching = count_match_end(mod_camel, &item_camel);
                         let nchars = mod_camel.chars().count();
@@ -296,7 +296,7 @@ impl LateLintPass<'_> for EnumVariantNames {
             }
         }
         if let ItemKind::Enum(ref def, _) = item.kind {
-            if !(self.avoid_breaking_exported_api && cx.access_levels.is_exported(item.def_id.def_id)) {
+            if !(self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(item.owner_id.def_id)) {
                 check_variant(cx, self.threshold, def, item_name, item.span);
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs
index c9a8307eba4..7f1a4c4beb1 100644
--- a/src/tools/clippy/clippy_lints/src/escape.rs
+++ b/src/tools/clippy/clippy_lints/src/escape.rs
@@ -88,7 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
                         // be sure we have `self` parameter in this function
                         if trait_item.kind == (AssocItemKind::Fn { has_self: true }) {
                             trait_self_ty = Some(
-                                TraitRef::identity(cx.tcx, trait_item.id.def_id.to_def_id())
+                                TraitRef::identity(cx.tcx, trait_item.id.owner_id.to_def_id())
                                     .self_ty()
                                     .skip_binder(),
                             );
diff --git a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs
index be6242bd20b..1fece5d1c48 100644
--- a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs
+++ b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs
@@ -73,7 +73,7 @@ impl LateLintPass<'_> for ExhaustiveItems {
     fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
         if_chain! {
             if let ItemKind::Enum(..) | ItemKind::Struct(..) = item.kind;
-            if cx.access_levels.is_exported(item.def_id.def_id);
+            if cx.effective_visibilities.is_exported(item.owner_id.def_id);
             let attrs = cx.tcx.hir().attrs(item.hir_id());
             if !attrs.iter().any(|a| a.has_name(sym::non_exhaustive));
             then {
diff --git a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
index ef24a5d06ad..0a633f242a5 100644
--- a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
+++ b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
@@ -55,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for FallibleImplFrom {
         // check for `impl From<???> for ..`
         if_chain! {
             if let hir::ItemKind::Impl(impl_) = &item.kind;
-            if let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(item.def_id);
+            if let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id);
             if cx.tcx.is_diagnostic_item(sym::From, impl_trait_ref.def_id);
             then {
                 lint_impl_body(cx, item.span, impl_.items);
@@ -107,7 +107,7 @@ fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_items: &[h
                 let body = cx.tcx.hir().body(body_id);
                 let mut fpu = FindPanicUnwrap {
                     lcx: cx,
-                    typeck_results: cx.tcx.typeck(impl_item.id.def_id.def_id),
+                    typeck_results: cx.tcx.typeck(impl_item.id.owner_id.def_id),
                     result: Vec::new(),
                 };
                 fpu.visit_expr(body.value);
diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs
index 32073536b45..f0fe845d330 100644
--- a/src/tools/clippy/clippy_lints/src/format_args.rs
+++ b/src/tools/clippy/clippy_lints/src/format_args.rs
@@ -115,7 +115,7 @@ declare_clippy_lint! {
     /// nothing will be suggested, e.g. `println!("{0}={1}", var, 1+2)`.
     #[clippy::version = "1.65.0"]
     pub UNINLINED_FORMAT_ARGS,
-    style,
+    pedantic,
     "using non-inlined variables in `format!` calls"
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/from_over_into.rs b/src/tools/clippy/clippy_lints/src/from_over_into.rs
index 95eda4ea882..8b24a4962fb 100644
--- a/src/tools/clippy/clippy_lints/src/from_over_into.rs
+++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs
@@ -76,7 +76,7 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto {
             && let Some(into_trait_seg) = hir_trait_ref.path.segments.last()
             // `impl Into<target_ty> for self_ty`
             && let Some(GenericArgs { args: [GenericArg::Type(target_ty)], .. }) = into_trait_seg.args
-            && let Some(middle_trait_ref) = cx.tcx.impl_trait_ref(item.def_id)
+            && let Some(middle_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id)
             && cx.tcx.is_diagnostic_item(sym::Into, middle_trait_ref.def_id)
         {
             span_lint_and_then(
diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
index 3064b6c9d22..bff69f91518 100644
--- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
@@ -22,9 +22,9 @@ use super::{DOUBLE_MUST_USE, MUST_USE_CANDIDATE, MUST_USE_UNIT};
 
 pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
     let attrs = cx.tcx.hir().attrs(item.hir_id());
-    let attr = cx.tcx.get_attr(item.def_id.to_def_id(), sym::must_use);
+    let attr = cx.tcx.get_attr(item.owner_id.to_def_id(), sym::must_use);
     if let hir::ItemKind::Fn(ref sig, _generics, ref body_id) = item.kind {
-        let is_public = cx.access_levels.is_exported(item.def_id.def_id);
+        let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);
         let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
         if let Some(attr) = attr {
             check_needless_must_use(cx, sig.decl, item.hir_id(), item.span, fn_header_span, attr);
@@ -34,7 +34,7 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>
                 sig.decl,
                 cx.tcx.hir().body(*body_id),
                 item.span,
-                item.def_id.def_id,
+                item.owner_id.def_id,
                 item.span.with_hi(sig.decl.output.span().hi()),
                 "this function could have a `#[must_use]` attribute",
             );
@@ -44,20 +44,20 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>
 
 pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {
     if let hir::ImplItemKind::Fn(ref sig, ref body_id) = item.kind {
-        let is_public = cx.access_levels.is_exported(item.def_id.def_id);
+        let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);
         let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
         let attrs = cx.tcx.hir().attrs(item.hir_id());
-        let attr = cx.tcx.get_attr(item.def_id.to_def_id(), sym::must_use);
+        let attr = cx.tcx.get_attr(item.owner_id.to_def_id(), sym::must_use);
         if let Some(attr) = attr {
             check_needless_must_use(cx, sig.decl, item.hir_id(), item.span, fn_header_span, attr);
-        } else if is_public && !is_proc_macro(cx.sess(), attrs) && trait_ref_of_method(cx, item.def_id.def_id).is_none()
+        } else if is_public && !is_proc_macro(cx.sess(), attrs) && trait_ref_of_method(cx, item.owner_id.def_id).is_none()
         {
             check_must_use_candidate(
                 cx,
                 sig.decl,
                 cx.tcx.hir().body(*body_id),
                 item.span,
-                item.def_id.def_id,
+                item.owner_id.def_id,
                 item.span.with_hi(sig.decl.output.span().hi()),
                 "this method could have a `#[must_use]` attribute",
             );
@@ -67,11 +67,11 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp
 
 pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
     if let hir::TraitItemKind::Fn(ref sig, ref eid) = item.kind {
-        let is_public = cx.access_levels.is_exported(item.def_id.def_id);
+        let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);
         let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
 
         let attrs = cx.tcx.hir().attrs(item.hir_id());
-        let attr = cx.tcx.get_attr(item.def_id.to_def_id(), sym::must_use);
+        let attr = cx.tcx.get_attr(item.owner_id.to_def_id(), sym::must_use);
         if let Some(attr) = attr {
             check_needless_must_use(cx, sig.decl, item.hir_id(), item.span, fn_header_span, attr);
         } else if let hir::TraitFn::Provided(eid) = *eid {
@@ -82,7 +82,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr
                     sig.decl,
                     body,
                     item.span,
-                    item.def_id.def_id,
+                    item.owner_id.def_id,
                     item.span.with_hi(sig.decl.output.span().hi()),
                     "this method could have a `#[must_use]` attribute",
                 );
@@ -137,7 +137,7 @@ fn check_must_use_candidate<'tcx>(
         || mutates_static(cx, body)
         || in_external_macro(cx.sess(), item_span)
         || returns_unit(decl)
-        || !cx.access_levels.is_exported(item_id)
+        || !cx.effective_visibilities.is_exported(item_id)
         || is_must_use_ty(cx, return_ty(cx, cx.tcx.hir().local_def_id_to_hir_id(item_id)))
     {
         return;
@@ -188,7 +188,7 @@ fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Span, tys: &m
         // primitive types are never mutable
         ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => false,
         ty::Adt(adt, substs) => {
-            tys.insert(adt.did()) && !ty.is_freeze(cx.tcx.at(span), cx.param_env)
+            tys.insert(adt.did()) && !ty.is_freeze(cx.tcx, cx.param_env)
                 || KNOWN_WRAPPER_TYS
                     .iter()
                     .any(|&sym| cx.tcx.is_diagnostic_item(sym, adt.did()))
diff --git a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
index b7595d101e0..2c0bf551fd7 100644
--- a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
@@ -31,7 +31,7 @@ pub(super) fn check_fn<'tcx>(
 pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
     if let hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(eid)) = item.kind {
         let body = cx.tcx.hir().body(eid);
-        check_raw_ptr(cx, sig.header.unsafety, sig.decl, body, item.def_id.def_id);
+        check_raw_ptr(cx, sig.header.unsafety, sig.decl, body, item.owner_id.def_id);
     }
 }
 
@@ -42,7 +42,7 @@ fn check_raw_ptr<'tcx>(
     body: &'tcx hir::Body<'tcx>,
     def_id: LocalDefId,
 ) {
-    if unsafety == hir::Unsafety::Normal && cx.access_levels.is_exported(def_id) {
+    if unsafety == hir::Unsafety::Normal && cx.effective_visibilities.is_exported(def_id) {
         let raw_ptrs = iter_input_pats(decl, body)
             .filter_map(|arg| raw_ptr_arg(cx, arg))
             .collect::<HirIdSet>();
diff --git a/src/tools/clippy/clippy_lints/src/functions/result.rs b/src/tools/clippy/clippy_lints/src/functions/result.rs
index 113c4e9f509..5c63fb2acb1 100644
--- a/src/tools/clippy/clippy_lints/src/functions/result.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/result.rs
@@ -34,9 +34,9 @@ fn result_err_ty<'tcx>(
 
 pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::Item<'tcx>, large_err_threshold: u64) {
     if let hir::ItemKind::Fn(ref sig, _generics, _) = item.kind
-        && let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.def_id.def_id, item.span)
+        && let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.owner_id.def_id, item.span)
     {
-        if cx.access_levels.is_exported(item.def_id.def_id) {
+        if cx.effective_visibilities.is_exported(item.owner_id.def_id) {
             let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
             check_result_unit_err(cx, err_ty, fn_header_span);
         }
@@ -47,10 +47,10 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::Item<'tcx>, l
 pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::ImplItem<'tcx>, large_err_threshold: u64) {
     // Don't lint if method is a trait's implementation, we can't do anything about those
     if let hir::ImplItemKind::Fn(ref sig, _) = item.kind
-        && let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.def_id.def_id, item.span)
-        && trait_ref_of_method(cx, item.def_id.def_id).is_none()
+        && let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.owner_id.def_id, item.span)
+        && trait_ref_of_method(cx, item.owner_id.def_id).is_none()
     {
-        if cx.access_levels.is_exported(item.def_id.def_id) {
+        if cx.effective_visibilities.is_exported(item.owner_id.def_id) {
             let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
             check_result_unit_err(cx, err_ty, fn_header_span);
         }
@@ -61,8 +61,8 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::ImplItem
 pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::TraitItem<'tcx>, large_err_threshold: u64) {
     if let hir::TraitItemKind::Fn(ref sig, _) = item.kind {
         let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
-        if let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.def_id.def_id, item.span) {
-            if cx.access_levels.is_exported(item.def_id.def_id) {
+        if let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.owner_id.def_id, item.span) {
+            if cx.effective_visibilities.is_exported(item.owner_id.def_id) {
                 check_result_unit_err(cx, err_ty, fn_header_span);
             }
             check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold);
diff --git a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
index 93efe957b1d..94e06cf704b 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
@@ -111,7 +111,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
             }
         }
 
-        if !cx.access_levels.is_exported(item.def_id.def_id) {
+        if !cx.effective_visibilities.is_exported(item.owner_id.def_id) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
index 676136df572..14a37f535b4 100644
--- a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
+++ b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
@@ -108,7 +108,7 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString {
             if is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id()), sym::String);
 
             // Filters instances of to_string which are required by a trait
-            if trait_ref_of_method(cx, impl_item.def_id.def_id).is_none();
+            if trait_ref_of_method(cx, impl_item.owner_id.def_id).is_none();
 
             then {
                 show_lint(cx, impl_item);
@@ -124,7 +124,7 @@ fn show_lint(cx: &LateContext<'_>, item: &ImplItem<'_>) {
         .expect("Failed to get trait ID of `Display`!");
 
     // Get the real type of 'self'
-    let self_type = cx.tcx.fn_sig(item.def_id).input(0);
+    let self_type = cx.tcx.fn_sig(item.owner_id).input(0);
     let self_type = self_type.skip_binder().peel_refs();
 
     // Emit either a warning or an error
diff --git a/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs b/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs
index ea9f046fb97..e76de77f195 100644
--- a/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs
+++ b/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs
@@ -44,7 +44,7 @@ impl<'tcx> LateLintPass<'tcx> for IterNotReturningIterator {
         let name = item.ident.name.as_str();
         if matches!(name, "iter" | "iter_mut") {
             if let TraitItemKind::Fn(fn_sig, _) = &item.kind {
-                check_sig(cx, name, fn_sig, item.def_id.def_id);
+                check_sig(cx, name, fn_sig, item.owner_id.def_id);
             }
         }
     }
@@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for IterNotReturningIterator {
             )
         {
             if let ImplItemKind::Fn(fn_sig, _) = &item.kind {
-                check_sig(cx, name, fn_sig, item.def_id.def_id);
+                check_sig(cx, name, fn_sig, item.owner_id.def_id);
             }
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
index 8ed7e4bb196..06e95728549 100644
--- a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
+++ b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
@@ -123,7 +123,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
             return;
         }
         if let ItemKind::Enum(ref def, _) = item.kind {
-            let ty = cx.tcx.type_of(item.def_id);
+            let ty = cx.tcx.type_of(item.owner_id);
             let Adt(adt, subst) = ty.kind() else {
                 panic!("already checked whether this is an enum")
             };
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index 3a563736fb0..b0cba40c27a 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -134,7 +134,7 @@ impl<'tcx> LateLintPass<'tcx> for LenZero {
             if item.ident.name == sym::len;
             if let ImplItemKind::Fn(sig, _) = &item.kind;
             if sig.decl.implicit_self.has_implicit_self();
-            if cx.access_levels.is_exported(item.def_id.def_id);
+            if cx.effective_visibilities.is_exported(item.owner_id.def_id);
             if matches!(sig.decl.output, FnRetTy::Return(_));
             if let Some(imp) = get_parent_as_impl(cx.tcx, item.hir_id());
             if imp.of_trait.is_none();
@@ -143,7 +143,7 @@ impl<'tcx> LateLintPass<'tcx> for LenZero {
             if let Some(local_id) = ty_id.as_local();
             let ty_hir_id = cx.tcx.hir().local_def_id_to_hir_id(local_id);
             if !is_lint_allowed(cx, LEN_WITHOUT_IS_EMPTY, ty_hir_id);
-            if let Some(output) = parse_len_output(cx, cx.tcx.fn_sig(item.def_id).skip_binder());
+            if let Some(output) = parse_len_output(cx, cx.tcx.fn_sig(item.owner_id).skip_binder());
             then {
                 let (name, kind) = match cx.tcx.hir().find(ty_hir_id) {
                     Some(Node::ForeignItem(x)) => (x.ident.name, "extern type"),
@@ -195,7 +195,7 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items
     fn is_named_self(cx: &LateContext<'_>, item: &TraitItemRef, name: Symbol) -> bool {
         item.ident.name == name
             && if let AssocItemKind::Fn { has_self } = item.kind {
-                has_self && { cx.tcx.fn_sig(item.id.def_id).inputs().skip_binder().len() == 1 }
+                has_self && { cx.tcx.fn_sig(item.id.owner_id).inputs().skip_binder().len() == 1 }
             } else {
                 false
             }
@@ -210,11 +210,11 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items
         }
     }
 
-    if cx.access_levels.is_exported(visited_trait.def_id.def_id)
+    if cx.effective_visibilities.is_exported(visited_trait.owner_id.def_id)
         && trait_items.iter().any(|i| is_named_self(cx, i, sym::len))
     {
         let mut current_and_super_traits = DefIdSet::default();
-        fill_trait_set(visited_trait.def_id.to_def_id(), &mut current_and_super_traits, cx);
+        fill_trait_set(visited_trait.owner_id.to_def_id(), &mut current_and_super_traits, cx);
         let is_empty = sym!(is_empty);
 
         let is_empty_method_found = current_and_super_traits
@@ -331,7 +331,7 @@ fn check_for_is_empty<'tcx>(
             None,
             None,
         ),
-        Some(is_empty) if !cx.access_levels.is_exported(is_empty.def_id.expect_local()) => (
+        Some(is_empty) if !cx.effective_visibilities.is_exported(is_empty.def_id.expect_local()) => (
             format!(
                 "{item_kind} `{}` has a public `len` method, but a private `is_empty` method",
                 item_name.as_str(),
diff --git a/src/tools/clippy/clippy_lints/src/let_if_seq.rs b/src/tools/clippy/clippy_lints/src/let_if_seq.rs
index 13071d64441..db41bc67da1 100644
--- a/src/tools/clippy/clippy_lints/src/let_if_seq.rs
+++ b/src/tools/clippy/clippy_lints/src/let_if_seq.rs
@@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for LetIfSeq {
                     let span = stmt.span.to(if_.span);
 
                     let has_interior_mutability = !cx.typeck_results().node_type(canonical_id).is_freeze(
-                        cx.tcx.at(span),
+                        cx.tcx,
                         cx.param_env,
                     );
                     if has_interior_mutability { return; }
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_all.rs b/src/tools/clippy/clippy_lints/src/lib.register_all.rs
index f5ad52ba189..c455e1561b7 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_all.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_all.rs
@@ -72,7 +72,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
     LintId::of(format::USELESS_FORMAT),
     LintId::of(format_args::FORMAT_IN_FORMAT_ARGS),
     LintId::of(format_args::TO_STRING_IN_FORMAT_ARGS),
-    LintId::of(format_args::UNINLINED_FORMAT_ARGS),
     LintId::of(format_args::UNUSED_FORMAT_SPECS),
     LintId::of(format_impl::PRINT_IN_FORMAT_IMPL),
     LintId::of(format_impl::RECURSIVE_FORMAT_IMPL),
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_pedantic.rs b/src/tools/clippy/clippy_lints/src/lib.register_pedantic.rs
index 060d3bdc7c6..44e969585b5 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_pedantic.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_pedantic.rs
@@ -29,6 +29,7 @@ store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
     LintId::of(eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS),
     LintId::of(excessive_bools::FN_PARAMS_EXCESSIVE_BOOLS),
     LintId::of(excessive_bools::STRUCT_EXCESSIVE_BOOLS),
+    LintId::of(format_args::UNINLINED_FORMAT_ARGS),
     LintId::of(functions::MUST_USE_CANDIDATE),
     LintId::of(functions::TOO_MANY_LINES),
     LintId::of(if_not_else::IF_NOT_ELSE),
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_style.rs b/src/tools/clippy/clippy_lints/src/lib.register_style.rs
index 6894d69e928..3312f564855 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_style.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_style.rs
@@ -25,7 +25,6 @@ store.register_group(true, "clippy::style", Some("clippy_style"), vec![
     LintId::of(enum_variants::MODULE_INCEPTION),
     LintId::of(eta_reduction::REDUNDANT_CLOSURE),
     LintId::of(float_literal::EXCESSIVE_PRECISION),
-    LintId::of(format_args::UNINLINED_FORMAT_ARGS),
     LintId::of(from_over_into::FROM_OVER_INTO),
     LintId::of(from_str_radix_10::FROM_STR_RADIX_10),
     LintId::of(functions::DOUBLE_MUST_USE),
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index aef253303a8..54c316358a1 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -6,11 +6,12 @@ use rustc_hir::intravisit::{
     walk_fn_decl, walk_generic_param, walk_generics, walk_impl_item_ref, walk_item, walk_param_bound,
     walk_poly_trait_ref, walk_trait_ref, walk_ty, Visitor,
 };
+use rustc_hir::lang_items;
 use rustc_hir::FnRetTy::Return;
 use rustc_hir::{
     BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, Impl, ImplItem,
-    ImplItemKind, Item, ItemKind, LangItem, Lifetime, LifetimeName, ParamName, PolyTraitRef, PredicateOrigin, TraitFn,
-    TraitItem, TraitItemKind, Ty, TyKind, WherePredicate,
+    ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, ParamName, PolyTraitRef, PredicateOrigin, TraitFn, TraitItem,
+    TraitItemKind, Ty, TyKind, WherePredicate,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter as middle_nested_filter;
@@ -102,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for Lifetimes {
 
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {
         if let ImplItemKind::Fn(ref sig, id) = item.kind {
-            let report_extra_lifetimes = trait_ref_of_method(cx, item.def_id.def_id).is_none();
+            let report_extra_lifetimes = trait_ref_of_method(cx, item.owner_id.def_id).is_none();
             check_fn_inner(
                 cx,
                 sig.decl,
@@ -364,8 +365,6 @@ fn unique_lifetimes(lts: &[RefLt]) -> usize {
     lts.iter().collect::<FxHashSet<_>>().len()
 }
 
-const CLOSURE_TRAIT_BOUNDS: [LangItem; 3] = [LangItem::Fn, LangItem::FnMut, LangItem::FnOnce];
-
 /// A visitor usable for `rustc_front::visit::walk_ty()`.
 struct RefVisitor<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
@@ -424,12 +423,8 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
 
     fn visit_poly_trait_ref(&mut self, poly_tref: &'tcx PolyTraitRef<'tcx>) {
         let trait_ref = &poly_tref.trait_ref;
-        if CLOSURE_TRAIT_BOUNDS.iter().any(|&item| {
-            self.cx
-                .tcx
-                .lang_items()
-                .require(item)
-                .map_or(false, |id| Some(id) == trait_ref.trait_def_id())
+        if let Some(id) = trait_ref.trait_def_id() && lang_items::FN_TRAITS.iter().any(|&item| {
+            self.cx.tcx.lang_items().get(item) == Some(id)
         }) {
             let mut sub_visitor = RefVisitor::new(self.cx);
             sub_visitor.visit_trait_ref(trait_ref);
diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
index 6a42275322b..6806c146696 100644
--- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
@@ -166,7 +166,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustiveEnum {
             if let Some((id, span)) = iter.next()
                 && iter.next().is_none()
             {
-                self.potential_enums.push((item.def_id.def_id, id, item.span, span));
+                self.potential_enums.push((item.owner_id.def_id, id, item.span, span));
             }
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/manual_retain.rs b/src/tools/clippy/clippy_lints/src/manual_retain.rs
index 3181bc86d17..6abbab278fe 100644
--- a/src/tools/clippy/clippy_lints/src/manual_retain.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_retain.rs
@@ -92,7 +92,7 @@ fn check_into_iter(
         && match_def_path(cx, filter_def_id, &paths::CORE_ITER_FILTER)
         && let hir::ExprKind::MethodCall(_, struct_expr, [], _) = &into_iter_expr.kind
         && let Some(into_iter_def_id) = cx.typeck_results().type_dependent_def_id(into_iter_expr.hir_id)
-        && cx.tcx.lang_items().require(hir::LangItem::IntoIterIntoIter).ok() == Some(into_iter_def_id)
+        && Some(into_iter_def_id) == cx.tcx.lang_items().into_iter_fn()
         && match_acceptable_type(cx, left_expr, msrv)
         && SpanlessEq::new(cx).eq_expr(left_expr, struct_expr) {
         suggest(cx, parent_expr, left_expr, target_expr);
diff --git a/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs b/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs
index cc26b0f7fa8..4720a6e6888 100644
--- a/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs
@@ -41,7 +41,7 @@ pub(crate) trait BindInsteadOfMap {
     const GOOD_METHOD_NAME: &'static str;
 
     fn no_op_msg(cx: &LateContext<'_>) -> Option<String> {
-        let variant_id = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM).ok()?;
+        let variant_id = cx.tcx.lang_items().get(Self::VARIANT_LANG_ITEM)?;
         let item_id = cx.tcx.parent(variant_id);
         Some(format!(
             "using `{}.{}({})`, which is a no-op",
@@ -52,7 +52,7 @@ pub(crate) trait BindInsteadOfMap {
     }
 
     fn lint_msg(cx: &LateContext<'_>) -> Option<String> {
-        let variant_id = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM).ok()?;
+        let variant_id = cx.tcx.lang_items().get(Self::VARIANT_LANG_ITEM)?;
         let item_id = cx.tcx.parent(variant_id);
         Some(format!(
             "using `{}.{}(|x| {}(y))`, which is more succinctly expressed as `{}(|x| y)`",
@@ -144,7 +144,7 @@ pub(crate) trait BindInsteadOfMap {
     fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) -> bool {
         if_chain! {
             if let Some(adt) = cx.typeck_results().expr_ty(recv).ty_adt_def();
-            if let Ok(vid) = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM);
+            if let Some(vid) = cx.tcx.lang_items().get(Self::VARIANT_LANG_ITEM);
             if adt.did() == cx.tcx.parent(vid);
             then {} else { return false; }
         }
@@ -181,7 +181,7 @@ pub(crate) trait BindInsteadOfMap {
 
     fn is_variant(cx: &LateContext<'_>, res: Res) -> bool {
         if let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), id) = res {
-            if let Ok(variant_id) = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM) {
+            if let Some(variant_id) = cx.tcx.lang_items().get(Self::VARIANT_LANG_ITEM) {
                 return cx.tcx.parent(id) == variant_id;
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index fb92779be2a..8a76ba0b064 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -3250,15 +3250,15 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
         let name = impl_item.ident.name.as_str();
         let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id;
         let item = cx.tcx.hir().expect_item(parent);
-        let self_ty = cx.tcx.type_of(item.def_id);
+        let self_ty = cx.tcx.type_of(item.owner_id);
 
         let implements_trait = matches!(item.kind, hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }));
         if let hir::ImplItemKind::Fn(ref sig, id) = impl_item.kind {
-            let method_sig = cx.tcx.fn_sig(impl_item.def_id);
+            let method_sig = cx.tcx.fn_sig(impl_item.owner_id);
             let method_sig = cx.tcx.erase_late_bound_regions(method_sig);
             let first_arg_ty_opt = method_sig.inputs().iter().next().copied();
             // if this impl block implements a trait, lint in trait definition instead
-            if !implements_trait && cx.access_levels.is_exported(impl_item.def_id.def_id) {
+            if !implements_trait && cx.effective_visibilities.is_exported(impl_item.owner_id.def_id) {
                 // check missing trait implementations
                 for method_config in &TRAIT_METHODS {
                     if name == method_config.method_name
@@ -3292,7 +3292,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
 
             if sig.decl.implicit_self.has_implicit_self()
                     && !(self.avoid_breaking_exported_api
-                    && cx.access_levels.is_exported(impl_item.def_id.def_id))
+                    && cx.effective_visibilities.is_exported(impl_item.owner_id.def_id))
                     && let Some(first_arg) = iter_input_pats(sig.decl, cx.tcx.hir().body(id)).next()
                     && let Some(first_arg_ty) = first_arg_ty_opt
                 {
@@ -3370,7 +3370,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
             then {
                 let first_arg_span = first_arg_ty.span;
                 let first_arg_ty = hir_ty_to_ty(cx.tcx, first_arg_ty);
-                let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id())
+                let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id())
                     .self_ty()
                     .skip_binder();
                 wrong_self_convention::check(
@@ -3389,7 +3389,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
             if item.ident.name == sym::new;
             if let TraitItemKind::Fn(_, _) = item.kind;
             let ret_ty = return_ty(cx, item.hir_id());
-            let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id())
+            let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id())
                 .self_ty()
                 .skip_binder();
             if !ret_ty.contains(self_ty);
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
index 1966a85f7a7..4eb579af7a1 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
@@ -5,7 +5,7 @@ use clippy_utils::source::snippet_opt;
 use clippy_utils::ty::{get_associated_type, get_iterator_item_ty, implements_trait};
 use clippy_utils::{fn_def_id, get_parent_expr};
 use rustc_errors::Applicability;
-use rustc_hir::{def_id::DefId, Expr, ExprKind, LangItem};
+use rustc_hir::{def_id::DefId, Expr, ExprKind};
 use rustc_lint::LateContext;
 use rustc_span::{sym, Symbol};
 
@@ -100,5 +100,5 @@ pub fn check_for_loop_iter(
 
 /// Returns true if the named method is `IntoIterator::into_iter`.
 pub fn is_into_iter(cx: &LateContext<'_>, callee_def_id: DefId) -> bool {
-    cx.tcx.lang_items().require(LangItem::IntoIterIntoIter) == Ok(callee_def_id)
+    Some(callee_def_id) == cx.tcx.lang_items().into_iter_fn()
 }
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 3566fe9a0bb..642a64ae77b 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
@@ -7,7 +7,7 @@ use clippy_utils::visitors::find_all_ret_expressions;
 use clippy_utils::{fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, return_ty};
 use clippy_utils::{meets_msrv, msrvs};
 use rustc_errors::Applicability;
-use rustc_hir::{def_id::DefId, BorrowKind, Expr, ExprKind, ItemKind, LangItem, Node};
+use rustc_hir::{def_id::DefId, BorrowKind, Expr, ExprKind, ItemKind, Node};
 use rustc_hir_typeck::{FnCtxt, Inherited};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::LateContext;
@@ -378,7 +378,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
             Node::Expr(parent_expr) => {
                 if let Some((callee_def_id, call_substs, recv, call_args)) = get_callee_substs_and_args(cx, parent_expr)
                 {
-                    if cx.tcx.lang_items().require(LangItem::IntoFutureIntoFuture) == Ok(callee_def_id) {
+                    if Some(callee_def_id) == cx.tcx.lang_items().into_future_fn() {
                         return false;
                     }
 
diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs
index b3f1553cfea..2a63681db60 100644
--- a/src/tools/clippy/clippy_lints/src/missing_doc.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs
@@ -131,7 +131,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
             hir::ItemKind::Fn(..) => {
                 // ignore main()
                 if it.ident.name == sym::main {
-                    let at_root = cx.tcx.local_parent(it.def_id.def_id) == CRATE_DEF_ID;
+                    let at_root = cx.tcx.local_parent(it.owner_id.def_id) == CRATE_DEF_ID;
                     if at_root {
                         return;
                     }
@@ -155,7 +155,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
             | hir::ItemKind::Use(..) => return,
         };
 
-        let (article, desc) = cx.tcx.article_and_description(it.def_id.to_def_id());
+        let (article, desc) = cx.tcx.article_and_description(it.owner_id.to_def_id());
 
         let attrs = cx.tcx.hir().attrs(it.hir_id());
         if !is_from_proc_macro(cx, it) {
@@ -164,7 +164,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
     }
 
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx hir::TraitItem<'_>) {
-        let (article, desc) = cx.tcx.article_and_description(trait_item.def_id.to_def_id());
+        let (article, desc) = cx.tcx.article_and_description(trait_item.owner_id.to_def_id());
 
         let attrs = cx.tcx.hir().attrs(trait_item.hir_id());
         if !is_from_proc_macro(cx, trait_item) {
@@ -174,7 +174,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
 
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
         // If the method is an impl for a trait, don't doc.
-        if let Some(cid) = cx.tcx.associated_item(impl_item.def_id).impl_container(cx.tcx) {
+        if let Some(cid) = cx.tcx.associated_item(impl_item.owner_id).impl_container(cx.tcx) {
             if cx.tcx.impl_trait_ref(cid).is_some() {
                 return;
             }
@@ -182,7 +182,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
             return;
         }
 
-        let (article, desc) = cx.tcx.article_and_description(impl_item.def_id.to_def_id());
+        let (article, desc) = cx.tcx.article_and_description(impl_item.owner_id.to_def_id());
         let attrs = cx.tcx.hir().attrs(impl_item.hir_id());
         if !is_from_proc_macro(cx, impl_item) {
             self.check_missing_docs_attrs(cx, attrs, impl_item.span, article, desc);
diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs
index 01c87f058ad..758ce47cf11 100644
--- a/src/tools/clippy/clippy_lints/src/missing_inline.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs
@@ -88,7 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
             return;
         }
 
-        if !cx.access_levels.is_exported(it.def_id.def_id) {
+        if !cx.effective_visibilities.is_exported(it.owner_id.def_id) {
             return;
         }
         match it.kind {
@@ -105,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
                     match tit_.kind {
                         hir::TraitItemKind::Const(..) | hir::TraitItemKind::Type(..) => {},
                         hir::TraitItemKind::Fn(..) => {
-                            if cx.tcx.impl_defaultness(tit.id.def_id).has_value() {
+                            if cx.tcx.impl_defaultness(tit.id.owner_id).has_value() {
                                 // trait method with default body needs inline in case
                                 // an impl is not provided
                                 let desc = "a default trait method";
@@ -142,7 +142,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
         }
 
         // If the item being implemented is not exported, then we don't need #[inline]
-        if !cx.access_levels.is_exported(impl_item.def_id.def_id) {
+        if !cx.effective_visibilities.is_exported(impl_item.owner_id.def_id) {
             return;
         }
 
@@ -151,7 +151,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
             hir::ImplItemKind::Const(..) | hir::ImplItemKind::Type(_) => return,
         };
 
-        let assoc_item = cx.tcx.associated_item(impl_item.def_id);
+        let assoc_item = cx.tcx.associated_item(impl_item.owner_id);
         let container_id = assoc_item.container_id(cx.tcx);
         let trait_def_id = match assoc_item.container {
             TraitContainer => Some(container_id),
@@ -159,7 +159,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
         };
 
         if let Some(trait_def_id) = trait_def_id {
-            if trait_def_id.is_local() && !cx.access_levels.is_exported(impl_item.def_id.def_id) {
+            if trait_def_id.is_local() && !cx.effective_visibilities.is_exported(impl_item.owner_id.def_id) {
                 // If a trait is being implemented for an item, and the
                 // trait is not exported, we don't need #[inline]
                 return;
diff --git a/src/tools/clippy/clippy_lints/src/mut_key.rs b/src/tools/clippy/clippy_lints/src/mut_key.rs
index 25d6ca83a94..4b62dcdffe2 100644
--- a/src/tools/clippy/clippy_lints/src/mut_key.rs
+++ b/src/tools/clippy/clippy_lints/src/mut_key.rs
@@ -89,7 +89,7 @@ impl<'tcx> LateLintPass<'tcx> for MutableKeyType {
 
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'tcx>) {
         if let hir::ImplItemKind::Fn(ref sig, ..) = item.kind {
-            if trait_ref_of_method(cx, item.def_id.def_id).is_none() {
+            if trait_ref_of_method(cx, item.owner_id.def_id).is_none() {
                 check_sig(cx, item.hir_id(), sig.decl);
             }
         }
@@ -136,12 +136,14 @@ fn check_ty<'tcx>(cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) {
 /// [`Hash`] or [`Ord`].
 fn is_interior_mutable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Span) -> bool {
     match *ty.kind() {
-        Ref(_, inner_ty, mutbl) => mutbl == hir::Mutability::Mut || is_interior_mutable_type(cx, inner_ty, span),
+        Ref(_, inner_ty, mutbl) => {
+            mutbl == hir::Mutability::Mut || is_interior_mutable_type(cx, inner_ty, span)
+        }
         Slice(inner_ty) => is_interior_mutable_type(cx, inner_ty, span),
         Array(inner_ty, size) => {
             size.try_eval_usize(cx.tcx, cx.param_env).map_or(true, |u| u != 0)
                 && is_interior_mutable_type(cx, inner_ty, span)
-        },
+        }
         Tuple(fields) => fields.iter().any(|ty| is_interior_mutable_type(cx, ty, span)),
         Adt(def, substs) => {
             // Special case for collections in `std` who's impl of `Hash` or `Ord` delegates to
@@ -167,9 +169,9 @@ fn is_interior_mutable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Sp
             } else {
                 !ty.has_escaping_bound_vars()
                     && cx.tcx.layout_of(cx.param_env.and(ty)).is_ok()
-                    && !ty.is_freeze(cx.tcx.at(span), cx.param_env)
+                    && !ty.is_freeze(cx.tcx, cx.param_env)
             }
-        },
+        }
         _ => false,
     }
 }
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 9c949a28f44..b2e9ce5c94d 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
@@ -19,7 +19,7 @@ use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::{self, TypeVisitable};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::symbol::kw;
-use rustc_span::{sym, Span, DUMMY_SP};
+use rustc_span::{sym, Span};
 use rustc_target::spec::abi::Abi;
 use rustc_trait_selection::traits;
 use rustc_trait_selection::traits::misc::can_type_implement_copy;
@@ -184,7 +184,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
                 if !is_self(arg);
                 if !ty.is_mutable_ptr();
                 if !is_copy(cx, ty);
-                if ty.is_sized(cx.tcx.at(DUMMY_SP), cx.param_env);
+                if ty.is_sized(cx.tcx, cx.param_env);
                 if !allowed_traits.iter().any(|&t| implements_trait(cx, ty, t, &[]));
                 if !implements_borrow_trait;
                 if !all_borrowable_trait;
diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs
index 6017117e1ec..54a3c82b713 100644
--- a/src/tools/clippy/clippy_lints/src/new_without_default.rs
+++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs
@@ -84,7 +84,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
                             // can't be implemented for unsafe new
                             return;
                         }
-                        if cx.tcx.is_doc_hidden(impl_item.def_id.def_id) {
+                        if cx.tcx.is_doc_hidden(impl_item.owner_id.def_id) {
                             // shouldn't be implemented when it is hidden in docs
                             return;
                         }
@@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
                         if_chain! {
                             if sig.decl.inputs.is_empty();
                             if name == sym::new;
-                            if cx.access_levels.is_reachable(impl_item.def_id.def_id);
+                            if cx.effective_visibilities.is_reachable(impl_item.owner_id.def_id);
                             let self_def_id = cx.tcx.hir().get_parent_item(id);
                             let self_ty = cx.tcx.type_of(self_def_id);
                             if self_ty == return_ty(cx, id);
diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
index a6742824bc5..2a3bd4ee6ce 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -20,7 +20,7 @@ use rustc_middle::mir::interpret::{ConstValue, ErrorHandled};
 use rustc_middle::ty::adjustment::Adjust;
 use rustc_middle::ty::{self, Ty};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::{sym, InnerSpan, Span, DUMMY_SP};
+use rustc_span::{sym, InnerSpan, Span};
 
 // FIXME: this is a correctness problem but there's no suitable
 // warn-by-default category.
@@ -136,7 +136,7 @@ fn is_unfrozen<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
     // since it works when a pointer indirection involves (`Cell<*const T>`).
     // Making up a `ParamEnv` where every generic params and assoc types are `Freeze`is another option;
     // but I'm not sure whether it's a decent way, if possible.
-    cx.tcx.layout_of(cx.param_env.and(ty)).is_ok() && !ty.is_freeze(cx.tcx.at(DUMMY_SP), cx.param_env)
+    cx.tcx.layout_of(cx.param_env.and(ty)).is_ok() && !ty.is_freeze(cx.tcx, cx.param_env)
 }
 
 fn is_value_unfrozen_raw<'tcx>(
@@ -303,7 +303,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
                         if let Some(of_trait_def_id) = of_trait_ref.trait_def_id();
                         if let Some(of_assoc_item) = cx
                             .tcx
-                            .associated_item(impl_item.def_id)
+                            .associated_item(impl_item.owner_id)
                             .trait_item_def_id;
                         if cx
                             .tcx
diff --git a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
index ddef7352de8..714c0ff227b 100644
--- a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
+++ b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
@@ -89,7 +89,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy {
             if let Some(trait_id) = trait_ref.trait_def_id();
             if send_trait == trait_id;
             if hir_impl.polarity == ImplPolarity::Positive;
-            if let Some(ty_trait_ref) = cx.tcx.impl_trait_ref(item.def_id);
+            if let Some(ty_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id);
             if let self_ty = ty_trait_ref.self_ty();
             if let ty::Adt(adt_def, impl_trait_substs) = self_ty.kind();
             then {
diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs
index d64a9cf71e1..7722a476d7b 100644
--- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs
+++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs
@@ -227,25 +227,25 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
         // `skip_params` is either `0` or `1` to skip the `self` parameter in trait functions.
         // It can't be renamed, and it can't be removed without removing it from multiple functions.
         let (fn_id, fn_kind, skip_params) = match get_parent_node(cx.tcx, body.value.hir_id) {
-            Some(Node::Item(i)) => (i.def_id.to_def_id(), FnKind::Fn, 0),
+            Some(Node::Item(i)) => (i.owner_id.to_def_id(), FnKind::Fn, 0),
             Some(Node::TraitItem(&TraitItem {
                 kind: TraitItemKind::Fn(ref sig, _),
-                def_id,
+                owner_id,
                 ..
             })) => (
-                def_id.to_def_id(),
+                owner_id.to_def_id(),
                 FnKind::TraitFn,
                 usize::from(sig.decl.implicit_self.has_implicit_self()),
             ),
             Some(Node::ImplItem(&ImplItem {
                 kind: ImplItemKind::Fn(ref sig, _),
-                def_id,
+                owner_id,
                 ..
             })) => {
                 #[allow(trivial_casts)]
-                if let Some(Node::Item(item)) = get_parent_node(cx.tcx, def_id.into())
-                    && let Some(trait_ref) = cx.tcx.impl_trait_ref(item.def_id)
-                    && let Some(trait_item_id) = cx.tcx.associated_item(def_id).trait_item_def_id
+                if let Some(Node::Item(item)) = get_parent_node(cx.tcx, owner_id.into())
+                    && let Some(trait_ref) = cx.tcx.impl_trait_ref(item.owner_id)
+                    && let Some(trait_item_id) = cx.tcx.associated_item(owner_id).trait_item_def_id
                 {
                     (
                         trait_item_id,
@@ -253,7 +253,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
                         usize::from(sig.decl.implicit_self.has_implicit_self()),
                     )
                 } else {
-                    (def_id.to_def_id(), FnKind::Fn, 0)
+                    (owner_id.to_def_id(), FnKind::Fn, 0)
                 }
             },
             _ => return,
diff --git a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
index ee9fd94064c..9bbf385fb59 100644
--- a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
@@ -28,7 +28,7 @@ pub(super) fn check<'tcx>(
             let rty = cx.typeck_results().expr_ty(rhs);
             if_chain! {
                 if let Some((_, lang_item)) = binop_traits(op.node);
-                if let Ok(trait_id) = cx.tcx.lang_items().require(lang_item);
+                if let Some(trait_id) = cx.tcx.lang_items().get(lang_item);
                 let parent_fn = cx.tcx.hir().get_parent_item(e.hir_id).def_id;
                 if trait_ref_of_method(cx, parent_fn)
                     .map_or(true, |t| t.path.res.def_id() != trait_id);
diff --git a/src/tools/clippy/clippy_lints/src/operators/op_ref.rs b/src/tools/clippy/clippy_lints/src/operators/op_ref.rs
index 1085e608944..71b31b5e4a5 100644
--- a/src/tools/clippy/clippy_lints/src/operators/op_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/op_ref.rs
@@ -204,7 +204,7 @@ fn are_equal<'tcx>(cx: &LateContext<'tcx>, middle_ty: Ty<'_>, hir_ty: &rustc_hir
         if let ty::Adt(adt_def, _) = middle_ty.kind();
         if let Some(local_did) = adt_def.did().as_local();
         let item = cx.tcx.hir().expect_item(local_did);
-        let middle_ty_id = item.def_id.to_def_id();
+        let middle_ty_id = item.owner_id.to_def_id();
         if let TyKind::Path(QPath::Resolved(_, path)) = hir_ty.kind;
         if let Res::Def(_, hir_ty_id) = path.res;
 
diff --git a/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs b/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs
index 09ac514d014..5aa3c6f2f93 100644
--- a/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs
@@ -36,7 +36,7 @@ impl<'tcx> LateLintPass<'tcx> for PartialEqNeImpl {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
         if_chain! {
             if let ItemKind::Impl(Impl { of_trait: Some(ref trait_ref), items: impl_items, .. }) = item.kind;
-            if !cx.tcx.has_attr(item.def_id.to_def_id(), sym::automatically_derived);
+            if !cx.tcx.has_attr(item.owner_id.to_def_id(), sym::automatically_derived);
             if let Some(eq_trait) = cx.tcx.lang_items().eq_trait();
             if trait_ref.path.res.def_id() == eq_trait;
             then {
diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
index 45e98de10ac..f9fd3645668 100644
--- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
+++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
@@ -139,7 +139,7 @@ impl<'tcx> PassByRefOrValue {
     }
 
     fn check_poly_fn(&mut self, cx: &LateContext<'tcx>, def_id: LocalDefId, decl: &FnDecl<'_>, span: Option<Span>) {
-        if self.avoid_breaking_exported_api && cx.access_levels.is_exported(def_id) {
+        if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id) {
             return;
         }
 
@@ -261,7 +261,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue {
         }
 
         if let hir::TraitItemKind::Fn(method_sig, _) = &item.kind {
-            self.check_poly_fn(cx, item.def_id.def_id, method_sig.decl, None);
+            self.check_poly_fn(cx, item.owner_id.def_id, method_sig.decl, None);
         }
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index 40db315bf27..0d74c90a834 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -164,7 +164,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
             check_mut_from_ref(cx, sig, None);
             for arg in check_fn_args(
                 cx,
-                cx.tcx.fn_sig(item.def_id).skip_binder().inputs(),
+                cx.tcx.fn_sig(item.owner_id).skip_binder().inputs(),
                 sig.decl.inputs,
                 &[],
             )
@@ -188,7 +188,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
         let (item_id, sig, is_trait_item) = match parents.next() {
             Some((_, Node::Item(i))) => {
                 if let ItemKind::Fn(sig, ..) = &i.kind {
-                    (i.def_id, sig, false)
+                    (i.owner_id, sig, false)
                 } else {
                     return;
                 }
@@ -200,14 +200,14 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
                     return;
                 }
                 if let ImplItemKind::Fn(sig, _) = &i.kind {
-                    (i.def_id, sig, false)
+                    (i.owner_id, sig, false)
                 } else {
                     return;
                 }
             },
             Some((_, Node::TraitItem(i))) => {
                 if let TraitItemKind::Fn(sig, _) = &i.kind {
-                    (i.def_id, sig, true)
+                    (i.owner_id, sig, true)
                 } else {
                     return;
                 }
diff --git a/src/tools/clippy/clippy_lints/src/question_mark.rs b/src/tools/clippy/clippy_lints/src/question_mark.rs
index 328371fd602..bb86fb3b7d4 100644
--- a/src/tools/clippy/clippy_lints/src/question_mark.rs
+++ b/src/tools/clippy/clippy_lints/src/question_mark.rs
@@ -94,7 +94,7 @@ fn check_is_none_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Ex
         then {
             let mut applicability = Applicability::MachineApplicable;
             let receiver_str = snippet_with_applicability(cx, caller.span, "..", &mut applicability);
-            let by_ref = !caller_ty.is_copy_modulo_regions(cx.tcx.at(caller.span), cx.param_env) &&
+            let by_ref = !caller_ty.is_copy_modulo_regions(cx.tcx, cx.param_env) &&
                 !matches!(caller.kind, ExprKind::Call(..) | ExprKind::MethodCall(..));
             let sugg = if let Some(else_inner) = r#else {
                 if eq_expr_value(cx, caller, peel_blocks(else_inner)) {
diff --git a/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs b/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs
index 464f6827e1d..26075e9f70f 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs
@@ -46,12 +46,12 @@ impl_lint_pass!(RedundantPubCrate => [REDUNDANT_PUB_CRATE]);
 impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
         if_chain! {
-            if cx.tcx.visibility(item.def_id.def_id) == ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id());
-            if !cx.access_levels.is_exported(item.def_id.def_id) && self.is_exported.last() == Some(&false);
+            if cx.tcx.visibility(item.owner_id.def_id) == ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id());
+            if !cx.effective_visibilities.is_exported(item.owner_id.def_id) && self.is_exported.last() == Some(&false);
             if is_not_macro_export(item);
             then {
                 let span = item.span.with_hi(item.ident.span.hi());
-                let descr = cx.tcx.def_kind(item.def_id).descr(item.def_id.to_def_id());
+                let descr = cx.tcx.def_kind(item.owner_id).descr(item.owner_id.to_def_id());
                 span_lint_and_then(
                     cx,
                     REDUNDANT_PUB_CRATE,
@@ -70,7 +70,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
         }
 
         if let ItemKind::Mod { .. } = item.kind {
-            self.is_exported.push(cx.access_levels.is_exported(item.def_id.def_id));
+            self.is_exported.push(cx.effective_visibilities.is_exported(item.owner_id.def_id));
         }
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs
index 16d702a3868..b77faf7322b 100644
--- a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs
+++ b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs
@@ -74,7 +74,7 @@ fn check_method(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_def: LocalDefId, spa
         if !in_external_macro(cx.sess(), span);
         if decl.implicit_self.has_implicit_self();
         // We only show this warning for public exported methods.
-        if cx.access_levels.is_exported(fn_def);
+        if cx.effective_visibilities.is_exported(fn_def);
         // We don't want to emit this lint if the `#[must_use]` attribute is already there.
         if !cx.tcx.hir().attrs(hir_id).iter().any(|attr| attr.has_name(sym::must_use));
         if cx.tcx.visibility(fn_def.to_def_id()).is_public();
@@ -128,7 +128,7 @@ impl<'tcx> LateLintPass<'tcx> for ReturnSelfNotMustUse {
 
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'tcx>) {
         if let TraitItemKind::Fn(ref sig, _) = item.kind {
-            check_method(cx, sig.decl, item.def_id.def_id, item.span, item.hir_id());
+            check_method(cx, sig.decl, item.owner_id.def_id, item.span, item.hir_id());
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs
index 4249063d2d4..caab5851baf 100644
--- a/src/tools/clippy/clippy_lints/src/same_name_method.rs
+++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs
@@ -52,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
         let mut map = FxHashMap::<Res, ExistingName>::default();
 
         for id in cx.tcx.hir().items() {
-            if matches!(cx.tcx.def_kind(id.def_id), DefKind::Impl)
+            if matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl)
                 && let item = cx.tcx.hir().item(id)
                 && let ItemKind::Impl(Impl {
                   items,
diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs
index 1ac538f4c7c..71b387c66a3 100644
--- a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs
+++ b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs
@@ -53,7 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors {
 
         let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id;
         let item = cx.tcx.hir().expect_item(parent);
-        let self_ty = cx.tcx.type_of(item.def_id);
+        let self_ty = cx.tcx.type_of(item.owner_id);
         let ret_ty = return_ty(cx, impl_item.hir_id());
 
         // Do not check trait impls
diff --git a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
index b57b484bdc8..6271ea02731 100644
--- a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
@@ -60,8 +60,8 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl {
         if_chain! {
             if let hir::ExprKind::Binary(binop, _, _) | hir::ExprKind::AssignOp(binop, ..) = expr.kind;
             if let Some((binop_trait_lang, op_assign_trait_lang)) = binop_traits(binop.node);
-            if let Ok(binop_trait_id) = cx.tcx.lang_items().require(binop_trait_lang);
-            if let Ok(op_assign_trait_id) = cx.tcx.lang_items().require(op_assign_trait_lang);
+            if let Some(binop_trait_id) = cx.tcx.lang_items().get(binop_trait_lang);
+            if let Some(op_assign_trait_id) = cx.tcx.lang_items().get(op_assign_trait_lang);
 
             // Check for more than one binary operation in the implemented function
             // Linting when multiple operations are involved can result in false positives
@@ -78,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl {
                 (&OP_ASSIGN_TRAITS, SUSPICIOUS_OP_ASSIGN_IMPL),
             ]
                 .iter()
-                .find(|&(ts, _)| ts.iter().any(|&t| Ok(trait_id) == cx.tcx.lang_items().require(t)));
+                .find(|&(ts, _)| ts.iter().any(|&t| Some(trait_id) == cx.tcx.lang_items().get(t)));
             if count_binops(body.value) == 1;
             then {
                 span_lint(
diff --git a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs
index 58cc057a39e..8cf3efc8dc7 100644
--- a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs
+++ b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs
@@ -46,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for TrailingEmptyArray {
                 None,
                 &format!(
                     "consider annotating `{}` with `#[repr(C)]` or another `repr` attribute",
-                    cx.tcx.def_path_str(item.def_id.to_def_id())
+                    cx.tcx.def_path_str(item.owner_id.to_def_id())
                 ),
             );
         }
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
index 1c99a02e6c7..3d4bbbf648c 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
@@ -5,7 +5,6 @@ use rustc_hir::Expr;
 use rustc_lint::LateContext;
 use rustc_middle::ty::SubstsRef;
 use rustc_middle::ty::{self, IntTy, Ty, TypeAndMut, UintTy};
-use rustc_span::DUMMY_SP;
 
 #[expect(clippy::too_many_lines)]
 pub(super) fn check<'tcx>(
@@ -28,24 +27,32 @@ pub(super) fn check<'tcx>(
 
             // `Repr(C)` <-> unordered type.
             // If the first field of the `Repr(C)` type matches then the transmute is ok
-            (ReducedTy::OrderedFields(_, Some(from_sub_ty)), ReducedTy::UnorderedFields(to_sub_ty))
-            | (ReducedTy::UnorderedFields(from_sub_ty), ReducedTy::OrderedFields(_, Some(to_sub_ty))) => {
+            (
+                ReducedTy::OrderedFields(_, Some(from_sub_ty)),
+                ReducedTy::UnorderedFields(to_sub_ty),
+            )
+            | (
+                ReducedTy::UnorderedFields(from_sub_ty),
+                ReducedTy::OrderedFields(_, Some(to_sub_ty)),
+            ) => {
                 from_ty = from_sub_ty;
                 to_ty = to_sub_ty;
                 continue;
-            },
-            (ReducedTy::OrderedFields(_, Some(from_sub_ty)), ReducedTy::Other(to_sub_ty)) if reduced_tys.to_fat_ptr => {
+            }
+            (ReducedTy::OrderedFields(_, Some(from_sub_ty)), ReducedTy::Other(to_sub_ty))
+                if reduced_tys.to_fat_ptr =>
+            {
                 from_ty = from_sub_ty;
                 to_ty = to_sub_ty;
                 continue;
-            },
+            }
             (ReducedTy::Other(from_sub_ty), ReducedTy::OrderedFields(_, Some(to_sub_ty)))
                 if reduced_tys.from_fat_ptr =>
             {
                 from_ty = from_sub_ty;
                 to_ty = to_sub_ty;
                 continue;
-            },
+            }
 
             // ptr <-> ptr
             (ReducedTy::Other(from_sub_ty), ReducedTy::Other(to_sub_ty))
@@ -55,19 +62,19 @@ pub(super) fn check<'tcx>(
                 from_ty = from_sub_ty;
                 to_ty = to_sub_ty;
                 continue;
-            },
+            }
 
             // fat ptr <-> (*size, *size)
             (ReducedTy::Other(_), ReducedTy::UnorderedFields(to_ty))
                 if reduced_tys.from_fat_ptr && is_size_pair(to_ty) =>
             {
                 return false;
-            },
+            }
             (ReducedTy::UnorderedFields(from_ty), ReducedTy::Other(_))
                 if reduced_tys.to_fat_ptr && is_size_pair(from_ty) =>
             {
                 return false;
-            },
+            }
 
             // fat ptr -> some struct | some struct -> fat ptr
             (ReducedTy::Other(_), _) if reduced_tys.from_fat_ptr => {
@@ -78,12 +85,14 @@ pub(super) fn check<'tcx>(
                     &format!("transmute from `{from_ty_orig}` which has an undefined layout"),
                     |diag| {
                         if from_ty_orig.peel_refs() != from_ty.peel_refs() {
-                            diag.note(&format!("the contained type `{from_ty}` has an undefined layout"));
+                            diag.note(&format!(
+                                "the contained type `{from_ty}` has an undefined layout"
+                            ));
                         }
                     },
                 );
                 return true;
-            },
+            }
             (_, ReducedTy::Other(_)) if reduced_tys.to_fat_ptr => {
                 span_lint_and_then(
                     cx,
@@ -92,14 +101,18 @@ pub(super) fn check<'tcx>(
                     &format!("transmute to `{to_ty_orig}` which has an undefined layout"),
                     |diag| {
                         if to_ty_orig.peel_refs() != to_ty.peel_refs() {
-                            diag.note(&format!("the contained type `{to_ty}` has an undefined layout"));
+                            diag.note(&format!(
+                                "the contained type `{to_ty}` has an undefined layout"
+                            ));
                         }
                     },
                 );
                 return true;
-            },
+            }
 
-            (ReducedTy::UnorderedFields(from_ty), ReducedTy::UnorderedFields(to_ty)) if from_ty != to_ty => {
+            (ReducedTy::UnorderedFields(from_ty), ReducedTy::UnorderedFields(to_ty))
+                if from_ty != to_ty =>
+            {
                 let same_adt_did = if let (ty::Adt(from_def, from_subs), ty::Adt(to_def, to_subs))
                         = (from_ty.kind(), to_ty.kind())
                         && from_def == to_def
@@ -126,19 +139,25 @@ pub(super) fn check<'tcx>(
                             ));
                         } else {
                             if from_ty_orig.peel_refs() != from_ty {
-                                diag.note(&format!("the contained type `{from_ty}` has an undefined layout"));
+                                diag.note(&format!(
+                                    "the contained type `{from_ty}` has an undefined layout"
+                                ));
                             }
                             if to_ty_orig.peel_refs() != to_ty {
-                                diag.note(&format!("the contained type `{to_ty}` has an undefined layout"));
+                                diag.note(&format!(
+                                    "the contained type `{to_ty}` has an undefined layout"
+                                ));
                             }
                         }
                     },
                 );
                 return true;
-            },
+            }
             (
                 ReducedTy::UnorderedFields(from_ty),
-                ReducedTy::Other(_) | ReducedTy::OrderedFields(..) | ReducedTy::TypeErasure { raw_ptr_only: true },
+                ReducedTy::Other(_)
+                | ReducedTy::OrderedFields(..)
+                | ReducedTy::TypeErasure { raw_ptr_only: true },
             ) => {
                 span_lint_and_then(
                     cx,
@@ -147,14 +166,18 @@ pub(super) fn check<'tcx>(
                     &format!("transmute from `{from_ty_orig}` which has an undefined layout"),
                     |diag| {
                         if from_ty_orig.peel_refs() != from_ty {
-                            diag.note(&format!("the contained type `{from_ty}` has an undefined layout"));
+                            diag.note(&format!(
+                                "the contained type `{from_ty}` has an undefined layout"
+                            ));
                         }
                     },
                 );
                 return true;
-            },
+            }
             (
-                ReducedTy::Other(_) | ReducedTy::OrderedFields(..) | ReducedTy::TypeErasure { raw_ptr_only: true },
+                ReducedTy::Other(_)
+                | ReducedTy::OrderedFields(..)
+                | ReducedTy::TypeErasure { raw_ptr_only: true },
                 ReducedTy::UnorderedFields(to_ty),
             ) => {
                 span_lint_and_then(
@@ -164,19 +187,25 @@ pub(super) fn check<'tcx>(
                     &format!("transmute into `{to_ty_orig}` which has an undefined layout"),
                     |diag| {
                         if to_ty_orig.peel_refs() != to_ty {
-                            diag.note(&format!("the contained type `{to_ty}` has an undefined layout"));
+                            diag.note(&format!(
+                                "the contained type `{to_ty}` has an undefined layout"
+                            ));
                         }
                     },
                 );
                 return true;
-            },
+            }
             (
-                ReducedTy::OrderedFields(..) | ReducedTy::Other(_) | ReducedTy::TypeErasure { raw_ptr_only: true },
-                ReducedTy::OrderedFields(..) | ReducedTy::Other(_) | ReducedTy::TypeErasure { raw_ptr_only: true },
+                ReducedTy::OrderedFields(..)
+                | ReducedTy::Other(_)
+                | ReducedTy::TypeErasure { raw_ptr_only: true },
+                ReducedTy::OrderedFields(..)
+                | ReducedTy::Other(_)
+                | ReducedTy::TypeErasure { raw_ptr_only: true },
             )
             | (ReducedTy::UnorderedFields(_), ReducedTy::UnorderedFields(_)) => {
                 break;
-            },
+            }
         }
     }
 
@@ -194,42 +223,38 @@ struct ReducedTys<'tcx> {
 }
 
 /// Remove references so long as both types are references.
-fn reduce_refs<'tcx>(cx: &LateContext<'tcx>, mut from_ty: Ty<'tcx>, mut to_ty: Ty<'tcx>) -> ReducedTys<'tcx> {
+fn reduce_refs<'tcx>(
+    cx: &LateContext<'tcx>,
+    mut from_ty: Ty<'tcx>,
+    mut to_ty: Ty<'tcx>,
+) -> ReducedTys<'tcx> {
     let mut from_raw_ptr = false;
     let mut to_raw_ptr = false;
-    let (from_fat_ptr, to_fat_ptr) = loop {
-        break match (from_ty.kind(), to_ty.kind()) {
-            (
-                &(ty::Ref(_, from_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: from_sub_ty, .. })),
-                &(ty::Ref(_, to_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: to_sub_ty, .. })),
-            ) => {
-                from_raw_ptr = matches!(*from_ty.kind(), ty::RawPtr(_));
-                from_ty = from_sub_ty;
-                to_raw_ptr = matches!(*to_ty.kind(), ty::RawPtr(_));
-                to_ty = to_sub_ty;
-                continue;
-            },
-            (&(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })), _)
-                if !unsized_ty.is_sized(cx.tcx.at(DUMMY_SP), cx.param_env) =>
-            {
-                (true, false)
-            },
-            (_, &(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })))
-                if !unsized_ty.is_sized(cx.tcx.at(DUMMY_SP), cx.param_env) =>
-            {
-                (false, true)
-            },
-            _ => (false, false),
+    let (from_fat_ptr, to_fat_ptr) =
+        loop {
+            break match (from_ty.kind(), to_ty.kind()) {
+                (
+                    &(ty::Ref(_, from_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: from_sub_ty, .. })),
+                    &(ty::Ref(_, to_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: to_sub_ty, .. })),
+                ) => {
+                    from_raw_ptr = matches!(*from_ty.kind(), ty::RawPtr(_));
+                    from_ty = from_sub_ty;
+                    to_raw_ptr = matches!(*to_ty.kind(), ty::RawPtr(_));
+                    to_ty = to_sub_ty;
+                    continue;
+                }
+                (
+                    &(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })),
+                    _,
+                ) if !unsized_ty.is_sized(cx.tcx, cx.param_env) => (true, false),
+                (
+                    _,
+                    &(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })),
+                ) if !unsized_ty.is_sized(cx.tcx, cx.param_env) => (false, true),
+                _ => (false, false),
+            };
         };
-    };
-    ReducedTys {
-        from_ty,
-        to_ty,
-        from_raw_ptr,
-        to_raw_ptr,
-        from_fat_ptr,
-        to_fat_ptr,
-    }
+    ReducedTys { from_ty, to_ty, from_raw_ptr, to_raw_ptr, from_fat_ptr, to_fat_ptr }
 }
 
 enum ReducedTy<'tcx> {
@@ -252,11 +277,11 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
         return match *ty.kind() {
             ty::Array(sub_ty, _) if matches!(sub_ty.kind(), ty::Int(_) | ty::Uint(_)) => {
                 ReducedTy::TypeErasure { raw_ptr_only: false }
-            },
+            }
             ty::Array(sub_ty, _) | ty::Slice(sub_ty) => {
                 ty = sub_ty;
                 continue;
-            },
+            }
             ty::Tuple(args) if args.is_empty() => ReducedTy::TypeErasure { raw_ptr_only: false },
             ty::Tuple(args) => {
                 let mut iter = args.iter();
@@ -268,7 +293,7 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
                     continue;
                 }
                 ReducedTy::UnorderedFields(ty)
-            },
+            }
             ty::Adt(def, substs) if def.is_struct() => {
                 let mut iter = def
                     .non_enum_variant()
@@ -287,10 +312,12 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
                 } else {
                     ReducedTy::UnorderedFields(ty)
                 }
-            },
-            ty::Adt(def, _) if def.is_enum() && (def.variants().is_empty() || is_c_void(cx, ty)) => {
+            }
+            ty::Adt(def, _)
+                if def.is_enum() && (def.variants().is_empty() || is_c_void(cx, ty)) =>
+            {
                 ReducedTy::TypeErasure { raw_ptr_only: false }
-            },
+            }
             // TODO: Check if the conversion to or from at least one of a union's fields is valid.
             ty::Adt(def, _) if def.is_union() => ReducedTy::TypeErasure { raw_ptr_only: false },
             ty::Foreign(_) | ty::Param(_) => ReducedTy::TypeErasure { raw_ptr_only: false },
@@ -329,7 +356,11 @@ fn same_except_params<'tcx>(subs1: SubstsRef<'tcx>, subs2: SubstsRef<'tcx>) -> b
     for (ty1, ty2) in subs1.types().zip(subs2.types()).filter(|(ty1, ty2)| ty1 != ty2) {
         match (ty1.kind(), ty2.kind()) {
             (ty::Param(_), _) | (_, ty::Param(_)) => (),
-            (ty::Adt(adt1, subs1), ty::Adt(adt2, subs2)) if adt1 == adt2 && same_except_params(subs1, subs2) => (),
+            (ty::Adt(adt1, subs1), ty::Adt(adt2, subs2))
+                if adt1 == adt2 && same_except_params(subs1, subs2) =>
+            {
+                ()
+            }
             _ => return false,
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/transmute/utils.rs b/src/tools/clippy/clippy_lints/src/transmute/utils.rs
index 2f190e594a8..641cdf5d330 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/utils.rs
@@ -3,6 +3,7 @@ use rustc_hir_typeck::{cast, FnCtxt, Inherited};
 use rustc_lint::LateContext;
 use rustc_middle::ty::{cast::CastKind, Ty};
 use rustc_span::DUMMY_SP;
+use rustc_hir as hir;
 
 // check if the component types of the transmuted collection and the result have different ABI,
 // size or alignment
@@ -56,7 +57,7 @@ fn check_cast<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>
         if let Ok(check) = cast::CastCheck::new(
             &fn_ctxt, e, from_ty, to_ty,
             // We won't show any error to the user, so we don't care what the span is here.
-            DUMMY_SP, DUMMY_SP,
+            DUMMY_SP, DUMMY_SP, hir::Constness::NotConst,
         ) {
             let res = check.do_check(&fn_ctxt);
 
diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs
index a06d1fffd8b..f6de87b0526 100644
--- a/src/tools/clippy/clippy_lints/src/types/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/types/mod.rs
@@ -319,7 +319,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
                 false
             };
 
-        let is_exported = cx.access_levels.is_exported(cx.tcx.hir().local_def_id(id));
+        let is_exported = cx.effective_visibilities.is_exported(cx.tcx.hir().local_def_id(id));
 
         self.check_fn_decl(
             cx,
@@ -333,7 +333,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
     }
 
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
-        let is_exported = cx.access_levels.is_exported(item.def_id.def_id);
+        let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id);
 
         match item.kind {
             ItemKind::Static(ty, _, _) | ItemKind::Const(ty, _) => self.check_ty(
@@ -379,7 +379,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
     }
 
     fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) {
-        let is_exported = cx.access_levels.is_exported(cx.tcx.hir().local_def_id(field.hir_id));
+        let is_exported = cx.effective_visibilities.is_exported(cx.tcx.hir().local_def_id(field.hir_id));
 
         self.check_ty(
             cx,
@@ -392,7 +392,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
     }
 
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &TraitItem<'_>) {
-        let is_exported = cx.access_levels.is_exported(item.def_id.def_id);
+        let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id);
 
         let context = CheckTyContext {
             is_exported,
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 7883353e3fe..2b964b64a33 100644
--- a/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs
+++ b/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs
@@ -9,7 +9,12 @@ use rustc_span::symbol::sym;
 
 use super::{utils, REDUNDANT_ALLOCATION};
 
-pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool {
+pub(super) fn check(
+    cx: &LateContext<'_>,
+    hir_ty: &hir::Ty<'_>,
+    qpath: &QPath<'_>,
+    def_id: DefId,
+) -> bool {
     let mut applicability = Applicability::MaybeIncorrect;
     let outer_sym = if Some(def_id) == cx.tcx.lang_items().owned_box() {
         "Box"
@@ -29,7 +34,12 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
             hir_ty.span,
             &format!("usage of `{outer_sym}<{generic_snippet}>`"),
             |diag| {
-                diag.span_suggestion(hir_ty.span, "try", format!("{generic_snippet}"), applicability);
+                diag.span_suggestion(
+                    hir_ty.span,
+                    "try",
+                    format!("{generic_snippet}"),
+                    applicability,
+                );
                 diag.note(&format!(
                     "`{generic_snippet}` is already a pointer, `{outer_sym}<{generic_snippet}>` allocates a pointer on the heap"
                 ));
@@ -55,11 +65,11 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
             // Reallocation of a fat pointer causes it to become thin. `hir_ty_to_ty` is safe to use
             // here because `mod.rs` guarantees this lint is only run on types outside of bodies and
             // is not run on locals.
-            if !hir_ty_to_ty(cx.tcx, ty).is_sized(cx.tcx.at(ty.span), cx.param_env) {
+            if !hir_ty_to_ty(cx.tcx, ty).is_sized(cx.tcx, cx.param_env) {
                 return false;
             }
             ty.span
-        },
+        }
         None => return false,
     };
     if inner_sym == outer_sym {
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 6c329d8cdf1..9ad2cb853d3 100644
--- a/src/tools/clippy/clippy_lints/src/types/vec_box.rs
+++ b/src/tools/clippy/clippy_lints/src/types/vec_box.rs
@@ -40,7 +40,7 @@ pub(super) fn check(
             });
             let ty_ty = hir_ty_to_ty(cx.tcx, boxed_ty);
             if !ty_ty.has_escaping_bound_vars();
-            if ty_ty.is_sized(cx.tcx.at(ty.span), cx.param_env);
+            if ty_ty.is_sized(cx.tcx, cx.param_env);
             if let Ok(ty_ty_size) = cx.layout_of(ty_ty).map(|l| l.size.bytes());
             if ty_ty_size <= box_size_threshold;
             then {
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 016aacbf9da..ab73f0fc44f 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
@@ -3,7 +3,7 @@ use clippy_utils::{match_def_path, paths};
 use if_chain::if_chain;
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
-use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability};
+use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -55,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryOwnedEmptyStrings {
                         );
                 } else {
                     if_chain! {
-                        if cx.tcx.lang_items().require(LangItem::FromFrom).ok() == Some(fun_def_id);
+                        if Some(fun_def_id) == cx.tcx.lang_items().from_fn();
                         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/unnecessary_wraps.rs b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
index 7211e6864f3..60b46854b4f 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
@@ -83,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
         match fn_kind {
             FnKind::ItemFn(..) | FnKind::Method(..) => {
                 let def_id = cx.tcx.hir().local_def_id(hir_id);
-                if self.avoid_breaking_exported_api && cx.access_levels.is_exported(def_id) {
+                if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id) {
                     return;
                 }
             },
diff --git a/src/tools/clippy/clippy_lints/src/unused_peekable.rs b/src/tools/clippy/clippy_lints/src/unused_peekable.rs
index f1cebf0f992..b452be08409 100644
--- a/src/tools/clippy/clippy_lints/src/unused_peekable.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_peekable.rs
@@ -3,7 +3,6 @@ use clippy_utils::ty::{match_type, peel_mid_ty_refs_is_mutable};
 use clippy_utils::{fn_def_id, is_trait_method, path_to_local_id, paths, peel_ref_operators};
 use rustc_ast::Mutability;
 use rustc_hir::intravisit::{walk_expr, Visitor};
-use rustc_hir::lang_items::LangItem;
 use rustc_hir::{Block, Expr, ExprKind, HirId, Local, Node, PatKind, PathSegment, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter::OnlyBodies;
@@ -132,11 +131,11 @@ impl<'tcx> Visitor<'tcx> for PeekableVisitor<'_, 'tcx> {
                             // If the Peekable is passed to a function, stop
                             ExprKind::Call(_, args) => {
                                 if let Some(func_did) = fn_def_id(self.cx, expr)
-                                    && let Ok(into_iter_did) = self
+                                    && let Some(into_iter_did) = self
                                         .cx
                                         .tcx
                                         .lang_items()
-                                        .require(LangItem::IntoIterIntoIter)
+                                        .into_iter_fn()
                                     && func_did == into_iter_did
                                 {
                                     // Probably a for loop desugar, stop searching
diff --git a/src/tools/clippy/clippy_lints/src/unused_self.rs b/src/tools/clippy/clippy_lints/src/unused_self.rs
index 713fe06bad4..42bccc7212b 100644
--- a/src/tools/clippy/clippy_lints/src/unused_self.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_self.rs
@@ -56,12 +56,12 @@ impl<'tcx> LateLintPass<'tcx> for UnusedSelf {
         }
         let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id;
         let parent_item = cx.tcx.hir().expect_item(parent);
-        let assoc_item = cx.tcx.associated_item(impl_item.def_id);
+        let assoc_item = cx.tcx.associated_item(impl_item.owner_id);
         if_chain! {
             if let ItemKind::Impl(Impl { of_trait: None, .. }) = parent_item.kind;
             if assoc_item.fn_has_self_parameter;
             if let ImplItemKind::Fn(.., body_id) = &impl_item.kind;
-            if !cx.access_levels.is_exported(impl_item.def_id.def_id) || !self.avoid_breaking_exported_api;
+            if !cx.effective_visibilities.is_exported(impl_item.owner_id.def_id) || !self.avoid_breaking_exported_api;
             let body = cx.tcx.hir().body(*body_id);
             if let [self_param, ..] = body.params;
             if !is_local_used(cx, body, self_param.pat.hir_id);
diff --git a/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs b/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs
index a69719b127b..f3611d17434 100644
--- a/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs
+++ b/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs
@@ -76,7 +76,7 @@ impl<'tcx> LateLintPass<'tcx> for UnwrapInResult {
 fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_item: &'tcx hir::ImplItem<'_>) {
     if let ImplItemKind::Fn(_, body_id) = impl_item.kind {
         let body = cx.tcx.hir().body(body_id);
-        let typeck = cx.tcx.typeck(impl_item.def_id.def_id);
+        let typeck = cx.tcx.typeck(impl_item.owner_id.def_id);
         let mut result = Vec::new();
         let _: Option<!> = for_each_expr(body.value, |e| {
             // check for `expect`
diff --git a/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs b/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs
index 654ea306793..1d2d3eb12e1 100644
--- a/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs
+++ b/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs
@@ -105,7 +105,7 @@ impl LateLintPass<'_> for UpperCaseAcronyms {
     fn check_item(&mut self, cx: &LateContext<'_>, it: &Item<'_>) {
         // do not lint public items or in macros
         if in_external_macro(cx.sess(), it.span)
-            || (self.avoid_breaking_exported_api && cx.access_levels.is_exported(it.def_id.def_id))
+            || (self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(it.owner_id.def_id))
         {
             return;
         }
diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs
index 65f1b546208..c6cdf3f85fc 100644
--- a/src/tools/clippy/clippy_lints/src/use_self.rs
+++ b/src/tools/clippy/clippy_lints/src/use_self.rs
@@ -106,7 +106,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
             if !is_from_proc_macro(cx, item); // expensive, should be last check
             then {
                 StackItem::Check {
-                    impl_id: item.def_id.def_id,
+                    impl_id: item.owner_id.def_id,
                     in_body: 0,
                     types_to_skip: std::iter::once(self_ty.hir_id).collect(),
                 }
@@ -143,7 +143,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
                 // trait, not in the impl of the trait.
                 let trait_method = cx
                     .tcx
-                    .associated_item(impl_item.def_id)
+                    .associated_item(impl_item.owner_id)
                     .trait_item_def_id
                     .expect("impl method matches a trait method");
                 let trait_method_sig = cx.tcx.fn_sig(trait_method);
diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
index 1f69db1cbca..3743d5d97a7 100644
--- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs
+++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
@@ -5,7 +5,7 @@ use clippy_utils::ty::{is_type_diagnostic_item, same_type_and_consts};
 use clippy_utils::{get_parent_expr, is_trait_method, match_def_path, paths};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind, HirId, LangItem, MatchSource};
+use rustc_hir::{Expr, ExprKind, HirId, MatchSource};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
@@ -153,7 +153,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
                         }
 
                         if_chain! {
-                            if cx.tcx.lang_items().require(LangItem::FromFrom).ok() == Some(def_id);
+                            if Some(def_id) == cx.tcx.lang_items().from_fn();
                             if same_type_and_consts(a, b);
 
                             then {
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
index 4cf76f53625..2a028c8141f 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
@@ -152,7 +152,7 @@ impl UnnecessaryDefPath {
                         has_ctor,
                     ),
                     (0, Item::LangItem(item)) => (
-                        format!("{cx_snip}.tcx.lang_items().require(LangItem::{item}).ok() == Some({def_snip})"),
+                        format!("{cx_snip}.tcx.lang_items().get(LangItem::{item}) == Some({def_snip})"),
                         has_ctor,
                     ),
                     // match_trait_method
@@ -184,7 +184,7 @@ impl UnnecessaryDefPath {
                     (3, Item::LangItem(item)) => (
                         format!(
                             "path_res({cx_snip}, {def_snip}).opt_def_id()\
-                                .map_or(false, |id| {cx_snip}.tcx.lang_items().require(LangItem::{item}).ok() == Some(id))",
+                                .map_or(false, |id| {cx_snip}.tcx.lang_items().get(LangItem::{item}) == Some(id))",
                         ),
                         false,
                     ),
diff --git a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
index 301eed9a1fb..be98344470b 100644
--- a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
+++ b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
@@ -120,14 +120,14 @@ impl LateLintPass<'_> for WildcardImports {
         if is_test_module_or_function(cx.tcx, item) {
             self.test_modules_deep = self.test_modules_deep.saturating_add(1);
         }
-        let module = cx.tcx.parent_module_from_def_id(item.def_id.def_id);
-        if cx.tcx.visibility(item.def_id.def_id) != ty::Visibility::Restricted(module.to_def_id()) {
+        let module = cx.tcx.parent_module_from_def_id(item.owner_id.def_id);
+        if cx.tcx.visibility(item.owner_id.def_id) != ty::Visibility::Restricted(module.to_def_id()) {
             return;
         }
         if_chain! {
             if let ItemKind::Use(use_path, UseKind::Glob) = &item.kind;
             if self.warn_on_all || !self.check_exceptions(item, use_path.segments);
-            let used_imports = cx.tcx.names_imported_by_glob_use(item.def_id.def_id);
+            let used_imports = cx.tcx.names_imported_by_glob_use(item.owner_id.def_id);
             if !used_imports.is_empty(); // Already handled by `unused_imports`
             then {
                 let mut applicability = Applicability::MachineApplicable;
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 052db3f3a03..d32cf1a7936 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -247,7 +247,7 @@ pub fn in_constant(cx: &LateContext<'_>, id: HirId) -> bool {
 /// For example, use this to check whether a function call or a pattern is `Some(..)`.
 pub fn is_res_lang_ctor(cx: &LateContext<'_>, res: Res, lang_item: LangItem) -> bool {
     if let Res::Def(DefKind::Ctor(..), id) = res
-        && let Ok(lang_id) = cx.tcx.lang_items().require(lang_item)
+        && let Some(lang_id) = cx.tcx.lang_items().get(lang_item)
         && let Some(id) = cx.tcx.opt_parent(id)
     {
         id == lang_id
@@ -303,7 +303,7 @@ pub fn is_lang_item_or_ctor(cx: &LateContext<'_>, did: DefId, item: LangItem) ->
         _ => did,
     };
 
-    cx.tcx.lang_items().require(item).map_or(false, |id| id == did)
+    cx.tcx.lang_items().get(item) == Some(did)
 }
 
 pub fn is_unit_expr(expr: &Expr<'_>) -> bool {
@@ -2281,7 +2281,7 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalDefId, f: impl Fn(&[Symbol
         Entry::Vacant(entry) => {
             let mut names = Vec::new();
             for id in tcx.hir().module_items(module) {
-                if matches!(tcx.def_kind(id.def_id), DefKind::Const)
+                if matches!(tcx.def_kind(id.owner_id), DefKind::Const)
                     && let item = tcx.hir().item(id)
                     && let ItemKind::Const(ty, _body) = item.kind {
                     if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind {
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 3b5a9ba8356..3a144c2bb22 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -18,7 +18,7 @@ use rustc_middle::ty::{
 };
 use rustc_middle::ty::{GenericArg, GenericArgKind};
 use rustc_span::symbol::Ident;
-use rustc_span::{sym, Span, Symbol, DUMMY_SP};
+use rustc_span::{sym, Span, Symbol};
 use rustc_target::abi::{Size, VariantIdx};
 use rustc_trait_selection::infer::InferCtxtExt;
 use rustc_trait_selection::traits::query::normalize::AtExt;
@@ -28,7 +28,7 @@ use crate::{match_def_path, path_res, paths};
 
 // Checks if the given type implements copy.
 pub fn is_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
-    ty.is_copy_modulo_regions(cx.tcx.at(DUMMY_SP), cx.param_env)
+    ty.is_copy_modulo_regions(cx.tcx, cx.param_env)
 }
 
 /// This checks whether a given type is known to implement Debug.
@@ -318,11 +318,7 @@ pub fn is_type_diagnostic_item(cx: &LateContext<'_>, ty: Ty<'_>, diag_item: Symb
 /// Returns `false` if the `LangItem` is not defined.
 pub fn is_type_lang_item(cx: &LateContext<'_>, ty: Ty<'_>, lang_item: hir::LangItem) -> bool {
     match ty.kind() {
-        ty::Adt(adt, _) => cx
-            .tcx
-            .lang_items()
-            .require(lang_item)
-            .map_or(false, |li| li == adt.did()),
+        ty::Adt(adt, _) => cx.tcx.lang_items().get(lang_item) == Some(adt.did()),
         _ => false,
     }
 }
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index b9ac6c9f364..0260f684838 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -269,10 +269,10 @@ pub struct Config {
     pub runtool: Option<String>,
 
     /// Flags to pass to the compiler when building for the host
-    pub host_rustcflags: Option<String>,
+    pub host_rustcflags: Vec<String>,
 
     /// Flags to pass to the compiler when building for the target
-    pub target_rustcflags: Option<String>,
+    pub target_rustcflags: Vec<String>,
 
     /// Whether tests should be optimized by default. Individual test-suites and test files may
     /// override this setting.
@@ -457,12 +457,12 @@ pub enum Endian {
 }
 
 impl TargetCfg {
-    fn new(rustc_path: &Path, target: &str, target_rustcflags: &Option<String>) -> TargetCfg {
+    fn new(rustc_path: &Path, target: &str, target_rustcflags: &Vec<String>) -> TargetCfg {
         let output = match Command::new(rustc_path)
             .arg("--print=cfg")
             .arg("--target")
             .arg(target)
-            .args(target_rustcflags.into_iter().map(|s| s.split_whitespace()).flatten())
+            .args(target_rustcflags)
             .output()
         {
             Ok(output) => output,
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index a8cf6623f35..19cf54780c1 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -254,8 +254,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
         }),
         logfile: matches.opt_str("logfile").map(|s| PathBuf::from(&s)),
         runtool: matches.opt_str("runtool"),
-        host_rustcflags: Some(matches.opt_strs("host-rustcflags").join(" ")),
-        target_rustcflags: Some(matches.opt_strs("target-rustcflags").join(" ")),
+        host_rustcflags: matches.opt_strs("host-rustcflags"),
+        target_rustcflags: matches.opt_strs("target-rustcflags"),
         optimize_tests: matches.opt_present("optimize-tests"),
         target,
         host: opt_str2(matches.opt_str("host")),
@@ -322,8 +322,8 @@ pub fn log_config(config: &Config) {
         format!("force_pass_mode: {}", opt_str(&config.force_pass_mode.map(|m| format!("{}", m))),),
     );
     logv(c, format!("runtool: {}", opt_str(&config.runtool)));
-    logv(c, format!("host-rustcflags: {}", opt_str(&config.host_rustcflags)));
-    logv(c, format!("target-rustcflags: {}", opt_str(&config.target_rustcflags)));
+    logv(c, format!("host-rustcflags: {:?}", config.host_rustcflags));
+    logv(c, format!("target-rustcflags: {:?}", config.target_rustcflags));
     logv(c, format!("target: {}", config.target));
     logv(c, format!("host: {}", config.host));
     logv(c, format!("android-cross-path: {:?}", config.android_cross_path.display()));
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 8f289876f73..8af5f1da694 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -558,10 +558,7 @@ impl<'test> TestCx<'test> {
             .arg(&aux_dir)
             .args(&self.props.compile_flags)
             .envs(self.props.rustc_env.clone());
-        self.maybe_add_external_args(
-            &mut rustc,
-            self.split_maybe_args(&self.config.target_rustcflags),
-        );
+        self.maybe_add_external_args(&mut rustc, &self.config.target_rustcflags);
 
         let src = match read_from {
             ReadFrom::Stdin(src) => Some(src),
@@ -629,10 +626,7 @@ impl<'test> TestCx<'test> {
             .arg("-L")
             .arg(aux_dir);
         self.set_revision_flags(&mut rustc);
-        self.maybe_add_external_args(
-            &mut rustc,
-            self.split_maybe_args(&self.config.target_rustcflags),
-        );
+        self.maybe_add_external_args(&mut rustc, &self.config.target_rustcflags);
         rustc.args(&self.props.compile_flags);
 
         self.compose_and_run_compiler(rustc, Some(src))
@@ -1186,23 +1180,14 @@ impl<'test> TestCx<'test> {
         ProcRes { status, stdout: out, stderr: err, cmdline: format!("{:?}", cmd) }
     }
 
-    fn cleanup_debug_info_options(&self, options: &Option<String>) -> Option<String> {
-        if options.is_none() {
-            return None;
-        }
-
+    fn cleanup_debug_info_options(&self, options: &Vec<String>) -> Vec<String> {
         // Remove options that are either unwanted (-O) or may lead to duplicates due to RUSTFLAGS.
         let options_to_remove = ["-O".to_owned(), "-g".to_owned(), "--debuginfo".to_owned()];
-        let new_options = self
-            .split_maybe_args(options)
-            .into_iter()
-            .filter(|x| !options_to_remove.contains(x))
-            .collect::<Vec<String>>();
 
-        Some(new_options.join(" "))
+        options.iter().filter(|x| !options_to_remove.contains(x)).map(|x| x.clone()).collect()
     }
 
-    fn maybe_add_external_args(&self, cmd: &mut Command, args: Vec<String>) {
+    fn maybe_add_external_args(&self, cmd: &mut Command, args: &Vec<String>) {
         // Filter out the arguments that should not be added by runtest here.
         //
         // Notable use-cases are: do not add our optimisation flag if
@@ -2035,15 +2020,9 @@ impl<'test> TestCx<'test> {
         }
 
         if self.props.force_host {
-            self.maybe_add_external_args(
-                &mut rustc,
-                self.split_maybe_args(&self.config.host_rustcflags),
-            );
+            self.maybe_add_external_args(&mut rustc, &self.config.host_rustcflags);
         } else {
-            self.maybe_add_external_args(
-                &mut rustc,
-                self.split_maybe_args(&self.config.target_rustcflags),
-            );
+            self.maybe_add_external_args(&mut rustc, &self.config.target_rustcflags);
             if !is_rustdoc {
                 if let Some(ref linker) = self.config.linker {
                     rustc.arg(format!("-Clinker={}", linker));
diff --git a/src/tools/miri/.github/workflows/ci.yml b/src/tools/miri/.github/workflows/ci.yml
index 659c51f77e6..3efb2d733d4 100644
--- a/src/tools/miri/.github/workflows/ci.yml
+++ b/src/tools/miri/.github/workflows/ci.yml
@@ -10,7 +10,7 @@ on:
     branches:
       - 'master'
   schedule:
-    - cron: '5 15 * * *' # At 15:05 UTC every day.
+    - cron: '6 6 * * *' # At 6:06 UTC every day.
 
 env:
   CARGO_UNSTABLE_SPARSE_REGISTRY: 'true'
@@ -24,16 +24,12 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        build: [linux64, macos, win32]
         include:
-          - build: linux64
-            os: ubuntu-latest
+          - os: ubuntu-latest
             host_target: x86_64-unknown-linux-gnu
-          - build: macos
-            os: macos-latest
+          - os: macos-latest
             host_target: x86_64-apple-darwin
-          - build: win32
-            os: windows-latest
+          - os: windows-latest
             host_target: i686-pc-windows-msvc
     steps:
       - uses: actions/checkout@v3
diff --git a/src/tools/miri/ci.sh b/src/tools/miri/ci.sh
index aa322e54a31..72b7b791a47 100755
--- a/src/tools/miri/ci.sh
+++ b/src/tools/miri/ci.sh
@@ -93,6 +93,7 @@ case $HOST_TARGET in
     ;;
   i686-pc-windows-msvc)
     MIRI_TEST_TARGET=x86_64-unknown-linux-gnu run_tests
+    MIRI_TEST_TARGET=x86_64-pc-windows-gnu run_tests
     ;;
   *)
     echo "FATAL: unknown OS"
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index 21e65bb1b70..3b73d05907b 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -38,6 +38,8 @@
     clippy::cast_lossless,
     clippy::cast_possible_truncation,
 )]
+// Needed for rustdoc from bootstrap (with `-Znormalize-docs`).
+#![recursion_limit = "256"]
 
 extern crate rustc_apfloat;
 extern crate rustc_ast;
@@ -98,8 +100,8 @@ pub use crate::eval::{
 pub use crate::helpers::{CurrentSpan, EvalContextExt as _};
 pub use crate::intptrcast::ProvenanceMode;
 pub use crate::machine::{
-    AllocExtra, FrameData, MiriInterpCx, MiriInterpCxExt, MiriMachine, MiriMemoryKind, Provenance,
-    ProvenanceExtra, PAGE_SIZE, STACK_ADDR, STACK_SIZE,
+    AllocExtra, FrameData, MiriInterpCx, MiriInterpCxExt, MiriMachine, MiriMemoryKind,
+    PrimitiveLayouts, Provenance, ProvenanceExtra, PAGE_SIZE, STACK_ADDR, STACK_SIZE,
 };
 pub use crate::mono_hash_map::MonoHashMap;
 pub use crate::operator::EvalContextExt as _;
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index e014e2db1e1..231a99c1d03 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -276,10 +276,14 @@ pub struct PrimitiveLayouts<'tcx> {
     pub i8: TyAndLayout<'tcx>,
     pub i16: TyAndLayout<'tcx>,
     pub i32: TyAndLayout<'tcx>,
+    pub i64: TyAndLayout<'tcx>,
+    pub i128: TyAndLayout<'tcx>,
     pub isize: TyAndLayout<'tcx>,
     pub u8: TyAndLayout<'tcx>,
     pub u16: TyAndLayout<'tcx>,
     pub u32: TyAndLayout<'tcx>,
+    pub u64: TyAndLayout<'tcx>,
+    pub u128: TyAndLayout<'tcx>,
     pub usize: TyAndLayout<'tcx>,
     pub bool: TyAndLayout<'tcx>,
     pub mut_raw_ptr: TyAndLayout<'tcx>,   // *mut ()
@@ -296,16 +300,42 @@ impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> {
             i8: layout_cx.layout_of(tcx.types.i8)?,
             i16: layout_cx.layout_of(tcx.types.i16)?,
             i32: layout_cx.layout_of(tcx.types.i32)?,
+            i64: layout_cx.layout_of(tcx.types.i64)?,
+            i128: layout_cx.layout_of(tcx.types.i128)?,
             isize: layout_cx.layout_of(tcx.types.isize)?,
             u8: layout_cx.layout_of(tcx.types.u8)?,
             u16: layout_cx.layout_of(tcx.types.u16)?,
             u32: layout_cx.layout_of(tcx.types.u32)?,
+            u64: layout_cx.layout_of(tcx.types.u64)?,
+            u128: layout_cx.layout_of(tcx.types.u128)?,
             usize: layout_cx.layout_of(tcx.types.usize)?,
             bool: layout_cx.layout_of(tcx.types.bool)?,
             mut_raw_ptr: layout_cx.layout_of(mut_raw_ptr)?,
             const_raw_ptr: layout_cx.layout_of(const_raw_ptr)?,
         })
     }
+
+    pub fn uint(&self, size: Size) -> Option<TyAndLayout<'tcx>> {
+        match size.bits() {
+            8 => Some(self.u8),
+            16 => Some(self.u16),
+            32 => Some(self.u32),
+            64 => Some(self.u64),
+            128 => Some(self.u128),
+            _ => None,
+        }
+    }
+
+    pub fn int(&self, size: Size) -> Option<TyAndLayout<'tcx>> {
+        match size.bits() {
+            8 => Some(self.i8),
+            16 => Some(self.i16),
+            32 => Some(self.i32),
+            64 => Some(self.i64),
+            128 => Some(self.i128),
+            _ => None,
+        }
+    }
 }
 
 /// The machine itself.
diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs
index e0985ace5be..6004e2078ad 100644
--- a/src/tools/miri/src/shims/intrinsics/mod.rs
+++ b/src/tools/miri/src/shims/intrinsics/mod.rs
@@ -11,7 +11,7 @@ use rustc_middle::{
     mir,
     ty::{self, FloatTy, Ty},
 };
-use rustc_target::abi::Integer;
+use rustc_target::abi::{Integer, Size};
 
 use crate::*;
 use atomic::EvalContextExt as _;
@@ -120,6 +120,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 this.write_bytes_ptr(ptr, iter::repeat(val_byte).take(byte_count.bytes_usize()))?;
             }
 
+            "ptr_mask" => {
+                let [ptr, mask] = check_arg_count(args)?;
+
+                let ptr = this.read_pointer(ptr)?;
+                let mask = this.read_scalar(mask)?.to_machine_usize(this)?;
+
+                let masked_addr = Size::from_bytes(ptr.addr().bytes() & mask);
+
+                this.write_pointer(Pointer::new(ptr.provenance, masked_addr), dest)?;
+            }
+
             // Floating-point operations
             "fabsf32" => {
                 let [f] = check_arg_count(args)?;
diff --git a/src/tools/miri/src/shims/unix/linux/sync.rs b/src/tools/miri/src/shims/unix/linux/sync.rs
index 5762ee27b84..292b9d2e7a1 100644
--- a/src/tools/miri/src/shims/unix/linux/sync.rs
+++ b/src/tools/miri/src/shims/unix/linux/sync.rs
@@ -1,7 +1,7 @@
+use std::time::SystemTime;
+
 use crate::concurrency::thread::{MachineCallback, Time};
 use crate::*;
-use rustc_target::abi::{Align, Size};
-use std::time::SystemTime;
 
 /// Implementation of the SYS_futex syscall.
 /// `args` is the arguments *after* the syscall number.
@@ -28,13 +28,14 @@ pub fn futex<'tcx>(
     // The first three arguments (after the syscall number itself) are the same to all futex operations:
     //     (int *addr, int op, int val).
     // We checked above that these definitely exist.
-    let addr = this.read_immediate(&args[0])?;
+    let addr = this.read_pointer(&args[0])?;
     let op = this.read_scalar(&args[1])?.to_i32()?;
     let val = this.read_scalar(&args[2])?.to_i32()?;
 
     let thread = this.get_active_thread();
-    let addr_scalar = addr.to_scalar();
-    let addr_usize = addr_scalar.to_machine_usize(this)?;
+    // This is a vararg function so we have to bring our own type for this pointer.
+    let addr = MPlaceTy::from_aligned_ptr(addr, this.machine.layouts.i32);
+    let addr_usize = addr.ptr.addr().bytes();
 
     let futex_private = this.eval_libc_i32("FUTEX_PRIVATE_FLAG")?;
     let futex_wait = this.eval_libc_i32("FUTEX_WAIT")?;
@@ -89,9 +90,11 @@ pub fn futex<'tcx>(
             let timeout_time = if this.ptr_is_null(timeout.ptr)? {
                 None
             } else {
-                this.check_no_isolation(
-                    "`futex` syscall with `op=FUTEX_WAIT` and non-null timeout",
-                )?;
+                if op & futex_realtime != 0 {
+                    this.check_no_isolation(
+                        "`futex` syscall with `op=FUTEX_WAIT` and non-null timeout with `FUTEX_CLOCK_REALTIME`",
+                    )?;
+                }
                 let duration = match this.read_timespec(&timeout)? {
                     Some(duration) => duration,
                     None => {
@@ -117,15 +120,6 @@ pub fn futex<'tcx>(
                     }
                 })
             };
-            // Check the pointer for alignment and validity.
-            // The API requires `addr` to be a 4-byte aligned pointer, and will
-            // use the 4 bytes at the given address as an (atomic) i32.
-            this.check_ptr_access_align(
-                addr_scalar.to_pointer(this)?,
-                Size::from_bytes(4),
-                Align::from_bytes(4).unwrap(),
-                CheckInAllocMsg::MemoryAccessTest,
-            )?;
             // There may be a concurrent thread changing the value of addr
             // and then invoking the FUTEX_WAKE syscall. It is critical that the
             // effects of this and the other thread are correctly observed,
@@ -172,14 +166,7 @@ pub fn futex<'tcx>(
             this.atomic_fence(AtomicFenceOrd::SeqCst)?;
             // Read an `i32` through the pointer, regardless of any wrapper types.
             // It's not uncommon for `addr` to be passed as another type than `*mut i32`, such as `*const AtomicI32`.
-            let futex_val = this
-                .read_scalar_at_offset_atomic(
-                    &addr.into(),
-                    0,
-                    this.machine.layouts.i32,
-                    AtomicReadOrd::Relaxed,
-                )?
-                .to_i32()?;
+            let futex_val = this.read_scalar_atomic(&addr, AtomicReadOrd::Relaxed)?.to_i32()?;
             if val == futex_val {
                 // The value still matches, so we block the thread make it wait for FUTEX_WAKE.
                 this.block_thread(thread);
@@ -214,11 +201,10 @@ pub fn futex<'tcx>(
                         }
                     }
 
-                    let dest = dest.clone();
                     this.register_timeout_callback(
                         thread,
                         timeout_time,
-                        Box::new(Callback { thread, addr_usize, dest }),
+                        Box::new(Callback { thread, addr_usize, dest: dest.clone() }),
                     );
                 }
             } else {
diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
index 371f56ca355..221dc39697f 100644
--- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
@@ -177,11 +177,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
                 let thread = this.pthread_self()?;
                 let max_len = this.eval_libc("MAXTHREADNAMESIZE")?.to_machine_usize(this)?;
-                this.pthread_setname_np(
+                let res = this.pthread_setname_np(
                     thread,
                     this.read_scalar(name)?,
                     max_len.try_into().unwrap(),
                 )?;
+                // Contrary to the manpage, `pthread_setname_np` on macOS still
+                // returns an integer indicating success.
+                this.write_scalar(res, dest)?;
             }
             "pthread_getname_np" => {
                 let [thread, name, len] =
diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs
index 3e1e34c5dbe..fcb00692079 100644
--- a/src/tools/miri/src/shims/unix/sync.rs
+++ b/src/tools/miri/src/shims/unix/sync.rs
@@ -743,8 +743,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
 
-        this.check_no_isolation("`pthread_cond_timedwait`")?;
-
         let id = this.condvar_get_or_create_id(cond_op, CONDVAR_ID_OFFSET)?;
         let mutex_id = this.mutex_get_or_create_id(mutex_op, MUTEX_ID_OFFSET)?;
         let active_thread = this.get_active_thread();
@@ -761,6 +759,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         };
 
         let timeout_time = if clock_id == this.eval_libc_i32("CLOCK_REALTIME")? {
+            this.check_no_isolation("`pthread_cond_timedwait` with `CLOCK_REALTIME`")?;
             Time::RealTime(SystemTime::UNIX_EPOCH.checked_add(duration).unwrap())
         } else if clock_id == this.eval_libc_i32("CLOCK_MONOTONIC")? {
             Time::Monotonic(this.machine.clock.anchor().checked_add(duration).unwrap())
diff --git a/src/tools/miri/src/shims/windows/dlsym.rs b/src/tools/miri/src/shims/windows/dlsym.rs
index 41b9473f81f..4b2a90723c7 100644
--- a/src/tools/miri/src/shims/windows/dlsym.rs
+++ b/src/tools/miri/src/shims/windows/dlsym.rs
@@ -6,12 +6,15 @@ use log::trace;
 
 use crate::helpers::check_arg_count;
 use crate::shims::windows::handle::{EvalContextExt as _, Handle, PseudoHandle};
+use crate::shims::windows::sync::EvalContextExt as _;
 use crate::*;
 
 #[derive(Debug, Copy, Clone)]
 pub enum Dlsym {
     NtWriteFile,
     SetThreadDescription,
+    WaitOnAddress,
+    WakeByAddressSingle,
 }
 
 impl Dlsym {
@@ -22,6 +25,8 @@ impl Dlsym {
             "GetSystemTimePreciseAsFileTime" => None,
             "NtWriteFile" => Some(Dlsym::NtWriteFile),
             "SetThreadDescription" => Some(Dlsym::SetThreadDescription),
+            "WaitOnAddress" => Some(Dlsym::WaitOnAddress),
+            "WakeByAddressSingle" => Some(Dlsym::WakeByAddressSingle),
             _ => throw_unsup_format!("unsupported Windows dlsym: {}", name),
         })
     }
@@ -127,6 +132,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
                 this.write_null(dest)?;
             }
+            Dlsym::WaitOnAddress => {
+                let [ptr_op, compare_op, size_op, timeout_op] = check_arg_count(args)?;
+
+                this.WaitOnAddress(ptr_op, compare_op, size_op, timeout_op, dest)?;
+            }
+            Dlsym::WakeByAddressSingle => {
+                let [ptr_op] = check_arg_count(args)?;
+
+                this.WakeByAddressSingle(ptr_op)?;
+            }
         }
 
         trace!("{:?}", this.dump_place(**dest));
diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs
index 8064ca56675..8156ae8af1e 100644
--- a/src/tools/miri/src/shims/windows/sync.rs
+++ b/src/tools/miri/src/shims/windows/sync.rs
@@ -1,3 +1,7 @@
+use std::time::Duration;
+
+use rustc_target::abi::Size;
+
 use crate::concurrency::init_once::InitOnceStatus;
 use crate::concurrency::thread::MachineCallback;
 use crate::*;
@@ -6,7 +10,6 @@ const SRWLOCK_ID_OFFSET: u64 = 0;
 const INIT_ONCE_ID_OFFSET: u64 = 0;
 
 impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
-
 #[allow(non_snake_case)]
 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     fn AcquireSRWLockExclusive(&mut self, lock_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> {
@@ -221,4 +224,105 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
         this.eval_windows("c", "TRUE")
     }
+
+    fn WaitOnAddress(
+        &mut self,
+        ptr_op: &OpTy<'tcx, Provenance>,
+        compare_op: &OpTy<'tcx, Provenance>,
+        size_op: &OpTy<'tcx, Provenance>,
+        timeout_op: &OpTy<'tcx, Provenance>,
+        dest: &PlaceTy<'tcx, Provenance>,
+    ) -> InterpResult<'tcx> {
+        let this = self.eval_context_mut();
+
+        let ptr = this.read_pointer(ptr_op)?;
+        let compare = this.read_pointer(compare_op)?;
+        let size = this.read_scalar(size_op)?.to_machine_usize(this)?;
+        let timeout_ms = this.read_scalar(timeout_op)?.to_u32()?;
+
+        let thread = this.get_active_thread();
+        let addr = ptr.addr().bytes();
+
+        if size > 8 || !size.is_power_of_two() {
+            let invalid_param = this.eval_windows("c", "ERROR_INVALID_PARAMETER")?;
+            this.set_last_error(invalid_param)?;
+            this.write_scalar(Scalar::from_i32(0), dest)?;
+            return Ok(());
+        };
+        let size = Size::from_bytes(size);
+
+        let timeout_time = if timeout_ms == this.eval_windows("c", "INFINITE")?.to_u32()? {
+            None
+        } else {
+            let duration = Duration::from_millis(timeout_ms.into());
+            Some(Time::Monotonic(this.machine.clock.now().checked_add(duration).unwrap()))
+        };
+
+        // See the Linux futex implementation for why this fence exists.
+        this.atomic_fence(AtomicFenceOrd::SeqCst)?;
+
+        let layout = this.machine.layouts.uint(size).unwrap();
+        let futex_val = this
+            .read_scalar_atomic(&MPlaceTy::from_aligned_ptr(ptr, layout), AtomicReadOrd::Relaxed)?;
+        let compare_val = this.read_scalar(&MPlaceTy::from_aligned_ptr(compare, layout).into())?;
+
+        if futex_val == compare_val {
+            // If the values are the same, we have to block.
+            this.block_thread(thread);
+            this.futex_wait(addr, thread, u32::MAX);
+
+            if let Some(timeout_time) = timeout_time {
+                struct Callback<'tcx> {
+                    thread: ThreadId,
+                    addr: u64,
+                    dest: PlaceTy<'tcx, Provenance>,
+                }
+
+                impl<'tcx> VisitTags for Callback<'tcx> {
+                    fn visit_tags(&self, visit: &mut dyn FnMut(SbTag)) {
+                        let Callback { thread: _, addr: _, dest } = self;
+                        dest.visit_tags(visit);
+                    }
+                }
+
+                impl<'mir, 'tcx: 'mir> MachineCallback<'mir, 'tcx> for Callback<'tcx> {
+                    fn call(&self, this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> {
+                        this.unblock_thread(self.thread);
+                        this.futex_remove_waiter(self.addr, self.thread);
+                        let error_timeout = this.eval_windows("c", "ERROR_TIMEOUT")?;
+                        this.set_last_error(error_timeout)?;
+                        this.write_scalar(Scalar::from_i32(0), &self.dest)?;
+
+                        Ok(())
+                    }
+                }
+
+                this.register_timeout_callback(
+                    thread,
+                    timeout_time,
+                    Box::new(Callback { thread, addr, dest: dest.clone() }),
+                );
+            }
+        }
+
+        this.write_scalar(Scalar::from_i32(1), dest)?;
+
+        Ok(())
+    }
+
+    fn WakeByAddressSingle(&mut self, ptr_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> {
+        let this = self.eval_context_mut();
+
+        let ptr = this.read_pointer(ptr_op)?;
+
+        // See the Linux futex implementation for why this fence exists.
+        this.atomic_fence(AtomicFenceOrd::SeqCst)?;
+
+        if let Some(thread) = this.futex_wake(ptr.addr().bytes(), u32::MAX) {
+            this.unblock_thread(thread);
+            this.unregister_timeout_callback_if_exists(thread);
+        }
+
+        Ok(())
+    }
 }
diff --git a/src/tools/miri/src/stacked_borrows/mod.rs b/src/tools/miri/src/stacked_borrows/mod.rs
index cc27b71eb56..5ec787dd441 100644
--- a/src/tools/miri/src/stacked_borrows/mod.rs
+++ b/src/tools/miri/src/stacked_borrows/mod.rs
@@ -16,7 +16,6 @@ use rustc_middle::ty::{
     layout::{HasParamEnv, LayoutOf},
     Ty,
 };
-use rustc_span::DUMMY_SP;
 use rustc_target::abi::Abi;
 use rustc_target::abi::Size;
 use smallvec::SmallVec;
@@ -714,12 +713,12 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
                 let mut kind_str = format!("{kind}");
                 match kind {
                     RefKind::Unique { two_phase: false }
-                        if !ty.is_unpin(this.tcx.at(DUMMY_SP), this.param_env()) =>
+                        if !ty.is_unpin(*this.tcx, this.param_env()) =>
                     {
                         write!(kind_str, " (!Unpin pointee type {ty})").unwrap()
                     },
                     RefKind::Shared
-                        if !ty.is_freeze(this.tcx.at(DUMMY_SP), this.param_env()) =>
+                        if !ty.is_freeze(*this.tcx, this.param_env()) =>
                     {
                         write!(kind_str, " (!Freeze pointee type {ty})").unwrap()
                     },
@@ -834,7 +833,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
         // There could be existing unique pointers reborrowed from them that should remain valid!
         let perm = match kind {
             RefKind::Unique { two_phase: false }
-                if place.layout.ty.is_unpin(this.tcx.at(DUMMY_SP), this.param_env()) =>
+                if place.layout.ty.is_unpin(*this.tcx, this.param_env()) =>
             {
                 // Only if the type is unpin do we actually enforce uniqueness
                 Permission::Unique
diff --git a/src/tools/miri/tests/fail/data_race/stack_pop_race.rs b/src/tools/miri/tests/fail/data_race/stack_pop_race.rs
index 8f371a680f1..163f46eacc1 100644
--- a/src/tools/miri/tests/fail/data_race/stack_pop_race.rs
+++ b/src/tools/miri/tests/fail/data_race/stack_pop_race.rs
@@ -1,4 +1,3 @@
-//@ignore-target-windows: Concurrency on Windows is not supported yet.
 //@compile-flags: -Zmiri-preemption-rate=0
 use std::thread;
 
diff --git a/src/tools/miri/tests/fail/panic/no_std.rs b/src/tools/miri/tests/fail/panic/no_std.rs
index b6a5c075570..589f843cf82 100644
--- a/src/tools/miri/tests/fail/panic/no_std.rs
+++ b/src/tools/miri/tests/fail/panic/no_std.rs
@@ -3,7 +3,7 @@
 // windows tls dtors go through libstd right now, thus this test
 // cannot pass. When windows tls dtors go through the special magic
 // windows linker section, we can run this test on windows again.
-//@ignore-target-windows
+//@ignore-target-windows: no-std not supported on Windows
 
 // Plumbing to let us use `writeln!` to host stderr:
 
diff --git a/src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond_isolated.rs b/src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond_isolated.rs
new file mode 100644
index 00000000000..103ce44006d
--- /dev/null
+++ b/src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond_isolated.rs
@@ -0,0 +1,82 @@
+//@ignore-target-windows: No libc on Windows
+//@ignore-target-apple: pthread_condattr_setclock is not supported on MacOS.
+
+/// Test that conditional variable timeouts are working properly
+/// with monotonic clocks even under isolation.
+use std::mem::MaybeUninit;
+use std::time::Instant;
+
+fn test_timed_wait_timeout(clock_id: i32) {
+    unsafe {
+        let mut attr: MaybeUninit<libc::pthread_condattr_t> = MaybeUninit::uninit();
+        assert_eq!(libc::pthread_condattr_init(attr.as_mut_ptr()), 0);
+        assert_eq!(libc::pthread_condattr_setclock(attr.as_mut_ptr(), clock_id), 0);
+
+        let mut cond: MaybeUninit<libc::pthread_cond_t> = MaybeUninit::uninit();
+        assert_eq!(libc::pthread_cond_init(cond.as_mut_ptr(), attr.as_ptr()), 0);
+        assert_eq!(libc::pthread_condattr_destroy(attr.as_mut_ptr()), 0);
+
+        let mut mutex: libc::pthread_mutex_t = libc::PTHREAD_MUTEX_INITIALIZER;
+
+        let mut now_mu: MaybeUninit<libc::timespec> = MaybeUninit::uninit();
+        assert_eq!(libc::clock_gettime(clock_id, now_mu.as_mut_ptr()), 0);
+        let now = now_mu.assume_init();
+        // Waiting for a second... mostly because waiting less requires mich more tricky arithmetic.
+        // FIXME: wait less.
+        let timeout = libc::timespec { tv_sec: now.tv_sec + 1, tv_nsec: now.tv_nsec };
+
+        assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0);
+        let current_time = Instant::now();
+        assert_eq!(
+            libc::pthread_cond_timedwait(cond.as_mut_ptr(), &mut mutex as *mut _, &timeout),
+            libc::ETIMEDOUT
+        );
+        let elapsed_time = current_time.elapsed().as_millis();
+        assert!(900 <= elapsed_time && elapsed_time <= 1300);
+
+        // Test calling `pthread_cond_timedwait` again with an already elapsed timeout.
+        assert_eq!(
+            libc::pthread_cond_timedwait(cond.as_mut_ptr(), &mut mutex as *mut _, &timeout),
+            libc::ETIMEDOUT
+        );
+
+        // Test that invalid nanosecond values (above 10^9 or negative) are rejected with the
+        // correct error code.
+        let invalid_timeout_1 = libc::timespec { tv_sec: now.tv_sec + 1, tv_nsec: 1_000_000_000 };
+        assert_eq!(
+            libc::pthread_cond_timedwait(
+                cond.as_mut_ptr(),
+                &mut mutex as *mut _,
+                &invalid_timeout_1
+            ),
+            libc::EINVAL
+        );
+        let invalid_timeout_2 = libc::timespec { tv_sec: now.tv_sec + 1, tv_nsec: -1 };
+        assert_eq!(
+            libc::pthread_cond_timedwait(
+                cond.as_mut_ptr(),
+                &mut mutex as *mut _,
+                &invalid_timeout_2
+            ),
+            libc::EINVAL
+        );
+        // Test that invalid second values (negative) are rejected with the correct error code.
+        let invalid_timeout_3 = libc::timespec { tv_sec: -1, tv_nsec: 0 };
+        assert_eq!(
+            libc::pthread_cond_timedwait(
+                cond.as_mut_ptr(),
+                &mut mutex as *mut _,
+                &invalid_timeout_3
+            ),
+            libc::EINVAL
+        );
+
+        assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0);
+        assert_eq!(libc::pthread_mutex_destroy(&mut mutex as *mut _), 0);
+        assert_eq!(libc::pthread_cond_destroy(cond.as_mut_ptr()), 0);
+    }
+}
+
+fn main() {
+    test_timed_wait_timeout(libc::CLOCK_MONOTONIC);
+}
diff --git a/src/tools/miri/tests/pass-dep/shims/libc-misc.rs b/src/tools/miri/tests/pass-dep/shims/libc-misc.rs
index a883a3d967a..904ae2fb17f 100644
--- a/src/tools/miri/tests/pass-dep/shims/libc-misc.rs
+++ b/src/tools/miri/tests/pass-dep/shims/libc-misc.rs
@@ -87,7 +87,7 @@ fn test_posix_realpath_errors() {
     assert_eq!(e.kind(), ErrorKind::NotFound);
 }
 
-#[cfg(any(target_os = "linux"))]
+#[cfg(target_os = "linux")]
 fn test_posix_fadvise() {
     use std::convert::TryInto;
     use std::io::Write;
@@ -115,7 +115,7 @@ fn test_posix_fadvise() {
     assert_eq!(result, 0);
 }
 
-#[cfg(any(target_os = "linux"))]
+#[cfg(target_os = "linux")]
 fn test_sync_file_range() {
     use std::io::Write;
 
@@ -181,7 +181,7 @@ fn test_thread_local_errno() {
 }
 
 /// Tests whether clock support exists at all
-#[cfg(any(target_os = "linux"))]
+#[cfg(target_os = "linux")]
 fn test_clocks() {
     let mut tp = std::mem::MaybeUninit::<libc::timespec>::uninit();
     let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME, tp.as_mut_ptr()) };
@@ -283,9 +283,6 @@ fn test_posix_mkstemp() {
 }
 
 fn main() {
-    #[cfg(any(target_os = "linux"))]
-    test_posix_fadvise();
-
     test_posix_gettimeofday();
     test_posix_mkstemp();
 
@@ -293,13 +290,14 @@ fn main() {
     test_posix_realpath_noalloc();
     test_posix_realpath_errors();
 
-    #[cfg(any(target_os = "linux"))]
-    test_sync_file_range();
-
     test_thread_local_errno();
 
-    #[cfg(any(target_os = "linux"))]
-    test_clocks();
-
     test_isatty();
+
+    #[cfg(target_os = "linux")]
+    {
+        test_posix_fadvise();
+        test_sync_file_range();
+        test_clocks();
+    }
 }
diff --git a/src/tools/miri/tests/pass-dep/shims/pthreads.rs b/src/tools/miri/tests/pass-dep/shims/pthreads.rs
index bbddca74754..09dd92564d3 100644
--- a/src/tools/miri/tests/pass-dep/shims/pthreads.rs
+++ b/src/tools/miri/tests/pass-dep/shims/pthreads.rs
@@ -1,6 +1,6 @@
 //@ignore-target-windows: No libc on Windows
 #![feature(cstr_from_bytes_until_nul)]
-use std::ffi::CStr;
+use std::ffi::{CStr, CString};
 use std::thread;
 
 fn main() {
@@ -10,7 +10,7 @@ fn main() {
     test_rwlock_libc_static_initializer();
     test_named_thread_truncation();
 
-    #[cfg(any(target_os = "linux"))]
+    #[cfg(target_os = "linux")]
     test_mutex_libc_static_initializer_recursive();
 }
 
@@ -135,6 +135,13 @@ fn test_named_thread_truncation() {
         .chain(std::iter::repeat(" yada").take(100))
         .collect::<String>();
 
+    fn set_thread_name(name: &CStr) -> i32 {
+        #[cfg(target_os = "linux")]
+        return unsafe { libc::pthread_setname_np(libc::pthread_self(), name.as_ptr().cast()) };
+        #[cfg(target_os = "macos")]
+        return unsafe { libc::pthread_setname_np(name.as_ptr().cast()) };
+    }
+
     let result = thread::Builder::new().name(long_name.clone()).spawn(move || {
         // Rust remembers the full thread name itself.
         assert_eq!(thread::current().name(), Some(long_name.as_str()));
@@ -142,11 +149,16 @@ fn test_named_thread_truncation() {
         // But the system is limited -- make sure we successfully set a truncation.
         let mut buf = vec![0u8; long_name.len() + 1];
         unsafe {
-            libc::pthread_getname_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len());
-        }
+            libc::pthread_getname_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len())
+        };
         let cstr = CStr::from_bytes_until_nul(&buf).unwrap();
         assert!(cstr.to_bytes().len() >= 15); // POSIX seems to promise at least 15 chars
         assert!(long_name.as_bytes().starts_with(cstr.to_bytes()));
+
+        // Also test directly calling pthread_setname to check its return value.
+        assert_eq!(set_thread_name(&cstr), 0);
+        // But with a too long name it should fail.
+        assert_ne!(set_thread_name(&CString::new(long_name).unwrap()), 0);
     });
     result.unwrap().join().unwrap();
 }
diff --git a/src/tools/miri/tests/pass/concurrency/channels.rs b/src/tools/miri/tests/pass/concurrency/channels.rs
index c75c5199bf1..53b57942d76 100644
--- a/src/tools/miri/tests/pass/concurrency/channels.rs
+++ b/src/tools/miri/tests/pass/concurrency/channels.rs
@@ -1,4 +1,3 @@
-//@ignore-target-windows: Channels on Windows are not supported yet.
 //@compile-flags: -Zmiri-strict-provenance
 
 use std::sync::mpsc::{channel, sync_channel};
diff --git a/src/tools/miri/tests/pass/concurrency/spin_loops_nopreempt.rs b/src/tools/miri/tests/pass/concurrency/spin_loops_nopreempt.rs
index 5d8e2ef5f02..44b16e1ac74 100644
--- a/src/tools/miri/tests/pass/concurrency/spin_loops_nopreempt.rs
+++ b/src/tools/miri/tests/pass/concurrency/spin_loops_nopreempt.rs
@@ -1,4 +1,3 @@
-//@ignore-target-windows: Channels on Windows are not supported yet.
 // This specifically tests behavior *without* preemption.
 //@compile-flags: -Zmiri-preemption-rate=0
 
diff --git a/src/tools/miri/tests/pass/concurrency/sync.rs b/src/tools/miri/tests/pass/concurrency/sync.rs
index 8bda32bb95a..b1518a49fbb 100644
--- a/src/tools/miri/tests/pass/concurrency/sync.rs
+++ b/src/tools/miri/tests/pass/concurrency/sync.rs
@@ -1,4 +1,3 @@
-//@ignore-target-windows: Concurrency on Windows is not supported yet.
 //@compile-flags: -Zmiri-disable-isolation -Zmiri-strict-provenance
 
 use std::sync::{Arc, Barrier, Condvar, Mutex, Once, RwLock};
@@ -225,14 +224,26 @@ fn park_unpark() {
 }
 
 fn main() {
-    check_barriers();
-    check_conditional_variables_notify_one();
-    check_conditional_variables_timed_wait_timeout();
-    check_conditional_variables_timed_wait_notimeout();
     check_mutex();
     check_rwlock_write();
     check_rwlock_read_no_deadlock();
     check_once();
     park_timeout();
     park_unpark();
+
+    if !cfg!(windows) {
+        // ignore-target-windows: Condvars on Windows are not supported yet
+        check_barriers();
+        check_conditional_variables_notify_one();
+        check_conditional_variables_timed_wait_timeout();
+        check_conditional_variables_timed_wait_notimeout();
+    } else {
+        // We need to fake the same output...
+        for _ in 0..10 {
+            println!("before wait");
+        }
+        for _ in 0..10 {
+            println!("after wait");
+        }
+    }
 }
diff --git a/src/tools/miri/tests/pass/concurrency/sync_nopreempt.rs b/src/tools/miri/tests/pass/concurrency/sync_nopreempt.rs
index 3da33fee4c0..55206f4bfc5 100644
--- a/src/tools/miri/tests/pass/concurrency/sync_nopreempt.rs
+++ b/src/tools/miri/tests/pass/concurrency/sync_nopreempt.rs
@@ -1,4 +1,4 @@
-//@ignore-target-windows: Concurrency on Windows is not supported yet.
+//@ignore-target-windows: Condvars on Windows are not supported yet.
 // We are making scheduler assumptions here.
 //@compile-flags: -Zmiri-strict-provenance -Zmiri-preemption-rate=0
 
diff --git a/src/tools/miri/tests/pass/concurrency/thread_park_isolated.rs b/src/tools/miri/tests/pass/concurrency/thread_park_isolated.rs
new file mode 100644
index 00000000000..bf004012e84
--- /dev/null
+++ b/src/tools/miri/tests/pass/concurrency/thread_park_isolated.rs
@@ -0,0 +1,12 @@
+//@ignore-target-apple: park_timeout on macOS uses the system clock
+use std::thread;
+use std::time::{Duration, Instant};
+
+fn main() {
+    let start = Instant::now();
+
+    thread::park_timeout(Duration::from_millis(200));
+
+    // Thanks to deterministic execution, this will wiat *exactly* 200ms (rounded to 1ms).
+    assert!((200..201).contains(&start.elapsed().as_millis()));
+}
diff --git a/src/tools/miri/tests/pass/no_std.rs b/src/tools/miri/tests/pass/no_std.rs
index 0203edfe181..eb0e860e68e 100644
--- a/src/tools/miri/tests/pass/no_std.rs
+++ b/src/tools/miri/tests/pass/no_std.rs
@@ -3,7 +3,7 @@
 // windows tls dtors go through libstd right now, thus this test
 // cannot pass. When windows tls dtors go through the special magic
 // windows linker section, we can run this test on windows again.
-//@ignore-target-windows
+//@ignore-target-windows: no-std not supported on Windows
 
 // Plumbing to let us use `writeln!` to host stdout:
 
diff --git a/src/tools/miri/tests/pass/shims/env/current_exe.rs b/src/tools/miri/tests/pass/shims/env/current_exe.rs
index 15ea6a52b7b..3f1153d265d 100644
--- a/src/tools/miri/tests/pass/shims/env/current_exe.rs
+++ b/src/tools/miri/tests/pass/shims/env/current_exe.rs
@@ -1,4 +1,4 @@
-//@ignore-target-windows
+//@ignore-target-windows: current_exe not supported on Windows
 //@only-on-host: the Linux std implementation opens /proc/self/exe, which doesn't work cross-target
 //@compile-flags: -Zmiri-disable-isolation
 use std::env;
diff --git a/src/tools/miri/tests/pass/shims/ptr_mask.rs b/src/tools/miri/tests/pass/shims/ptr_mask.rs
new file mode 100644
index 00000000000..fb8bb6b13db
--- /dev/null
+++ b/src/tools/miri/tests/pass/shims/ptr_mask.rs
@@ -0,0 +1,18 @@
+#![feature(ptr_mask)]
+#![feature(strict_provenance)]
+
+fn main() {
+    let v: u32 = 0xABCDABCD;
+    let ptr: *const u32 = &v;
+
+    // u32 is 4 aligned,
+    // so the lower `log2(4) = 2` bits of the address are always 0
+    assert_eq!(ptr.addr() & 0b11, 0);
+
+    let tagged_ptr = ptr.map_addr(|a| a | 0b11);
+    let tag = tagged_ptr.addr() & 0b11;
+    let masked_ptr = tagged_ptr.mask(!0b11);
+
+    assert_eq!(tag, 0b11);
+    assert_eq!(unsafe { *masked_ptr }, 0xABCDABCD);
+}
diff --git a/src/tools/miri/tests/pass/shims/sleep_long.rs b/src/tools/miri/tests/pass/shims/sleep_long.rs
index dd4a1843942..c94f63a5427 100644
--- a/src/tools/miri/tests/pass/shims/sleep_long.rs
+++ b/src/tools/miri/tests/pass/shims/sleep_long.rs
@@ -1,4 +1,3 @@
-//@ignore-target-windows: no threads nor sleep on Windows
 //@compile-flags: -Zmiri-ignore-leaks -Zmiri-disable-isolation
 use std::sync::{Arc, Mutex};
 use std::thread;
diff --git a/src/tools/miri/tests/pass/threadleak_ignored.rs b/src/tools/miri/tests/pass/threadleak_ignored.rs
index 99bac7aa42a..a5f81573e96 100644
--- a/src/tools/miri/tests/pass/threadleak_ignored.rs
+++ b/src/tools/miri/tests/pass/threadleak_ignored.rs
@@ -1,6 +1,4 @@
-//@ignore-target-windows: Channels on Windows are not supported yet.
-// FIXME: disallow preemption to work around https://github.com/rust-lang/rust/issues/55005
-//@compile-flags: -Zmiri-ignore-leaks -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-ignore-leaks
 
 //! Test that leaking threads works, and that their destructors are not executed.
 
diff --git a/src/version b/src/version
index b6148bc0a75..65ee0959841 100644
--- a/src/version
+++ b/src/version
@@ -1 +1 @@
-1.66.0
+1.67.0
diff --git a/x b/x
index 704d0f791f3..4309b82627c 100755
--- a/x
+++ b/x
@@ -29,5 +29,11 @@ for SEARCH_PYTHON in py python3 python python2; do
         exec "$python" $extra_arg "$xpy" "$@"
     fi
 done
+
+python=$(bash -c "compgen -c python" | grep '^python[2-3]\.[0-9]\+$' | head -n1)
+if ! [ "$python" = "" ]; then
+    exec "$python" "$xpy" "$@"
+fi
+
 echo "$0: error: did not find python installed" >&2
 exit 1
diff --git a/x.ps1 b/x.ps1
index 86cea606591..81b98919f43 100755
--- a/x.ps1
+++ b/x.ps1
@@ -10,11 +10,15 @@ foreach ($arg in $args) {
     $xpy_args += """$arg"""
 }
 
+function Get-Application($app) {
+    return Get-Command $app -ErrorAction SilentlyContinue -CommandType Application
+}
+
 foreach ($python in "py", "python3", "python", "python2") {
     # NOTE: this only tests that the command exists in PATH, not that it's actually
     # executable. The latter is not possible in a portable way, see
     # https://github.com/PowerShell/PowerShell/issues/12625.
-    if (Get-Command $python -ErrorAction SilentlyContinue) {
+    if (Get-Application $python) {
         if ($python -eq "py") {
             # Use python3, not python2
             $xpy_args = @("-3") + $xpy_args
@@ -24,5 +28,12 @@ foreach ($python in "py", "python3", "python", "python2") {
     }
 }
 
+$found = (Get-Application "python*" | Where-Object {$_.name -match '^python[2-3]\.[0-9]+(\.exe)?$'})
+if (($null -ne $found) -and ($found.Length -ge 1)) {
+    $python = $found[0]
+    $process = Start-Process -NoNewWindow -Wait -PassThru $python $xpy_args
+    Exit $process.ExitCode
+}
+
 Write-Error "${PSCommandPath}: error: did not find python installed"
 Exit 1